From ea3473f7fff6f6ca6c4a46a4f052624047a2333a Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:41:05 +0100 Subject: [PATCH 01/64] Script for installing agents on macOS (#6305) * Fix script deploy mac agent * Add command test * Add euispacer * Update changelog --- CHANGELOG.md | 1 + .../command-output/command-output.tsx | 18 +- ...egister-agent-os-commands-services.test.ts | 227 ++++++++++++++++++ .../register-agent-os-commands-services.tsx | 32 +-- 4 files changed, 257 insertions(+), 21 deletions(-) create mode 100644 plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9543380e7b..8569139d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed exception in Inventory when agents don't have OS information [#6177](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6177) - Fixed pinned agent state in URL [#6177](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6177) - Fixed invalid date format in about and agent views [#6234](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6234) +- Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) ### Removed diff --git a/plugins/main/public/controllers/register-agent/components/command-output/command-output.tsx b/plugins/main/public/controllers/register-agent/components/command-output/command-output.tsx index 1a8f604ccf..3137ba5831 100644 --- a/plugins/main/public/controllers/register-agent/components/command-output/command-output.tsx +++ b/plugins/main/public/controllers/register-agent/components/command-output/command-output.tsx @@ -84,14 +84,18 @@ export default function CommandOutput(props: ICommandSectionProps) { )} - {showCommand && havePassword ? ( - - ) : null} + <> + + + + ) : ( + + )} ); diff --git a/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.test.ts b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.test.ts new file mode 100644 index 0000000000..cea94326b9 --- /dev/null +++ b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.test.ts @@ -0,0 +1,227 @@ +import { + getAllOptionals, + getAllOptionalsMacos, + getDEBAMD64InstallCommand, + getDEBARM64InstallCommand, + getLinuxStartCommand, + getMacOsInstallCommand, + getMacosStartCommand, + getRPMAMD64InstallCommand, + getRPMARM64InstallCommand, + getWindowsInstallCommand, + getWindowsStartCommand, + transformOptionalsParamatersMacOSCommand, +} from './register-agent-os-commands-services'; + +let test: any; + +beforeEach(() => { + test = { + optionals: { + agentGroups: "WAZUH_AGENT_GROUP='default'", + agentName: "WAZUH_AGENT_NAME='test'", + serverAddress: "WAZUH_MANAGER='1.1.1.1'", + wazuhPassword: "WAZUH_REGISTRATION_PASSWORD=''", + }, + urlPackage: 'https://test.com/agent.deb', + wazuhVersion: '4.8.0', + }; +}); + +describe('getAllOptionals', () => { + it('should return empty string if optionals is falsy', () => { + const result = getAllOptionals(null); + expect(result).toBe(''); + }); + + it('should return the correct paramsText', () => { + const optionals = { + serverAddress: 'localhost', + wazuhPassword: 'password', + agentGroups: 'group1', + agentName: 'agent1', + protocol: 'http', + }; + const result = getAllOptionals(optionals, 'linux'); + expect(result).toBe('localhost password group1 agent1 http '); + }); +}); + +describe('getDEBAMD64InstallCommand', () => { + it('should return the correct install command', () => { + const props = { + optionals: { + serverAddress: 'localhost', + wazuhPassword: 'password', + agentGroups: 'group1', + agentName: 'agent1', + protocol: 'http', + }, + urlPackage: 'https://example.com/package.deb', + wazuhVersion: '4.0.0', + }; + const result = getDEBAMD64InstallCommand(props); + expect(result).toBe( + 'wget https://example.com/package.deb && sudo localhost password group1 agent1 http dpkg -i ./wazuh-agent_4.0.0-1_amd64.deb', + ); + }); +}); + +describe('getDEBAMD64InstallCommand', () => { + it('should return the correct command', () => { + let expected = `wget ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.wazuhPassword} ${test.optionals.agentGroups} ${test.optionals.agentName} dpkg -i ./wazuh-agent_${test.wazuhVersion}-1_amd64.deb`; + const withAllOptionals = getDEBAMD64InstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + + expected = `wget ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.agentGroups} dpkg -i ./wazuh-agent_${test.wazuhVersion}-1_amd64.deb`; + const withServerAddresAndAgentGroupsOptions = + getDEBAMD64InstallCommand(test); + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getDEBARM64InstallCommand', () => { + it('should return the correct command', () => { + let expected = `wget ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.wazuhPassword} ${test.optionals.agentGroups} ${test.optionals.agentName} dpkg -i ./wazuh-agent_${test.wazuhVersion}-1_arm64.deb`; + const withAllOptionals = getDEBARM64InstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + + expected = `wget ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.agentGroups} dpkg -i ./wazuh-agent_${test.wazuhVersion}-1_arm64.deb`; + const withServerAddresAndAgentGroupsOptions = + getDEBARM64InstallCommand(test); + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getRPMAMD64InstallCommand', () => { + it('should return the correct command', () => { + let expected = `curl -o wazuh-agent-4.8.0-1.x86_64.rpm ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.wazuhPassword} ${test.optionals.agentGroups} ${test.optionals.agentName} rpm -ihv wazuh-agent-${test.wazuhVersion}-1.x86_64.rpm`; + const withAllOptionals = getRPMAMD64InstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + + expected = `curl -o wazuh-agent-4.8.0-1.x86_64.rpm ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.agentGroups} rpm -ihv wazuh-agent-${test.wazuhVersion}-1.x86_64.rpm`; + const withServerAddresAndAgentGroupsOptions = + getRPMAMD64InstallCommand(test); + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getRPMARM64InstallCommand', () => { + it('should return the correct command', () => { + let expected = `curl -o wazuh-agent-4.8.0-1.aarch64.rpm ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.wazuhPassword} ${test.optionals.agentGroups} ${test.optionals.agentName} rpm -ihv wazuh-agent-${test.wazuhVersion}-1.aarch64.rpm`; + const withAllOptionals = getRPMARM64InstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + + expected = `curl -o wazuh-agent-4.8.0-1.aarch64.rpm ${test.urlPackage} && sudo ${test.optionals.serverAddress} ${test.optionals.agentGroups} rpm -ihv wazuh-agent-${test.wazuhVersion}-1.aarch64.rpm`; + const withServerAddresAndAgentGroupsOptions = + getRPMARM64InstallCommand(test); + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getLinuxStartCommand', () => { + it('returns the correct start command for Linux', () => { + const startCommand = getLinuxStartCommand({}); + const expectedCommand = + 'sudo systemctl daemon-reload\nsudo systemctl enable wazuh-agent\nsudo systemctl start wazuh-agent'; + + expect(startCommand).toEqual(expectedCommand); + }); +}); + +// Windows + +describe('getWindowsInstallCommand', () => { + it('should return the correct install command', () => { + let expected = `Invoke-WebRequest -Uri ${test.urlPackage} -OutFile \${env.tmp}\\wazuh-agent; msiexec.exe /i \${env.tmp}\\wazuh-agent /q ${test.optionals.serverAddress} ${test.optionals.wazuhPassword} ${test.optionals.agentGroups} ${test.optionals.agentName} `; + + const withAllOptionals = getWindowsInstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + + expected = `Invoke-WebRequest -Uri ${test.urlPackage} -OutFile \${env.tmp}\\wazuh-agent; msiexec.exe /i \${env.tmp}\\wazuh-agent /q ${test.optionals.serverAddress} ${test.optionals.agentGroups} `; + const withServerAddresAndAgentGroupsOptions = + getWindowsInstallCommand(test); + + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getWindowsStartCommand', () => { + it('should return the correct start command', () => { + const expectedCommand = 'NET START WazuhSvc'; + + const result = getWindowsStartCommand({}); + + expect(result).toEqual(expectedCommand); + }); +}); + +// MacOS + +describe('getAllOptionalsMacos', () => { + it('should return empty string if optionals is falsy', () => { + const result = getAllOptionalsMacos(null); + expect(result).toBe(''); + }); + + it('should return the correct paramsValueList', () => { + const optionals = { + serverAddress: 'localhost', + agentGroups: 'group1', + agentName: 'agent1', + protocol: 'http', + wazuhPassword: 'password', + }; + const result = getAllOptionalsMacos(optionals); + expect(result).toBe('localhost && group1 && agent1 && http && password'); + }); +}); + +describe('transformOptionalsParamatersMacOSCommand', () => { + it('should transform the command correctly', () => { + const command = + "' serverAddress && agentGroups && agentName && protocol && wazuhPassword"; + const result = transformOptionalsParamatersMacOSCommand(command); + expect(result).toBe( + "' && serverAddress && agentGroups && agentName && protocol && wazuhPassword", + ); + }); +}); + +describe('getMacOsInstallCommand', () => { + it('should return the correct macOS installation script', () => { + let expected = `curl -so wazuh-agent.pkg ${test.urlPackage} && echo "${test.optionals.serverAddress} && ${test.optionals.agentGroups} && ${test.optionals.agentName} && ${test.optionals.wazuhPassword}\\n\" > /tmp/wazuh_envs && sudo installer -pkg ./wazuh-agent.pkg -target /`; + + const withAllOptionals = getMacOsInstallCommand(test); + expect(withAllOptionals).toEqual(expected); + + delete test.optionals.wazuhPassword; + delete test.optionals.agentName; + expected = `curl -so wazuh-agent.pkg ${test.urlPackage} && echo "${test.optionals.serverAddress} && ${test.optionals.agentGroups}" > /tmp/wazuh_envs && sudo installer -pkg ./wazuh-agent.pkg -target /`; + + const withServerAddresAndAgentGroupsOptions = getMacOsInstallCommand(test); + expect(withServerAddresAndAgentGroupsOptions).toEqual(expected); + }); +}); + +describe('getMacosStartCommand', () => { + it('returns the correct start command for macOS', () => { + const startCommand = getMacosStartCommand({}); + expect(startCommand).toEqual('sudo /Library/Ossec/bin/wazuh-control start'); + }); +}); diff --git a/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx index bce1272426..e38a78248f 100644 --- a/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx +++ b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx @@ -6,7 +6,7 @@ import { } from '../core/register-commands/types'; import { tOperatingSystem } from '../hooks/use-register-agent-commands.test'; -const getAllOptionals = ( +export const getAllOptionals = ( optionals: IOptionalParameters, osName?: tOperatingSystem['name'], ) => { @@ -38,12 +38,12 @@ const getAllOptionals = ( return paramsText; }; -const getAllOptionalsMacos = ( +export const getAllOptionalsMacos = ( optionals: IOptionalParameters, ) => { // create paramNameOrderList, which is an array of the keys of optionals add interface const paramNameOrderList: (keyof IOptionalParameters)[] = - ['serverAddress', 'agentGroups', 'agentName', 'protocol']; + ['serverAddress', 'agentGroups', 'agentName', 'protocol', 'wazuhPassword']; if (!optionals) return ''; @@ -145,29 +145,33 @@ export const getMacOsInstallCommand = ( props: tOSEntryInstallCommand, ) => { const { optionals, urlPackage } = props; - // Set macOS installation script with environment variables - const optionalsText = optionals && getAllOptionalsMacos(optionals); - const macOSInstallationOptions = transformOptionalsParamatersMacOSCommand( - optionalsText || '', - ); - let wazuhPasswordParamWithValue = ''; - if (optionals?.wazuhPassword) { + + let optionalsForCommand = { ...optionals }; + if (optionalsForCommand?.wazuhPassword) { /** * We use the JSON.stringify to prevent that the scaped specials characters will be removed * and mantain the format of the password The JSON.stringify mantain the password format but adds " to wrap the characters */ const scapedPasswordLength = JSON.stringify( - optionals?.wazuhPassword, + optionalsForCommand?.wazuhPassword, ).length; // We need to remove the " added by JSON.stringify - wazuhPasswordParamWithValue = `${JSON.stringify( - optionals?.wazuhPassword, + optionalsForCommand.wazuhPassword = `${JSON.stringify( + optionalsForCommand?.wazuhPassword, ).substring(1, scapedPasswordLength - 1)}\\n`; } + + // Set macOS installation script with environment variables + const optionalsText = + optionalsForCommand && getAllOptionalsMacos(optionalsForCommand); + const macOSInstallationOptions = transformOptionalsParamatersMacOSCommand( + optionalsText || '', + ); + // If no variables are set, the echo will be empty const macOSInstallationSetEnvVariablesScript = macOSInstallationOptions - ? `echo "${macOSInstallationOptions}${wazuhPasswordParamWithValue}" > /tmp/wazuh_envs && ` + ? `echo "${macOSInstallationOptions}" > /tmp/wazuh_envs && ` : ``; // Merge environment variables with installation script From 26a06fae5c0f65c5e34bc34f0669f74aa638d9d8 Mon Sep 17 00:00:00 2001 From: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:35:48 -0300 Subject: [PATCH 02/64] Fix deploy new agent filters (#6327) * change validations * change tests * Modify changelog * Update changelog * Fix typo --- CHANGELOG.md | 1 + .../register-agent/utils/validations.test.tsx | 32 ++++++++++---- .../register-agent/utils/validations.tsx | 44 +++++++------------ 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8569139d24..a9ef4c16c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed pinned agent state in URL [#6177](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6177) - Fixed invalid date format in about and agent views [#6234](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6234) - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) +- Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) ### Removed diff --git a/plugins/main/public/controllers/register-agent/utils/validations.test.tsx b/plugins/main/public/controllers/register-agent/utils/validations.test.tsx index df84f6d767..beca15c672 100644 --- a/plugins/main/public/controllers/register-agent/utils/validations.test.tsx +++ b/plugins/main/public/controllers/register-agent/utils/validations.test.tsx @@ -12,26 +12,42 @@ describe('Validations', () => { expect(result).toBeUndefined(); }); - it('should return undefined for a valid IP', () => { + it('should return undefined for a valid IPv4', () => { const validIP = '192.168.1.1'; const result = validateServerAddress(validIP); expect(result).toBeUndefined(); }); + it('should return undefined for a valid IPv6', () => { + const validIP = '2001:0db8:85a3:0000:0000:8a2e:0370:7334'; + const result = validateServerAddress(validIP); + expect(result).toBeUndefined(); + }); + + it('should return an error message for an invalid IPv6', () => { + const invalidIPV6 = '2001:db8:85a3::8a2e:370:7334'; + const result = validateServerAddress(invalidIPV6); + expect(result).toBe( + 'It should be a valid hostname, FQDN, IPv4 or uncompressed IPv6', + ); + }); + + it('should return an error message for a compressed IPv6', () => { + const compressedIPV6 = '2001:0db8:85a3:0000:0000:8a2e:0370:7334:KL12'; + const result = validateServerAddress(compressedIPV6); + expect(result).toBe( + 'It should be a valid hostname, FQDN, IPv4 or uncompressed IPv6', + ); + }); + it('should return an error message for an invalid FQDN', () => { const invalidFQDN = 'example.'; const result = validateServerAddress(invalidFQDN); expect(result).toBe( - 'Each label must have a letter or number at the beginning. The maximum length is 63 characters.', + 'It should be a valid hostname, FQDN, IPv4 or uncompressed IPv6', ); }); - test('should return an error message for an invalid IP', () => { - const invalidIP = '999.999.999.999.999'; - const result = validateServerAddress(invalidIP); - expect(result).toBe('Not a valid IP'); - }); - test('should return undefined for an empty value', () => { const emptyValue = ''; const result = validateAgentName(emptyValue); diff --git a/plugins/main/public/controllers/register-agent/utils/validations.tsx b/plugins/main/public/controllers/register-agent/utils/validations.tsx index c231d99c76..6d5c402739 100644 --- a/plugins/main/public/controllers/register-agent/utils/validations.tsx +++ b/plugins/main/public/controllers/register-agent/utils/validations.tsx @@ -1,41 +1,27 @@ -//IP: This is a set of four numbers, for example, 192.158.1.38. Each number in the set can range from 0 to 255. Therefore, the full range of IP addresses goes from 0.0.0.0 to 255.255.255.255 -// O ipv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 +//IPv4: This is a set of four numbers, for example, 192.158.1.38. Each number in the set can range from 0 to 255. Therefore, the full range of IP addresses goes from 0.0.0.0 to 255.255.255.255 +//IPv6: This is a set or eight hexadecimal expressions, each from 0000 to FFFF. 2001:0db8:85a3:0000:0000:8a2e:0370:7334 // FQDN: Maximum of 63 characters per label. // Can only contain numbers, letters and hyphens (-) // Labels cannot begin or end with a hyphen // Currently supports multilingual characters, i.e. letters not included in the English alphabet: e.g. á é í ó ú ü ñ. // Minimum 3 labels -export const validateServerAddress = (value: any) => { - const isFQDN = - /^(?!-)(?!.*--)(?!.*\d$)[a-zA-Z0-9áéíóúüñ]{1,63}(?:-[a-zA-Z0-9áéíóúüñ]{1,63})*(?:\.[a-zA-Z0-9áéíóúüñ]{1,63}(?:-[a-zA-Z0-9áéíóúüñ]{1,63})*){1,}$/; - const isIP = - /^(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})$/; - const numbersAndPoints = /^[0-9.]+$/; - const areLettersNumbersAndColons = /^[a-zA-Z0-9:]+$/; - const letters = /[a-zA-Z]/; - const isFQDNFormatValid = isFQDN.test(value); - const isIPFormatValid = isIP.test(value); - const areNumbersAndPoints = numbersAndPoints.test(value); - const hasLetters = letters.test(value); - const hasPoints = value.includes('.'); +// A label can contain only numbers - let validation = undefined; - if (value.length === 0) { - return validation; - } else if (isFQDNFormatValid && value !== '') { - return validation; // FQDN valid - } else if (isIPFormatValid && value !== '') { - return validation; // IP valid - } else if (hasPoints && hasLetters && !isFQDNFormatValid) { - return (validation = - 'Each label must have a letter or number at the beginning. The maximum length is 63 characters.'); // FQDN invalid - } else if ( - (areNumbersAndPoints || areLettersNumbersAndColons) && - !isIPFormatValid +// Hostname: Maximum of 63 characters per label. Same rules as FQDN apply. + +export const validateServerAddress = (value: string) => { + const isFQDNOrHostname = + /^(?!-)(?!.*--)[a-zA-Z0-9áéíóúüñ-]{0,62}[a-zA-Z0-9áéíóúüñ](?:\.[a-zA-Z0-9áéíóúüñ-]{0,62}[a-zA-Z0-9áéíóúüñ]){0,}$/; + const isIPv6 = /^(?:[0-9a-fA-F]{4}:){7}[0-9a-fA-F]{4}$/; + + if ( + value.length > 255 || + (value.length > 0 && !isFQDNOrHostname.test(value) && !isIPv6.test(value)) ) { - return (validation = 'Not a valid IP'); // IP invalid + return 'It should be a valid hostname, FQDN, IPv4 or uncompressed IPv6'; } + return undefined; }; export const validateAgentName = (value: any) => { From 09663d4a3e0d9c4413c911d8d6ff4ba7d325e103 Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Wed, 17 Jan 2024 12:37:44 +0100 Subject: [PATCH 03/64] Fix abbreviation for Fully Qualified Domain Name (#6333) * fix abbreviation for FQDN * Add changelog --- CHANGELOG.md | 1 + .../controllers/register-agent/utils/register-agent-data.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9ef4c16c8..bb4b0670eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed invalid date format in about and agent views [#6234](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6234) - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) - Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) +- Fixed a typo in an abbreviation for Fully Qualified Domain Name [#6333](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6333) ### Removed diff --git a/plugins/main/public/controllers/register-agent/utils/register-agent-data.tsx b/plugins/main/public/controllers/register-agent/utils/register-agent-data.tsx index 39d39d19bf..004891c324 100644 --- a/plugins/main/public/controllers/register-agent/utils/register-agent-data.tsx +++ b/plugins/main/public/controllers/register-agent/utils/register-agent-data.tsx @@ -34,7 +34,7 @@ export const SERVER_ADDRESS_TEXTS = [ { title: 'Server address', subtitle: - 'This is the address the agent uses to communicate with the server. Enter an IP address or a fully qualified domain name (FDQN).', + 'This is the address the agent uses to communicate with the server. Enter an IP address or a fully qualified domain name (FQDN).', }, ]; From 7a9b3c99320b5e7532e1d53a445701b21ef19c5c Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Thu, 18 Jan 2024 07:58:40 -0300 Subject: [PATCH 04/64] Fix vulnerability detail truncated text in big fields (#6338) * Fix vulnerability detail truncated text in big fields * Update CHANGELOG --- CHANGELOG.md | 2 +- .../dashboards/inventory/inventory.tsx | 2 +- .../vulnerabilities/doc_viewer/doc_viewer.tsx | 272 ++++++++++-------- 3 files changed, 149 insertions(+), 127 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb4b0670eb..3b6165625d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index 121b356289..9be439669b 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -238,7 +238,7 @@ const InventoryVulsComponent = () => { setInspectedHit(undefined)} size='m'> -

Document Details

+

Document details

diff --git a/plugins/main/public/components/overview/vulnerabilities/doc_viewer/doc_viewer.tsx b/plugins/main/public/components/overview/vulnerabilities/doc_viewer/doc_viewer.tsx index 08e170f9d5..429acdeb92 100644 --- a/plugins/main/public/components/overview/vulnerabilities/doc_viewer/doc_viewer.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/doc_viewer/doc_viewer.tsx @@ -9,142 +9,164 @@ const COLLAPSE_LINE_LENGTH = 350; const DOT_PREFIX_RE = /(.).+?\./g; export type tDocViewerProps = { - flattened: any; - formatted: any; - mapping: any; - indexPattern: any; -} + flattened: any; + formatted: any; + mapping: any; + indexPattern: any; +}; /** * Convert a dot.notated.string into a short * version (d.n.string) */ -export const shortenDottedString = (input: string) => input.replace(DOT_PREFIX_RE, '$1.'); +export const shortenDottedString = (input: string) => + input.replace(DOT_PREFIX_RE, '$1.'); export function getFieldTypeName(type: string) { - switch (type) { - case 'boolean': - return i18n.translate('discover.fieldNameIcons.booleanAriaLabel', { - defaultMessage: 'Boolean field', - }); - case 'conflict': - return i18n.translate('discover.fieldNameIcons.conflictFieldAriaLabel', { - defaultMessage: 'Conflicting field', - }); - case 'date': - return i18n.translate('discover.fieldNameIcons.dateFieldAriaLabel', { - defaultMessage: 'Date field', - }); - case 'geo_point': - return i18n.translate('discover.fieldNameIcons.geoPointFieldAriaLabel', { - defaultMessage: 'Geo point field', - }); - case 'geo_shape': - return i18n.translate('discover.fieldNameIcons.geoShapeFieldAriaLabel', { - defaultMessage: 'Geo shape field', - }); - case 'ip': - return i18n.translate('discover.fieldNameIcons.ipAddressFieldAriaLabel', { - defaultMessage: 'IP address field', - }); - case 'murmur3': - return i18n.translate('discover.fieldNameIcons.murmur3FieldAriaLabel', { - defaultMessage: 'Murmur3 field', - }); - case 'number': - return i18n.translate('discover.fieldNameIcons.numberFieldAriaLabel', { - defaultMessage: 'Number field', - }); - case 'source': - // Note that this type is currently not provided, type for _source is undefined - return i18n.translate('discover.fieldNameIcons.sourceFieldAriaLabel', { - defaultMessage: 'Source field', - }); - case 'string': - return i18n.translate('discover.fieldNameIcons.stringFieldAriaLabel', { - defaultMessage: 'String field', - }); - case 'nested': - return i18n.translate('discover.fieldNameIcons.nestedFieldAriaLabel', { - defaultMessage: 'Nested field', - }); - default: - return i18n.translate('discover.fieldNameIcons.unknownFieldAriaLabel', { - defaultMessage: 'Unknown field', - }); - } + switch (type) { + case 'boolean': + return i18n.translate('discover.fieldNameIcons.booleanAriaLabel', { + defaultMessage: 'Boolean field', + }); + case 'conflict': + return i18n.translate('discover.fieldNameIcons.conflictFieldAriaLabel', { + defaultMessage: 'Conflicting field', + }); + case 'date': + return i18n.translate('discover.fieldNameIcons.dateFieldAriaLabel', { + defaultMessage: 'Date field', + }); + case 'geo_point': + return i18n.translate('discover.fieldNameIcons.geoPointFieldAriaLabel', { + defaultMessage: 'Geo point field', + }); + case 'geo_shape': + return i18n.translate('discover.fieldNameIcons.geoShapeFieldAriaLabel', { + defaultMessage: 'Geo shape field', + }); + case 'ip': + return i18n.translate('discover.fieldNameIcons.ipAddressFieldAriaLabel', { + defaultMessage: 'IP address field', + }); + case 'murmur3': + return i18n.translate('discover.fieldNameIcons.murmur3FieldAriaLabel', { + defaultMessage: 'Murmur3 field', + }); + case 'number': + return i18n.translate('discover.fieldNameIcons.numberFieldAriaLabel', { + defaultMessage: 'Number field', + }); + case 'source': + // Note that this type is currently not provided, type for _source is undefined + return i18n.translate('discover.fieldNameIcons.sourceFieldAriaLabel', { + defaultMessage: 'Source field', + }); + case 'string': + return i18n.translate('discover.fieldNameIcons.stringFieldAriaLabel', { + defaultMessage: 'String field', + }); + case 'nested': + return i18n.translate('discover.fieldNameIcons.nestedFieldAriaLabel', { + defaultMessage: 'Nested field', + }); + default: + return i18n.translate('discover.fieldNameIcons.unknownFieldAriaLabel', { + defaultMessage: 'Unknown field', + }); + } } const DocViewer = (props: tDocViewerProps) => { - const [fieldRowOpen, setFieldRowOpen] = useState({} as Record); - const { flattened, formatted, mapping, indexPattern } = props; + const [fieldRowOpen, setFieldRowOpen] = useState( + {} as Record, + ); + const { flattened, formatted, mapping, indexPattern } = props; - return (<> - {flattened && ( - - - {Object.keys(flattened) - .sort() - .map((field, index) => { - const value = String(formatted[field]); - const fieldMapping = mapping(field); - const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; - const isCollapsed = isCollapsible && !fieldRowOpen[field]; - const valueClassName = classNames({ - // eslint-disable-next-line @typescript-eslint/naming-convention - osdDocViewer__value: true, - 'truncate-by-height': isCollapsible && isCollapsed, - }); - const isNestedField = - !indexPattern.fields.getByName(field) && - !!indexPattern.fields.getAll().find((patternField) => { - // We only want to match a full path segment - const nestedRootRegex = new RegExp(escapeRegExp(field) + '(\\.|$)'); - return nestedRootRegex.test(patternField.subType?.nested?.path ?? ''); - }); - const fieldType = isNestedField ? 'nested' : indexPattern.fields.getByName(field)?.type; - const typeName = getFieldTypeName(String(fieldType)); - const displayName = field; - const fieldIconProps = { fill: 'none', color: 'gray' } - const scripted = Boolean(fieldMapping?.scripted) + return ( + <> + {flattened && ( +
+ + {Object.keys(flattened) + .sort() + .map((field, index) => { + const value = String(formatted[field]); + const fieldMapping = mapping(field); + const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; + const isCollapsed = isCollapsible && !fieldRowOpen[field]; + const valueClassName = classNames({ + // eslint-disable-next-line @typescript-eslint/naming-convention + osdDocViewer__value: true, + 'truncate-by-height': isCollapsible && isCollapsed, + }); + const isNestedField = + !indexPattern.fields.getByName(field) && + !!indexPattern.fields.getAll().find(patternField => { + // We only want to match a full path segment + const nestedRootRegex = new RegExp( + escapeRegExp(field) + '(\\.|$)', + ); + return nestedRootRegex.test( + patternField.subType?.nested?.path ?? '', + ); + }); + const fieldType = isNestedField + ? 'nested' + : indexPattern.fields.getByName(field)?.type; + const typeName = getFieldTypeName(String(fieldType)); + const displayName = field; + const fieldIconProps = { fill: 'none', color: 'gray' }; + const scripted = Boolean(fieldMapping?.scripted); - return ( - - - - - ); - })} - -
- - - - - - - {displayName} - - - - -
-
- )}) + return ( + + + + + + + + + {displayName} + + + + + +
+ + + ); + })} + + + )} + + ); }; -export default DocViewer; \ No newline at end of file +export default DocViewer; From cae72da9a92cf5493fe072c9e2988b50f9734d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Biset?= <43619595+jbiset@users.noreply.github.com> Date: Thu, 18 Jan 2024 07:59:43 -0300 Subject: [PATCH 05/64] Fix maximize in embeddable vulnerability panel (#6330) * Fix to maximize display panel * Fixed overflow in the minimize panel. --------- Co-authored-by: Federico Rodriguez --- .../vulnerability_detector_filters.scss | 6 + plugins/main/public/styles/common.scss | 119 +++++++++++------- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/vulnerability_detector_filters.scss b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/vulnerability_detector_filters.scss index d27e09efb0..c953f43a4f 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/vulnerability_detector_filters.scss +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/vulnerability_detector_filters.scss @@ -3,6 +3,9 @@ .euiDataGrid__pagination { display: none !important; } + .visTable { + overflow: hidden !important; + } } .vulnerability-dashboard-responsive { @@ -10,5 +13,8 @@ .react-grid-layout { height: auto !important; } + .dshLayout-isMaximizedPanel { + height: 100% !important; + } } } diff --git a/plugins/main/public/styles/common.scss b/plugins/main/public/styles/common.scss index c88d18117e..63ea08e7b9 100644 --- a/plugins/main/public/styles/common.scss +++ b/plugins/main/public/styles/common.scss @@ -306,7 +306,7 @@ /* Custom input filter box styles */ -input[type="search"].euiFieldSearch { +input[type='search'].euiFieldSearch { box-sizing: inherit !important; } @@ -365,7 +365,9 @@ input[type="search"].euiFieldSearch { box-shadow: none; } -:focus:not(.wz-button):not(.input-filter-box):not(.kuiLocalSearchInput):not(.euiTextArea):not(.euiPanel.euiPopover__panel.euiPopover__panel-isOpen) { +:focus:not(.wz-button):not(.input-filter-box):not(.kuiLocalSearchInput):not( + .euiTextArea + ):not(.euiPanel.euiPopover__panel.euiPopover__panel-isOpen) { box-shadow: none !important; } @@ -443,7 +445,7 @@ md-content { color: black !important; } -.table-hover>tbody>tr:hover { +.table-hover > tbody > tr:hover { background-color: #fafbfd !important; } @@ -777,7 +779,7 @@ md-switch.md-checked .md-thumb { min-height: 300px; } -.nav-bar-white-bg>div { +.nav-bar-white-bg > div { background: #fff; } @@ -803,7 +805,7 @@ md-switch.md-checked .md-thumb { * https://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/ * Handling long URLs on error toasts. */ -.euiGlobalToastList>.euiToast>.euiToastHeader>.euiToastHeader__title { +.euiGlobalToastList > .euiToast > .euiToastHeader > .euiToastHeader__title { overflow-wrap: break-word; word-wrap: break-word; -ms-word-break: break-all; @@ -866,34 +868,34 @@ wz-xml-file-editor { background: #ecf6fb !important; } -.table-striped>tbody>tr:nth-of-type(odd) { +.table-striped > tbody > tr:nth-of-type(odd) { background-color: transparent !important; } -.table-striped>tbody>tr:nth-of-type(odd):hover { +.table-striped > tbody > tr:nth-of-type(odd):hover { background-color: #fafbfd !important; } -.table-striped-duo>tbody tr:not(.euiTableRow):nth-child(2n + 1):not(:hover), -.table-striped-duo>tbody tr:not(.euiTableRow):nth-child(2n + 2):not(:hover) { +.table-striped-duo > tbody tr:not(.euiTableRow):nth-child(2n + 1):not(:hover), +.table-striped-duo > tbody tr:not(.euiTableRow):nth-child(2n + 2):not(:hover) { background: #f9f9f9; } -.table-striped-duo>tbody tr:not(.euiTableRow):nth-child(4n + 1):not(:hover), -.table-striped-duo>tbody tr:not(.euiTableRow):nth-child(4n + 2):not(:hover) { +.table-striped-duo > tbody tr:not(.euiTableRow):nth-child(4n + 1):not(:hover), +.table-striped-duo > tbody tr:not(.euiTableRow):nth-child(4n + 2):not(:hover) { background: #fff; } -.table-resizable>thead th:not(:first-child) { +.table-resizable > thead th:not(:first-child) { border-left: 1px dashed #dfeff8; overflow: hidden; } -.table-resizable>thead th:last-child .ui-resizable-handle { +.table-resizable > thead th:last-child .ui-resizable-handle { display: none !important; } -.table-resizable td+td { +.table-resizable td + td { width: auto; } @@ -944,7 +946,7 @@ wz-xml-file-editor { display: block !important; } -.sca-vis .visWrapper .visWrapper__chart>div>svg>g>text:nth-child(2) { +.sca-vis .visWrapper .visWrapper__chart > div > svg > g > text:nth-child(2) { font-size: 10px !important; } @@ -1033,7 +1035,7 @@ wz-xml-file-editor { white-space: nowrap; } -.health-check dl.euiDescriptionList dd>span:first-child { +.health-check dl.euiDescriptionList dd > span:first-child { display: inline-block; width: 26px; } @@ -1111,7 +1113,7 @@ wz-xml-file-editor { .wz-link { cursor: pointer; - color: #006BB4; + color: #006bb4; text-decoration: none; } @@ -1168,7 +1170,7 @@ wz-xml-file-editor { margin: 0px; } -.header-global-wrapper+.app-wrapper:not(.hidden-chrome) { +.header-global-wrapper + .app-wrapper:not(.hidden-chrome) { top: 48px !important; left: 48px !important; } @@ -1180,7 +1182,8 @@ wz-xml-file-editor { .reqCard:hover, .reqCard:focus { transform: translateY(0px) !important; - box-shadow: 0 2px 2px -1px rgba(152, 162, 179, 0.3), 0 1px 5px -2px rgba(152, 162, 179, 0.3) !important; + box-shadow: 0 2px 2px -1px rgba(152, 162, 179, 0.3), + 0 1px 5px -2px rgba(152, 162, 179, 0.3) !important; } .reqCard:hover .euiCard__title, @@ -1241,7 +1244,6 @@ wz-xml-file-editor { color: #377dbb !important; } - .list-of-files-fail { margin-top: 10px; margin-bottom: 10px; @@ -1312,8 +1314,8 @@ md-chips .md-chips { .title-pin:hover:after { padding-left: 5px; font-size: 12px; - content: "\f00e"; - font-family: "FontAwesome"; + content: '\f00e'; + font-family: 'FontAwesome'; color: #0b6bb4; position: absolute; } @@ -1323,15 +1325,15 @@ md-chips .md-chips { // margin-top: 50px; // } -.wz-markdown-margin>p { +.wz-markdown-margin > p { margin-top: 5px; } -.wz-markdown-margin>ul { +.wz-markdown-margin > ul { list-style: disc; } -.wz-markdown-margin>ul>li { +.wz-markdown-margin > ul > li { margin-left: 25px; } @@ -1369,7 +1371,7 @@ md-chips .md-chips { border: solid 1px #d9d9d9; } -.react-code-mirror>.CodeMirror.CodeMirror-wrap.cm-s-default { +.react-code-mirror > .CodeMirror.CodeMirror-wrap.cm-s-default { height: 100% !important; } @@ -1441,7 +1443,6 @@ div.euiPopover__panel.euiPopover__panel-isOpen.euiPopover__panel--bottom.wz-menu padding-right: 0; } - .euiSuggestItem .euiSuggestItem__label { flex-basis: 25%; min-width: 25%; @@ -1468,7 +1469,7 @@ div.euiPopover__panel.euiPopover__panel-isOpen.euiPopover__panel--bottom.wz-menu } .euiCodeBlock.euiCodeBlock-isFullScreen { - border: 1px solid #D3DAE6; + border: 1px solid #d3dae6; border-radius: 4px; margin: 22px; } @@ -1488,7 +1489,7 @@ div.euiPopover__panel.euiPopover__panel-isOpen.euiPopover__panel--bottom.wz-menu margin-left: 24px; width: 100%; height: 2px; - background-color: #006BB4; + background-color: #006bb4; -webkit-animation: euiBasicTableLoading 1000ms linear; animation: euiBasicTableLoading 1000ms linear; -webkit-animation-iteration-count: infinite; @@ -1523,7 +1524,12 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { } /* Change custom discover size */ -.wz-discover>.globalQueryBar>.kbnQueryBar--withDatePicker>.euiFlexItem.euiFlexItem--flexGrowZero>.euiFlexGroup>.euiFlexItem.kbnQueryBar__datePickerWrapper { +.wz-discover + > .globalQueryBar + > .kbnQueryBar--withDatePicker + > .euiFlexItem.euiFlexItem--flexGrowZero + > .euiFlexGroup + > .euiFlexItem.kbnQueryBar__datePickerWrapper { max-width: 300px; } @@ -1533,13 +1539,18 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { } /* Change custom discover size */ - .wz-discover>.globalQueryBar>.euiFlexGroup.kbnQueryBar.kbnQueryBar--withDatePicker { + .wz-discover + > .globalQueryBar + > .euiFlexGroup.kbnQueryBar.kbnQueryBar--withDatePicker { flex-wrap: wrap; margin-left: 0; margin-right: 0; } - .wz-discover>.globalQueryBar>.euiFlexGroup.kbnQueryBar.kbnQueryBar--withDatePicker>.euiFlexItem { + .wz-discover + > .globalQueryBar + > .euiFlexGroup.kbnQueryBar.kbnQueryBar--withDatePicker + > .euiFlexItem { width: 100% !important; -ms-flex-preferred-size: 100% !important; flex-basis: 100% !important; @@ -1548,16 +1559,27 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { margin-bottom: 16px !important; } - .wz-discover>.globalQueryBar>.kbnQueryBar--withDatePicker> :first-child { + .wz-discover > .globalQueryBar > .kbnQueryBar--withDatePicker > :first-child { order: 1; margin-top: -8px; } - .wz-discover>.globalQueryBar>.kbnQueryBar--withDatePicker>.euiFlexItem.euiFlexItem--flexGrowZero>.euiFlexGroup>.euiFlexItem.kbnQueryBar__datePickerWrapper>.euiFlexGroup { + .wz-discover + > .globalQueryBar + > .kbnQueryBar--withDatePicker + > .euiFlexItem.euiFlexItem--flexGrowZero + > .euiFlexGroup + > .euiFlexItem.kbnQueryBar__datePickerWrapper + > .euiFlexGroup { width: 100%; } - .wz-discover>.globalQueryBar>.kbnQueryBar--withDatePicker>.euiFlexItem.euiFlexItem--flexGrowZero>.euiFlexGroup>.euiFlexItem.kbnQueryBar__datePickerWrapper { + .wz-discover + > .globalQueryBar + > .kbnQueryBar--withDatePicker + > .euiFlexItem.euiFlexItem--flexGrowZero + > .euiFlexGroup + > .euiFlexItem.kbnQueryBar__datePickerWrapper { flex-grow: 1 !important; max-width: none; } @@ -1587,7 +1609,6 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { .agents-details-card { width: 55vw; } - } @media (max-width: 1599px) { @@ -1624,7 +1645,7 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { } } -.chrHeaderWrapper--navIsLocked~.app-wrapper .wz-module-header-agent-wrapper { +.chrHeaderWrapper--navIsLocked ~ .app-wrapper .wz-module-header-agent-wrapper { padding-left: 320px; } @@ -1642,7 +1663,6 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { background-color: transparent !important; } - .ace_scrollbar-v { margin-top: -10px !important; } @@ -1661,7 +1681,6 @@ kbn-dis.hide-filter-control .globalFilterGroup__branch { text-decoration: none !important; } - .history-list { background-color: white; border: 1px solid #80808061; @@ -1720,7 +1739,7 @@ iframe.width-changed { } .code-block-log-viewer-container { - max-width: calc(100vw - 41*2px); + max-width: calc(100vw - 41 * 2px); } .dscFieldDetails__barContainer { @@ -1768,7 +1787,6 @@ iframe.width-changed { } .wz-euiCard-no-title { - .euiCard__title, .euiCard__description { display: none; @@ -1793,7 +1811,7 @@ iframe.width-changed { } @media only screen and (max-width: 767px) { - .header-global-wrapper+.app-wrapper:not(.hidden-chrome) { + .header-global-wrapper + .app-wrapper:not(.hidden-chrome) { left: 0 !important; } @@ -1817,19 +1835,26 @@ iframe.width-changed { } .wz-flex { - display: flex; + display: flex; } .wz-callout-message { - margin-top: 10px; - display: flex; - flex-direction: row; + margin-top: 10px; + display: flex; + flex-direction: row; } -.wz-overflow-auto{ +.wz-overflow-auto { overflow: auto; } .wz-vertical-align-middle { vertical-align: middle !important; } + +/* Workaround to fix maximize embeddable dashboard */ +.wz-app .dshLayout-isMaximizedPanel { + top: 0; + left: 0; + z-index: 9999; +} From e4274d25ed39a1e95187e9ed639d977ea28f5501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Biset?= <43619595+jbiset@users.noreply.github.com> Date: Thu, 18 Jan 2024 08:21:17 -0300 Subject: [PATCH 06/64] Change default vulnerabilities pattern health check to false (#6321) * Change default vulnerabilities pattern health check to false * Add CHANGELOG * Modify changelog * Undo last commit made by mistake --------- Co-authored-by: Tostti Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- plugins/main/common/constants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b6165625d..185d7dc6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/common/constants.ts b/plugins/main/common/constants.ts index ab420dcaac..ee1ee5b600 100644 --- a/plugins/main/common/constants.ts +++ b/plugins/main/common/constants.ts @@ -841,7 +841,7 @@ export const PLUGIN_SETTINGS: { [key: string]: TPluginSetting } = { 'Enable or disable the vulnerabilities index pattern health check when opening the app.', category: SettingCategory.HEALTH_CHECK, type: EpluginSettingType.switch, - defaultValue: true, + defaultValue: false, isConfigurableFromFile: true, isConfigurableFromUI: true, options: { From 21fa7f7ef5bf4002aa0d1b324fd9398e7aec8c56 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:31:41 +0100 Subject: [PATCH 07/64] Hide discover deprecation notice (#6341) * Hide discover deprecation notice * Update changelog * Update changelog --- CHANGELOG.md | 1 + plugins/main/public/plugin.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 185d7dc6f8..53e1d07319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed the ability to configure the visibility of modules and removed `extensions.*` settings [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Removed the application menu in the IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) - Removed the implicit filter of WQL language of the search bar UI [#6174](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6174) +- Removed notice of old Discover deprecation [#6341](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6341) ## Wazuh v4.7.2 - OpenSearch Dashboards 2.8.0 - Revision 02 diff --git a/plugins/main/public/plugin.ts b/plugins/main/public/plugin.ts index ab5ea70129..a86adb9989 100644 --- a/plugins/main/public/plugin.ts +++ b/plugins/main/public/plugin.ts @@ -57,6 +57,10 @@ export class WazuhPlugin private innerAngularInitialized: boolean = false; private hideTelemetryBanner?: () => void; public async setup(core: CoreSetup, plugins: WazuhSetupPlugins): WazuhSetup { + // Hide the discover deprecation notice + // After opensearch version 2.11.0 this line may be deleted + localStorage.setItem('discover:deprecation-notice:show', 'false'); + // Get custom logos configuration to start up the app with the correct logos let logosInitialState = {}; try { From c4d8f1bfeb743da74f852843c82f63516b219306 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:49:54 +0100 Subject: [PATCH 08/64] The check update button does not show the date of the last scan (#6328) * Fix date of the last scan(check update) * Fix menu overlapping with notification of updates * Fix test * Update changelog * Use service * Fix published date * Fix test --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- plugins/main/opensearch_dashboards.json | 5 +- .../components/settings/api/api-table.js | 20 +++---- .../update-detail.test.tsx | 23 +++++--- .../update-detail.tsx | 29 +++++----- plugins/main/public/kibana-services.ts | 2 + plugins/main/public/plugin.ts | 2 + .../components/updates-notification.scss | 14 ++--- .../components/updates-notification.test.tsx | 5 ++ .../components/updates-notification.tsx | 53 ++++++++++++------- plugins/wazuh-core/public/hooks/index.ts | 1 + .../public/hooks/use-docked-side-nav.tsx | 20 +++++++ plugins/wazuh-core/public/plugin-services.ts | 10 +++- plugins/wazuh-core/public/plugin.ts | 5 +- plugins/wazuh-core/public/types.ts | 1 + 15 files changed, 123 insertions(+), 69 deletions(-) create mode 100644 plugins/wazuh-core/public/hooks/index.ts create mode 100644 plugins/wazuh-core/public/hooks/use-docked-side-nav.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e1d07319..c486730508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Added - Support for Wazuh 4.8.0 -- Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) +- Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) - Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index c51068870a..57736d8726 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -19,7 +19,8 @@ "opensearchDashboardsReact", "opensearchDashboardsUtils", "opensearchDashboardsLegacy", - "wazuhCheckUpdates" + "wazuhCheckUpdates", + "wazuhCore" ], "optionalPlugins": [ "security", @@ -29,4 +30,4 @@ ], "server": true, "ui": true -} \ No newline at end of file +} diff --git a/plugins/main/public/components/settings/api/api-table.js b/plugins/main/public/components/settings/api/api-table.js index 89bed290c1..8511b4cc93 100644 --- a/plugins/main/public/components/settings/api/api-table.js +++ b/plugins/main/public/components/settings/api/api-table.js @@ -35,9 +35,11 @@ import { compose } from 'redux'; import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; import { UI_LOGGER_LEVELS } from '../../../../common/constants'; import { getErrorOrchestrator } from '../../../react-services/common-services'; -import { getWazuhCheckUpdatesPlugin } from '../../../kibana-services'; +import { + getWazuhCheckUpdatesPlugin, + getWazuhCorePlugin, +} from '../../../kibana-services'; import { AvailableUpdatesFlyout } from './available-updates-flyout'; -import { formatUIDate } from '../../../react-services/time-service'; export const ApiTable = compose( withErrorBoundary, @@ -47,13 +49,10 @@ export const ApiTable = compose( constructor(props) { super(props); - const { getAvailableUpdates } = getWazuhCheckUpdatesPlugin(); - this.state = { apiEntries: [], refreshingEntries: false, availableUpdates: {}, - getAvailableUpdates, refreshingAvailableUpdates: true, apiAvailableUpdateDetails: undefined, }; @@ -62,9 +61,8 @@ export const ApiTable = compose( async getApisAvailableUpdates(forceUpdate = false) { try { this.setState({ refreshingAvailableUpdates: true }); - const availableUpdates = await this.state.getAvailableUpdates( - forceUpdate, - ); + const availableUpdates = + await getWazuhCheckUpdatesPlugin().getAvailableUpdates(forceUpdate); this.setState({ availableUpdates }); } catch (error) { const options = { @@ -553,10 +551,8 @@ export const ApiTable = compose( title='Last check' content={ this.state.availableUpdates?.last_check_date - ? formatUIDate( - new Date( - this.state.availableUpdates.last_check_date, - ), + ? getWazuhCorePlugin().utils.formatUIDate( + this.state.availableUpdates.last_check_date, ) : '-' } diff --git a/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.test.tsx b/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.test.tsx index 3065bee989..0ff3b36489 100644 --- a/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.test.tsx +++ b/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.test.tsx @@ -7,22 +7,29 @@ jest.mock( '../../../../../../../node_modules/@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ htmlIdGenerator: () => () => 'htmlId', - }) + }), ); -jest.mock('../../../../react-services/time-service', () => ({ - formatUIDate: jest.fn().mockReturnValue('Sep 25, 2023 @ 14:03:40.816'), +jest.mock('../../../../kibana-services', () => ({ + getWazuhCorePlugin: jest.fn().mockReturnValue({ + utils: { + formatUIDate: jest.fn().mockReturnValue('Sep 25, 2023 @ 14:03:40.816'), + }, + }), })); -jest.mock('../../../../../../../src/plugins/opensearch_dashboards_react/public', () => ({ - Markdown: jest.fn().mockReturnValue(
Description
), -})); +jest.mock( + '../../../../../../../src/plugins/opensearch_dashboards_react/public', + () => ({ + Markdown: jest.fn().mockReturnValue(
Description
), + }), +); describe('UpdateDetail component', () => { test('should return the UpdateDetail component', async () => { const { container, getByText, getByRole } = render( { tag: 'v4.8.0', title: 'Wazuh v4.8.0', }} - /> + />, ); expect(container).toMatchSnapshot(); diff --git a/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.tsx b/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.tsx index 24e04b142b..a678076905 100644 --- a/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.tsx +++ b/plugins/main/public/components/settings/api/available-updates-flyout/update-detail.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { Update } from '../../../../../../wazuh-check-updates/common/types'; -import { formatUIDate } from '../../../../react-services/time-service'; import { Markdown } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; import { EuiAccordion, @@ -12,6 +11,7 @@ import { EuiBadge, EuiTitle, } from '@elastic/eui'; +import { getWazuhCorePlugin } from '../../../../kibana-services'; interface UpdateDetailProps { update: Partial; @@ -25,7 +25,9 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => { semver?.major && (semver?.minor || semver?.minor === 0) && (semver?.patch || semver?.patch === 0); - const minorVersion = hasVersions ? `${semver.major}.${semver.minor}` : undefined; + const minorVersion = hasVersions + ? `${semver.major}.${semver.minor}` + : undefined; const releaseNotesUrl = hasVersions ? `https://documentation.wazuh.com/current/release-notes/release-${semver.major}-${semver.minor}-${semver.patch}.html` : undefined; @@ -36,21 +38,21 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => { return title && tag ? ( + - +

{title}

- {type} + {type}
} - paddingSize="l" + paddingSize='l' > {published_date ? ( <> @@ -58,7 +60,8 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => { listItems={[ { title: 'Published', - description: formatUIDate(new Date(published_date)), + description: + getWazuhCorePlugin().utils.formatUIDate(published_date), }, ]} /> @@ -69,12 +72,12 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => { <> - + Release notes - + Upgrade guide @@ -82,7 +85,9 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => { ) : null} - {description ? : null} + {description ? ( + + ) : null}
) : null; }; diff --git a/plugins/main/public/kibana-services.ts b/plugins/main/public/kibana-services.ts index 1257f238ed..1c536dc5e1 100644 --- a/plugins/main/public/kibana-services.ts +++ b/plugins/main/public/kibana-services.ts @@ -45,6 +45,8 @@ export const [getWzCurrentAppID, setWzCurrentAppID] = createGetterSetter('WzCurrentAppID'); export const [getWazuhCheckUpdatesPlugin, setWazuhCheckUpdatesPlugin] = createGetterSetter('WazuhCheckUpdatesPlugin'); +export const [getWazuhCorePlugin, setWazuhCorePlugin] = + createGetterSetter('WazuhCorePlugin'); export const [getHeaderActionMenuMounter, setHeaderActionMenuMounter] = createGetterSetter( 'headerActionMenuMounter', diff --git a/plugins/main/public/plugin.ts b/plugins/main/public/plugin.ts index a86adb9989..8126e4acc5 100644 --- a/plugins/main/public/plugin.ts +++ b/plugins/main/public/plugin.ts @@ -24,6 +24,7 @@ import { setWzCurrentAppID, setWazuhCheckUpdatesPlugin, setHeaderActionMenuMounter, + setWazuhCorePlugin, } from './kibana-services'; import { AppPluginStartDependencies, @@ -225,6 +226,7 @@ export class WazuhPlugin setOverlays(core.overlays); setErrorOrchestrator(ErrorOrchestratorService); setWazuhCheckUpdatesPlugin(plugins.wazuhCheckUpdates); + setWazuhCorePlugin(plugins.wazuhCore); return {}; } } diff --git a/plugins/wazuh-check-updates/public/components/updates-notification.scss b/plugins/wazuh-check-updates/public/components/updates-notification.scss index fa19126902..21eb2494b3 100644 --- a/plugins/wazuh-check-updates/public/components/updates-notification.scss +++ b/plugins/wazuh-check-updates/public/components/updates-notification.scss @@ -1,11 +1,3 @@ -.euiBody--hasFlyout { - .wz-check-updates-bottom-bar { - margin-left: 320px; - } - - &.euiBody-hasOverlayMask { - .wz-check-updates-bottom-bar { - margin-left: 0px; - } - } - } \ No newline at end of file +.wz-check-updates-bottom-bar { + margin-left: 320px; +} diff --git a/plugins/wazuh-check-updates/public/components/updates-notification.test.tsx b/plugins/wazuh-check-updates/public/components/updates-notification.test.tsx index 222db29f1d..20d1ab1683 100644 --- a/plugins/wazuh-check-updates/public/components/updates-notification.test.tsx +++ b/plugins/wazuh-check-updates/public/components/updates-notification.test.tsx @@ -27,6 +27,11 @@ jest.mock('../plugin-services', () => ({ }, }, }), + getWazuhCore: jest.fn().mockReturnValue({ + hooks: { + useDockedSideNav: () => false, + }, + }), })); jest.mock('react-use/lib/useObservable', () => () => {}); diff --git a/plugins/wazuh-check-updates/public/components/updates-notification.tsx b/plugins/wazuh-check-updates/public/components/updates-notification.tsx index 7c3828302a..e0d2d0e433 100644 --- a/plugins/wazuh-check-updates/public/components/updates-notification.tsx +++ b/plugins/wazuh-check-updates/public/components/updates-notification.tsx @@ -11,7 +11,7 @@ import React, { useEffect, useState } from 'react'; import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; import { useUserPreferences } from '../hooks'; import { areThereNewUpdates } from '../utils'; -import { getCore } from '../plugin-services'; +import { getCore, getWazuhCore } from '../plugin-services'; import { AvailableUpdates } from '../../../wazuh-check-updates/common/types'; import { getAvailableUpdates } from '../services'; import { RedirectAppLinks } from '../../../../src/plugins/opensearch_dashboards_react/public'; @@ -22,6 +22,8 @@ export const UpdatesNotification = () => { const [isDismissed, setIsDismissed] = useState(false); const [dismissFutureUpdates, setDismissFutureUpdates] = useState(false); + const sideNavDocked = getWazuhCore().hooks.useDockedSideNav(); + const { userPreferences, error: userPreferencesError, @@ -57,7 +59,7 @@ export const UpdatesNotification = () => { const mustNotifyUser = areThereNewUpdates( availableUpdates?.apis_available_updates, - userPreferences.last_dismissed_updates + userPreferences.last_dismissed_updates, ); const handleOnChangeDismiss = (checked: boolean) => { @@ -67,7 +69,7 @@ export const UpdatesNotification = () => { const handleOnClose = () => { updateUserPreferences({ last_dismissed_updates: availableUpdates?.apis_available_updates?.map( - (apiAvailableUpdates) => { + apiAvailableUpdates => { const { api_id, last_available_major, @@ -80,7 +82,7 @@ export const UpdatesNotification = () => { last_minor: last_available_minor?.tag, last_patch: last_available_patch?.tag, }; - } + }, ), ...(dismissFutureUpdates ? { hide_update_notifications: true } : {}), }); @@ -89,29 +91,35 @@ export const UpdatesNotification = () => { return mustNotifyUser ? ( - - + + - + @@ -119,25 +127,30 @@ export const UpdatesNotification = () => { - + } checked={dismissFutureUpdates} - onChange={(e) => handleOnChangeDismiss(e.target.checked)} + onChange={e => handleOnChangeDismiss(e.target.checked)} /> - handleOnClose()}> + handleOnClose()} + > diff --git a/plugins/wazuh-core/public/hooks/index.ts b/plugins/wazuh-core/public/hooks/index.ts new file mode 100644 index 0000000000..d06d93425c --- /dev/null +++ b/plugins/wazuh-core/public/hooks/index.ts @@ -0,0 +1 @@ +export { useDockedSideNav } from './use-docked-side-nav'; diff --git a/plugins/wazuh-core/public/hooks/use-docked-side-nav.tsx b/plugins/wazuh-core/public/hooks/use-docked-side-nav.tsx new file mode 100644 index 0000000000..a3c59f08ce --- /dev/null +++ b/plugins/wazuh-core/public/hooks/use-docked-side-nav.tsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { getChrome } from '../plugin-services'; + +export const useDockedSideNav = () => { + const [sideNavDocked, setSideNavDocked] = useState(false); + + useEffect(() => { + const isNavDrawerSubscription = getChrome() + .getIsNavDrawerLocked$() + .subscribe((value: boolean) => { + setSideNavDocked(value); + }); + + return () => { + isNavDrawerSubscription.unsubscribe(); + }; + }, []); + + return sideNavDocked; +}; diff --git a/plugins/wazuh-core/public/plugin-services.ts b/plugins/wazuh-core/public/plugin-services.ts index de618c9e18..626d2fbba1 100644 --- a/plugins/wazuh-core/public/plugin-services.ts +++ b/plugins/wazuh-core/public/plugin-services.ts @@ -1,5 +1,11 @@ -import { CoreStart, IUiSettingsClient } from 'opensearch-dashboards/public'; +import { + ChromeStart, + CoreStart, + IUiSettingsClient, +} from 'opensearch-dashboards/public'; import { createGetterSetter } from '../../../src/plugins/opensearch_dashboards_utils/common'; +export const [getChrome, setChrome] = createGetterSetter('Chrome'); export const [getCore, setCore] = createGetterSetter('Core'); -export const [getUiSettings, setUiSettings] = createGetterSetter('UiSettings'); +export const [getUiSettings, setUiSettings] = + createGetterSetter('UiSettings'); diff --git a/plugins/wazuh-core/public/plugin.ts b/plugins/wazuh-core/public/plugin.ts index 8b3078adba..f25ff297fe 100644 --- a/plugins/wazuh-core/public/plugin.ts +++ b/plugins/wazuh-core/public/plugin.ts @@ -1,7 +1,8 @@ import { CoreSetup, CoreStart, Plugin } from 'opensearch-dashboards/public'; import { WazuhCorePluginSetup, WazuhCorePluginStart } from './types'; -import { setCore, setUiSettings } from './plugin-services'; +import { setChrome, setCore, setUiSettings } from './plugin-services'; import * as utils from './utils'; +import * as hooks from './hooks'; export class WazuhCorePlugin implements Plugin @@ -11,11 +12,13 @@ export class WazuhCorePlugin } public start(core: CoreStart): WazuhCorePluginStart { + setChrome(core.chrome); setCore(core); setUiSettings(core.uiSettings); return { utils, + hooks, }; } diff --git a/plugins/wazuh-core/public/types.ts b/plugins/wazuh-core/public/types.ts index 28803ab6df..d1865d30ee 100644 --- a/plugins/wazuh-core/public/types.ts +++ b/plugins/wazuh-core/public/types.ts @@ -1,6 +1,7 @@ export interface WazuhCorePluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface WazuhCorePluginStart { + hooks: { useDockedSideNav: () => boolean }; utils: { formatUIDate: (date: Date) => string }; } From 45715268e78ac4c132fee75860990a222e12d593 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Fri, 19 Jan 2024 13:35:03 +0100 Subject: [PATCH 09/64] Fix inventory data table full screen side menu dock (#6344) * Fix datagrid full screen side menu dock * Update changelog --- CHANGELOG.md | 1 + .../vulnerabilities/dashboards/inventory/inventory.tsx | 5 ++++- plugins/main/public/styles/common.scss | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c486730508..d36942286b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) - Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) - Fixed a typo in an abbreviation for Fully Qualified Domain Name [#6333](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6333) +- Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) ### Removed diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index 9be439669b..89110f1cec 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useMemo, useState } from 'react'; -import { getPlugins } from '../../../../../kibana-services'; +import { getPlugins, getWazuhCorePlugin } from '../../../../../kibana-services'; import useSearchBarConfiguration from '../../search_bar/use_search_bar_configuration'; import { IntlProvider } from 'react-intl'; import { @@ -55,6 +55,8 @@ const InventoryVulsComponent = () => { const [isSearching, setIsSearching] = useState(false); const [isExporting, setIsExporting] = useState(false); + const sideNavDocked = getWazuhCorePlugin().hooks.useDockedSideNav(); + const onClickInspectDoc = useMemo( () => (index: number) => { const rowClicked = results.hits.hits[index]; @@ -197,6 +199,7 @@ const InventoryVulsComponent = () => { results?.hits?.total > 0 ? ( diff --git a/plugins/main/public/styles/common.scss b/plugins/main/public/styles/common.scss index 63ea08e7b9..a09fed26df 100644 --- a/plugins/main/public/styles/common.scss +++ b/plugins/main/public/styles/common.scss @@ -1858,3 +1858,11 @@ iframe.width-changed { left: 0; z-index: 9999; } + +/* OSD Data grid full screen with dock navigation left sidebar */ + +.dataGridDockedNav { + &.euiDataGrid--fullScreen { + left: 320px; + } +} From 0c6b6477f8607f82ff5983a9a44a9356c9877e5f Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:19:53 -0300 Subject: [PATCH 10/64] Fix server stat Archives queue usage is picking the wrong value (#6342) * Fix server stat Archives queue usage is picking the wrong value * Update CHANGELOG --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + .../visualizations/cluster/statistics.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d36942286b..0dff68c69d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) - Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) - Fixed a typo in an abbreviation for Fully Qualified Domain Name [#6333](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6333) +- Fixed wrong value at server stat Archives queue usage [#6342](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6342) - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) ### Removed diff --git a/plugins/main/server/integration-files/visualizations/cluster/statistics.ts b/plugins/main/server/integration-files/visualizations/cluster/statistics.ts index c814416829..628102b968 100644 --- a/plugins/main/server/integration-files/visualizations/cluster/statistics.ts +++ b/plugins/main/server/integration-files/visualizations/cluster/statistics.ts @@ -2537,7 +2537,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.event_queue_size', + field: 'analysisd.event_queue_usage', customLabel: 'Event queue usage', }, schema: 'metric', @@ -2547,7 +2547,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.rule_matching_queue_size', + field: 'analysisd.rule_matching_queue_usage', customLabel: 'Rule matching queue usage', }, schema: 'metric', @@ -2557,7 +2557,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.alerts_queue_size', + field: 'analysisd.alerts_queue_usage', customLabel: 'Alerts log queue usage', }, schema: 'metric', @@ -2567,7 +2567,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.firewall_queue_size', + field: 'analysisd.firewall_queue_usage', customLabel: 'Firewall log queue usage', }, schema: 'metric', @@ -2577,7 +2577,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.statistical_queue_size', + field: 'analysisd.statistical_queue_usage', customLabel: 'Statistical log queue usage', }, schema: 'metric', @@ -2587,7 +2587,7 @@ export default [ enabled: true, type: 'avg', params: { - field: 'analysisd.archives_queue_size', + field: 'analysisd.archives_queue_usage', customLabel: 'Archives queue usage', }, schema: 'metric', From c1a20390f2c3dde3c792577605561ff689b924e1 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:44:09 +0100 Subject: [PATCH 11/64] Fix unnecessary scroll in Vulnerability inventory (#6345) * Fix unnecessary scroll * Update changelog * Add comment --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + .../dashboards/inventory/inventory.scss | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dff68c69d..021a4a40d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) - Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) - Fixed a typo in an abbreviation for Fully Qualified Domain Name [#6333](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6333) +- Fixed unnecessary scrolling in Vulnerability Inventory table [#6345](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6345) - Fixed wrong value at server stat Archives queue usage [#6342](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6342) - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss index e3329465a8..b09cec0f4f 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss @@ -1,14 +1,18 @@ .vulsInventoryContainer { - height: calc(100vh - 104px); -} - + height: calc(100vh - 104px); -.headerIsExpanded .vulsInventoryContainer { - height: calc(100vh - 153px); -} + // This makes the table not generate an unnecessary scroll when filtering data from 1 page and then do another search for more pages. + .euiDataGrid__virtualized { + height: calc(100vh - 345px) !important; + } -.vulsInventoryContainer .euiDataGrid--fullScreen { + .euiDataGrid--fullScreen { height: calc(100vh - 49px); bottom: 0; top: auto; + } +} + +.headerIsExpanded .vulsInventoryContainer { + height: calc(100vh - 153px); } From 20b4770defda9050af0f13d663d614b52396be30 Mon Sep 17 00:00:00 2001 From: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:22:21 -0300 Subject: [PATCH 12/64] Fix dashboards for Splunk integration (#6349) Update dashboards for splunk --- docker/integrations/extra/dashboards/Splunk/wazuh-pci-dss | 3 +-- .../integrations/extra/dashboards/Splunk/wazuh-security-events | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docker/integrations/extra/dashboards/Splunk/wazuh-pci-dss b/docker/integrations/extra/dashboards/Splunk/wazuh-pci-dss index 705a40d0f0..681acc9193 100644 --- a/docker/integrations/extra/dashboards/Splunk/wazuh-pci-dss +++ b/docker/integrations/extra/dashboards/Splunk/wazuh-pci-dss @@ -3,7 +3,6 @@ "viz_9NIbkgTo": { "type": "splunk.bubble", "options": { - "backgroundColor": "#ffffff", "xAxisTitleText": "timestamp", "yAxisTitleText": "count" }, @@ -134,4 +133,4 @@ }, "description": "", "title": "wazuh-pci-dss-v1.0" -} +} \ No newline at end of file diff --git a/docker/integrations/extra/dashboards/Splunk/wazuh-security-events b/docker/integrations/extra/dashboards/Splunk/wazuh-security-events index 7ddd19103c..7d5d033ab0 100644 --- a/docker/integrations/extra/dashboards/Splunk/wazuh-security-events +++ b/docker/integrations/extra/dashboards/Splunk/wazuh-security-events @@ -56,7 +56,6 @@ "viz_R8LMR6U6": { "type": "splunk.singlevalueradial", "options": { - "backgroundColor": "#ffffff", "majorColor": "#bf0561" }, "dataSources": { @@ -294,4 +293,4 @@ }, "description": "", "title": "wazuh-security-events-v1.0" -} +} \ No newline at end of file From dc59dd348c77081b8e21e9517a2311dbd72a7b2b Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Wed, 24 Jan 2024 16:36:57 +0100 Subject: [PATCH 13/64] Remove WAZUH_REGISTRATION_SERVER from the windows command (#6361) * remove WAZUH_REGISTRATION_SERVER from the windows command * Add changelog --- CHANGELOG.md | 1 + .../services/register-agent-os-commands-services.tsx | 10 ---------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 021a4a40d5..f7d1d037b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed the application menu in the IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) - Removed the implicit filter of WQL language of the search bar UI [#6174](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6174) - Removed notice of old Discover deprecation [#6341](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6341) +- Removed WAZUH_REGISTRATION_SERVER from Windows agent deployment command [#6361](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6361) ## Wazuh v4.7.2 - OpenSearch Dashboards 2.8.0 - Revision 02 diff --git a/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx index e38a78248f..f7d139e30b 100644 --- a/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx +++ b/plugins/main/public/controllers/register-agent/services/register-agent-os-commands-services.tsx @@ -25,16 +25,6 @@ export const getAllOptionals = ( '', ); - if (osName && osName.toLowerCase() === 'windows' && optionals.serverAddress) { - // when os is windows we must to add wazuh registration server with server address - paramsText = - paramsText + - `WAZUH_REGISTRATION_SERVER=${optionals.serverAddress.replace( - 'WAZUH_MANAGER=', - '', - )} `; - } - return paramsText; }; From fb281e9e3fa660cc8b3d916df838963db25170a3 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Wed, 24 Jan 2024 12:49:55 -0300 Subject: [PATCH 14/64] Refactor top N tables in vulnerabilities dashboard (#6356) * Set column with for count and change titles * Update CHANGELOG * Remove unnecessary import * Remove prop * Modify column width --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- .../overview/dashboard_panels_filters.ts | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7d1d037b4..80d1840569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts index 074ca8947b..7d8e2c64be 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts @@ -6,7 +6,7 @@ const getVisStateFilter = ( indexPatternId: string, title: string, label: string, - fieldName: string, + fieldName: string ) => { return { id, @@ -21,6 +21,16 @@ const getVisStateFilter = ( showTotal: false, totalFunc: 'sum', }, + uiState: { + vis: { + columnsWidth: [ + { + colIndex: 1, + width: 75, + }, + ], + }, + }, data: { searchSource: { query: { @@ -69,11 +79,9 @@ const getVisStateFilter = ( }; export const getDashboardFilters = ( - indexPatternId: string, + indexPatternId: string ): { - [panelId: string]: DashboardPanelState< - EmbeddableInput & { [k: string]: unknown } - >; + [panelId: string]: DashboardPanelState; } => { return { topPackageSelector: { @@ -91,8 +99,8 @@ export const getDashboardFilters = ( 'topPackageSelector', indexPatternId, 'Top packages vulnerabilities', - 'Top 5 package names', - 'package.name', + 'Top 5 packages', + 'package.name' ), }, }, @@ -111,8 +119,8 @@ export const getDashboardFilters = ( 'topOSVulnerabilities', indexPatternId, 'Top operating system vulnerabilities', - 'Top 5 operating systems', - 'host.os.full', + 'Top 5 OS', + 'host.os.full' ), }, }, @@ -132,7 +140,7 @@ export const getDashboardFilters = ( indexPatternId, 'Agent filter', 'Top 5 agents', - 'agent.id', + 'agent.id' ), }, }, @@ -152,7 +160,7 @@ export const getDashboardFilters = ( indexPatternId, 'Top vulnerabilities', 'Top 5 vulnerabilities', - 'vulnerability.id', + 'vulnerability.id' ), }, }, From c15c13eddcf7c11a85fc5c9763b1db34d073a7fa Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Wed, 24 Jan 2024 17:05:17 +0100 Subject: [PATCH 15/64] Add tooltip to most active agent label (#6364) * Change label "Last enrolled agent" * Add tooltip most active agent * Update changelog --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + .../controllers/agent/components/agents-preview.js | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d1840569..84a9580c22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) +- Added information icon with tooltip on the most active agent in the endpoint summary view [#6364](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6364) ### Changed diff --git a/plugins/main/public/controllers/agent/components/agents-preview.js b/plugins/main/public/controllers/agent/components/agents-preview.js index b8ee210bb9..a077afea2e 100644 --- a/plugins/main/public/controllers/agent/components/agents-preview.js +++ b/plugins/main/public/controllers/agent/components/agents-preview.js @@ -25,6 +25,7 @@ import { EuiLink, EuiProgress, EuiText, + EuiIconTip, } from '@elastic/eui'; import { AgentsTable } from './agents-table'; import { WzRequest } from '../../../react-services/wz-request'; @@ -344,7 +345,7 @@ export const AgentsPreview = compose( ) } titleSize='s' - description='Last registered agent' + description='Last enrolled agent' titleColor='primary' /> @@ -384,7 +385,16 @@ export const AgentsPreview = compose( ) } titleSize='s' - description='Most active agent' + description={ + <> + Most active agent{' '} + + + } titleColor='primary' /> From e8d2d00b6207926794828dae6f0232b0721d5bc1 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Wed, 24 Jan 2024 18:10:22 +0100 Subject: [PATCH 16/64] Remove compilation date from dashboard (#6366) * Remove compilation_date from the app * Add changelog --- CHANGELOG.md | 1 + .../management/status/status-node-info.js | 20 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84a9580c22..958a52d299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed the application menu in the IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) - Removed the implicit filter of WQL language of the search bar UI [#6174](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6174) - Removed notice of old Discover deprecation [#6341](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6341) +- Removed compilation date field from the app [#6366](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6366) - Removed WAZUH_REGISTRATION_SERVER from Windows agent deployment command [#6361](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6361) ## Wazuh v4.7.2 - OpenSearch Dashboards 2.8.0 - Revision 02 diff --git a/plugins/main/public/controllers/management/components/management/status/status-node-info.js b/plugins/main/public/controllers/management/components/management/status/status-node-info.js index aa6dc15196..99b7adfef8 100644 --- a/plugins/main/public/controllers/management/components/management/status/status-node-info.js +++ b/plugins/main/public/controllers/management/components/management/status/status-node-info.js @@ -32,13 +32,19 @@ export class WzStatusNodeInfo extends Component { render() { const { stats, nodeInfo, selectedNode, clusterEnabled } = this.props.state; - const agentsNodeCount = clusterEnabled ? (stats.agentsCountByManagerNodes.find(node => node.node_name === selectedNode) || {}).count || 0 : stats.agentsCount.total; + const agentsNodeCount = clusterEnabled + ? ( + stats.agentsCountByManagerNodes.find( + node => node.node_name === selectedNode, + ) || {} + ).count || 0 + : stats.agentsCount.total; const title = selectedNode ? selectedNode + ' information' : 'Manager information'; const greyStyle = { - color: 'grey' + color: 'grey', }; return ( @@ -47,7 +53,7 @@ export class WzStatusNodeInfo extends Component { - +

{title}

@@ -58,12 +64,6 @@ export class WzStatusNodeInfo extends Component { Version {nodeInfo.version}
- - Compilation date - - {formatUIDate(nodeInfo.compilation_date)} - - Installation path {nodeInfo.path} @@ -83,7 +83,7 @@ export class WzStatusNodeInfo extends Component { const mapStateToProps = state => { return { - state: state.statusReducers + state: state.statusReducers, }; }; From e02df5bc1621bcfe3f808dac5513714929c352b3 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Wed, 24 Jan 2024 18:11:13 +0100 Subject: [PATCH 17/64] Add - when run as is disable (#6354) * Add - when run as is disable * Update changelog --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 3 ++- plugins/main/public/components/settings/api/api-table.js | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 958a52d299..60493846da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,9 @@ All notable changes to the Wazuh app project will be documented in this file. - Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) -- Added a redirection button to Endpoint Summary from IT Hygiene application [6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) +- Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) - Added information icon with tooltip on the most active agent in the endpoint summary view [#6364](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6364) +- Added a dash with a tooltip in the server APIs table when the run as is disabled [#6354](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6354) ### Changed diff --git a/plugins/main/public/components/settings/api/api-table.js b/plugins/main/public/components/settings/api/api-table.js index 8511b4cc93..59eb0f8415 100644 --- a/plugins/main/public/components/settings/api/api-table.js +++ b/plugins/main/public/components/settings/api/api-table.js @@ -460,7 +460,12 @@ export const ApiTable = compose( ) : ( - '' + +

-

+
); }, }, From bcb7853a7a7cbe9c281662274aeeadc6a9986a26 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:25:06 -0300 Subject: [PATCH 18/64] Fix statistics visualizations when cluster mode is disabled (#6352) * Fix statistics visualizations when cluster mode is disabled * Update CHANGELOG * Fix incorrect uppercase --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + .../statistics-dashboard-analysisd.js | 15 +- .../statistics/statistics-overview.js | 37 +- .../main/server/controllers/wazuh-elastic.ts | 6 +- .../cluster/common-statistics.ts | 335 ++++++++++++++++++ .../visualizations/cluster/statistics.ts | 327 +---------------- 6 files changed, 382 insertions(+), 339 deletions(-) create mode 100644 plugins/main/server/integration-files/visualizations/cluster/common-statistics.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 60493846da..2fde11bdc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed script to install agents on macOS when you have password to deploy [#6305](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6305) - Fixed a problem with the address validation on Deploy New Agent [#6327](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6327) - Fixed a typo in an abbreviation for Fully Qualified Domain Name [#6333](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6333) +- Fixed server statistics when cluster mode is disabled [#6352](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6352) - Fixed unnecessary scrolling in Vulnerability Inventory table [#6345](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6345) - Fixed wrong value at server stat Archives queue usage [#6342](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6342) - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) diff --git a/plugins/main/public/controllers/management/components/management/statistics/statistics-dashboard-analysisd.js b/plugins/main/public/controllers/management/components/management/statistics/statistics-dashboard-analysisd.js index 729647e1dc..975ab0b656 100644 --- a/plugins/main/public/controllers/management/components/management/statistics/statistics-dashboard-analysisd.js +++ b/plugins/main/public/controllers/management/components/management/statistics/statistics-dashboard-analysisd.js @@ -17,6 +17,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import { useBuildStatisticsVisualizations } from './hooks'; export function WzStatisticsAnalysisd({ + isClusterMode, clusterNodeSelected, refreshVisualizations, }) { @@ -35,7 +36,11 @@ export function WzStatisticsAnalysisd({
@@ -47,7 +52,7 @@ export function WzStatisticsAnalysisd({ - Events Dropped + Events dropped @@ -55,7 +60,9 @@ export function WzStatisticsAnalysisd({ @@ -93,7 +100,7 @@ export function WzStatisticsAnalysisd({ - Events Decoded summary + Events decoded summary diff --git a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js index fc672455e9..7cd5cb998b 100644 --- a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js +++ b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js @@ -27,11 +27,10 @@ import { EuiProgress, } from '@elastic/eui'; -import { clusterNodes } from '../configuration/utils/wz-fetch'; +import { clusterReq, clusterNodes } from '../configuration/utils/wz-fetch'; import { WzStatisticsRemoted } from './statistics-dashboard-remoted'; import { WzStatisticsAnalysisd } from './statistics-dashboard-analysisd'; import { WzDatePicker } from '../../../../../components/wz-date-picker/wz-date-picker'; -import { AppNavigate } from '../../../../../react-services/app-navigate'; import { compose } from 'redux'; import { withGuard, @@ -85,17 +84,32 @@ export class WzStatisticsOverview extends Component { async componentDidMount() { this._isMounted = true; try { - const data = await clusterNodes(); - const nodes = data.data.data.affected_items.map(item => { - return { value: item.name, text: `${item.name} (${item.type})` }; - }); - nodes.unshift({ value: 'all', text: 'All' }); - this.setState({ - clusterNodes: nodes, - clusterNodeSelected: nodes[0].value, - }); + // try if it is a cluster + const clusterStatus = await clusterReq(); + const isClusterMode = + clusterStatus.data.data.enabled === 'yes' && + clusterStatus.data.data.running === 'yes'; + if (isClusterMode) { + const data = await clusterNodes(); + const nodes = data.data.data.affected_items.map(item => { + return { value: item.name, text: `${item.name} (${item.type})` }; + }); + nodes.unshift({ value: 'all', text: 'All' }); + this.setState({ + isClusterMode, + clusterNodes: nodes, + clusterNodeSelected: nodes[0].value, + }); + } else { + this.setState({ + isClusterMode, + clusterNodes: [], + clusterNodeSelected: 'all', + }); + } } catch (error) { this.setState({ + isClusterMode: undefined, clusterNodes: [], clusterNodeSelected: 'all', }); @@ -253,6 +267,7 @@ export class WzStatisticsOverview extends Component { /> diff --git a/plugins/main/server/controllers/wazuh-elastic.ts b/plugins/main/server/controllers/wazuh-elastic.ts index cdcfb23d41..479994a5d7 100644 --- a/plugins/main/server/controllers/wazuh-elastic.ts +++ b/plugins/main/server/controllers/wazuh-elastic.ts @@ -461,7 +461,11 @@ export class WazuhElasticCtrl { const filter = bulk_content.visualization.kibanaSavedObjectMeta.searchSourceJSON.replace( '"filter":[]', - '"filter":[{"match_phrase":{"apiName":"' + master_node + '"}}]', + `"filter":[{"bool":{"must":[{"match":{"apiName":"'${master_node}'"}}${ + name && name !== 'all' + ? `,{"match":{"nodeName":"'${name}'"}}` + : '' + }]}}]`, ); bulk_content.visualization.kibanaSavedObjectMeta.searchSourceJSON = diff --git a/plugins/main/server/integration-files/visualizations/cluster/common-statistics.ts b/plugins/main/server/integration-files/visualizations/cluster/common-statistics.ts new file mode 100644 index 0000000000..e977234541 --- /dev/null +++ b/plugins/main/server/integration-files/visualizations/cluster/common-statistics.ts @@ -0,0 +1,335 @@ +export const commonStatisticsByNode = (isClusterMode: boolean) => { + const idNodeText = isClusterMode ? '-By-Node' : ''; + const titleNodeText = isClusterMode ? ' by Node' : ''; + const labelNodeText = isClusterMode ? ' by Node:' : ''; + + return [ + { + _id: 'Wazuh-App-Statistics-Analysisd-Events' + idNodeText, + _type: 'visualization', + _source: { + title: 'Wazuh App Statistics Events' + titleNodeText, + visState: JSON.stringify({ + title: 'Wazuh App Statistics Events' + titleNodeText, + type: 'line', + aggs: [ + { + id: '1', + enabled: true, + type: 'sum', + params: { + field: 'analysisd.events_processed', + customLabel: 'Count', + }, + schema: 'metric', + }, + { + id: '2', + enabled: true, + type: 'date_histogram', + params: { + field: 'timestamp', + timeRange: { + from: 'now-30m', + to: 'now', + }, + useNormalizedOpenSearchInterval: true, + scaleMetricValues: false, + interval: 'auto', + drop_partials: false, + min_doc_count: 1, + extended_bounds: {}, + customLabel: 'timestamp', + }, + schema: 'segment', + }, + { + id: '4', + enabled: true, + type: 'filters', + params: { + filters: [ + { + input: { + query: 'analysisd.events_processed:*', + language: 'kuery', + }, + label: 'Events processed' + labelNodeText, + }, + ], + }, + schema: 'group', + }, + isClusterMode + ? { + id: '3', + enabled: true, + type: 'terms', + params: { + field: 'nodeName.keyword', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + customLabel: '', + }, + schema: 'group', + } + : {}, + ], + params: { + type: 'line', + grid: { + categoryLines: true, + }, + categoryAxes: [ + { + id: 'CategoryAxis-1', + type: 'category', + position: 'bottom', + show: true, + style: {}, + scale: { + type: 'linear', + }, + labels: { + show: true, + filter: true, + truncate: 100, + }, + title: {}, + }, + ], + valueAxes: [ + { + id: 'ValueAxis-1', + name: 'LeftAxis-1', + type: 'value', + position: 'left', + show: true, + style: {}, + scale: { + type: 'linear', + mode: 'normal', + }, + labels: { + show: true, + rotate: 0, + filter: false, + truncate: 100, + }, + title: { + text: 'Count', + }, + }, + ], + seriesParams: [ + { + show: true, + type: 'line', + mode: 'normal', + data: { + label: 'Count', + id: '1', + }, + valueAxis: 'ValueAxis-1', + drawLinesBetweenPoints: true, + lineWidth: 2, + interpolate: 'linear', + showCircles: true, + }, + ], + addTooltip: true, + addLegend: true, + legendPosition: 'right', + times: [], + addTimeMarker: false, + labels: {}, + thresholdLine: { + show: false, + value: 10, + width: 1, + style: 'full', + color: '#E7664C', + }, + }, + }), + description: '', + version: 1, + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + index: 'wazuh-statistics-*', + filter: [], + query: { query: '', language: 'lucene' }, + }), + }, + }, + }, + { + _id: 'Wazuh-App-Statistics-Analysisd-Events-Dropped' + idNodeText, + _type: 'visualization', + _source: { + title: 'Wazuh App Statistics Events Dropped' + titleNodeText, + visState: JSON.stringify({ + title: 'Wazuh App Statistics Events Dropped' + titleNodeText, + type: 'line', + aggs: [ + { + id: '1', + enabled: true, + type: 'sum', + params: { + field: 'analysisd.events_dropped', + customLabel: 'Count', + }, + schema: 'metric', + }, + { + id: '2', + enabled: true, + type: 'date_histogram', + params: { + field: 'timestamp', + timeRange: { + from: 'now-30m', + to: 'now', + }, + useNormalizedOpenSearchInterval: true, + scaleMetricValues: false, + interval: 'auto', + drop_partials: false, + min_doc_count: 1, + extended_bounds: {}, + customLabel: 'timestamp', + }, + schema: 'segment', + }, + { + id: '3', + enabled: true, + type: 'filters', + params: { + filters: [ + { + input: { + query: 'analysisd.events_dropped:*', + language: 'kuery', + }, + label: 'Events dropped' + labelNodeText, + }, + ], + }, + schema: 'group', + }, + isClusterMode + ? { + id: '4', + enabled: true, + type: 'terms', + params: { + field: 'nodeName.keyword', + orderBy: '1', + order: 'desc', + size: 5, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + schema: 'group', + } + : {}, + ], + params: { + type: 'line', + grid: { + categoryLines: true, + }, + categoryAxes: [ + { + id: 'CategoryAxis-1', + type: 'category', + position: 'bottom', + show: true, + style: {}, + scale: { + type: 'linear', + }, + labels: { + show: true, + filter: true, + truncate: 100, + }, + title: {}, + }, + ], + valueAxes: [ + { + id: 'ValueAxis-1', + name: 'LeftAxis-1', + type: 'value', + position: 'left', + show: true, + style: {}, + scale: { + type: 'linear', + mode: 'normal', + }, + labels: { + show: true, + rotate: 0, + filter: false, + truncate: 100, + }, + title: { + text: 'Count', + }, + }, + ], + seriesParams: [ + { + show: true, + type: 'line', + mode: 'normal', + data: { + label: 'Count', + id: '1', + }, + valueAxis: 'ValueAxis-1', + drawLinesBetweenPoints: true, + lineWidth: 2, + interpolate: 'linear', + showCircles: true, + }, + ], + addTooltip: true, + addLegend: true, + legendPosition: 'right', + times: [], + addTimeMarker: false, + labels: {}, + thresholdLine: { + show: false, + value: 10, + width: 1, + style: 'full', + color: '#E7664C', + }, + }, + }), + description: '', + version: 1, + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + index: 'wazuh-statistics-*', + filter: [], + query: { query: '', language: 'lucene' }, + }), + }, + }, + }, + ]; +}; diff --git a/plugins/main/server/integration-files/visualizations/cluster/statistics.ts b/plugins/main/server/integration-files/visualizations/cluster/statistics.ts index 628102b968..a163611431 100644 --- a/plugins/main/server/integration-files/visualizations/cluster/statistics.ts +++ b/plugins/main/server/integration-files/visualizations/cluster/statistics.ts @@ -1,3 +1,5 @@ +import { commonStatisticsByNode } from './common-statistics'; + /* * Wazuh app - Cluster monitoring visualizations * Copyright (C) 2015-2022 Wazuh, Inc. @@ -2171,329 +2173,6 @@ export default [ }, }, }, - { - _id: 'Wazuh-App-Statistics-Analysisd-Events-By-Node', - _type: 'visualization', - _source: { - title: 'Wazuh App Statistics Events by Node', - visState: JSON.stringify({ - title: 'Wazuh App Statistics Events by Node', - type: 'line', - aggs: [ - { - id: '1', - enabled: true, - type: 'sum', - params: { - field: 'analysisd.events_processed', - customLabel: 'Count', - }, - schema: 'metric', - }, - { - id: '2', - enabled: true, - type: 'date_histogram', - params: { - field: 'timestamp', - timeRange: { - from: 'now-30m', - to: 'now', - }, - useNormalizedOpenSearchInterval: true, - scaleMetricValues: false, - interval: 'auto', - drop_partials: false, - min_doc_count: 1, - extended_bounds: {}, - customLabel: 'timestamp', - }, - schema: 'segment', - }, - { - id: '4', - enabled: true, - type: 'filters', - params: { - filters: [ - { - input: { - query: 'analysisd.events_processed:*', - language: 'kuery', - }, - label: 'Events processed by Node:', - }, - ], - }, - schema: 'group', - }, - { - id: '3', - enabled: true, - type: 'terms', - params: { - field: 'nodeName.keyword', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - customLabel: '', - }, - schema: 'group', - }, - ], - params: { - type: 'line', - grid: { - categoryLines: true, - }, - categoryAxes: [ - { - id: 'CategoryAxis-1', - type: 'category', - position: 'bottom', - show: true, - style: {}, - scale: { - type: 'linear', - }, - labels: { - show: true, - filter: true, - truncate: 100, - }, - title: {}, - }, - ], - valueAxes: [ - { - id: 'ValueAxis-1', - name: 'LeftAxis-1', - type: 'value', - position: 'left', - show: true, - style: {}, - scale: { - type: 'linear', - mode: 'normal', - }, - labels: { - show: true, - rotate: 0, - filter: false, - truncate: 100, - }, - title: { - text: 'Count', - }, - }, - ], - seriesParams: [ - { - show: true, - type: 'line', - mode: 'normal', - data: { - label: 'Count', - id: '1', - }, - valueAxis: 'ValueAxis-1', - drawLinesBetweenPoints: true, - lineWidth: 2, - interpolate: 'linear', - showCircles: true, - }, - ], - addTooltip: true, - addLegend: true, - legendPosition: 'right', - times: [], - addTimeMarker: false, - labels: {}, - thresholdLine: { - show: false, - value: 10, - width: 1, - style: 'full', - color: '#E7664C', - }, - }, - }), - description: '', - version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'wazuh-statistics-*', - filter: [], - query: { query: '', language: 'lucene' }, - }), - }, - }, - }, - { - _id: 'Wazuh-App-Statistics-Analysisd-Events-Dropped-By-Node', - _type: 'visualization', - _source: { - title: 'Wazuh App Statistics Events Dropped by Node', - visState: JSON.stringify({ - title: 'Wazuh App Statistics Events Dropped by Node', - type: 'line', - aggs: [ - { - id: '1', - enabled: true, - type: 'sum', - params: { - field: 'analysisd.events_dropped', - customLabel: 'Count', - }, - schema: 'metric', - }, - { - id: '2', - enabled: true, - type: 'date_histogram', - params: { - field: 'timestamp', - timeRange: { - from: 'now-30m', - to: 'now', - }, - useNormalizedOpenSearchInterval: true, - scaleMetricValues: false, - interval: 'auto', - drop_partials: false, - min_doc_count: 1, - extended_bounds: {}, - customLabel: 'timestamp', - }, - schema: 'segment', - }, - { - id: '3', - enabled: true, - type: 'filters', - params: { - filters: [ - { - input: { - query: 'analysisd.events_dropped:*', - language: 'kuery', - }, - label: 'Events dropped by Node:', - }, - ], - }, - schema: 'group', - }, - { - id: '4', - enabled: true, - type: 'terms', - params: { - field: 'nodeName.keyword', - orderBy: '1', - order: 'desc', - size: 5, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - schema: 'group', - }, - ], - params: { - type: 'line', - grid: { - categoryLines: true, - }, - categoryAxes: [ - { - id: 'CategoryAxis-1', - type: 'category', - position: 'bottom', - show: true, - style: {}, - scale: { - type: 'linear', - }, - labels: { - show: true, - filter: true, - truncate: 100, - }, - title: {}, - }, - ], - valueAxes: [ - { - id: 'ValueAxis-1', - name: 'LeftAxis-1', - type: 'value', - position: 'left', - show: true, - style: {}, - scale: { - type: 'linear', - mode: 'normal', - }, - labels: { - show: true, - rotate: 0, - filter: false, - truncate: 100, - }, - title: { - text: 'Count', - }, - }, - ], - seriesParams: [ - { - show: true, - type: 'line', - mode: 'normal', - data: { - label: 'Count', - id: '1', - }, - valueAxis: 'ValueAxis-1', - drawLinesBetweenPoints: true, - lineWidth: 2, - interpolate: 'linear', - showCircles: true, - }, - ], - addTooltip: true, - addLegend: true, - legendPosition: 'right', - times: [], - addTimeMarker: false, - labels: {}, - thresholdLine: { - show: false, - value: 10, - width: 1, - style: 'full', - color: '#E7664C', - }, - }, - }), - description: '', - version: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'wazuh-statistics-*', - filter: [], - query: { query: '', language: 'lucene' }, - }), - }, - }, - }, { _id: 'Wazuh-App-Statistics-Analysisd-Queues-Usage', _type: 'visualization', @@ -2777,4 +2456,6 @@ export default [ }, }, }, + ...commonStatisticsByNode(true), + ...commonStatisticsByNode(false), ]; From 1eeb80b095e10a059726f1d4256688ed8c719726 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:59:15 +0100 Subject: [PATCH 19/64] Add wazuh_manager.conf version 4.8.0 or higher (#6362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add wazuh_manager.conf version 4.8.0 or higher * Remove wazuh_manager.conf custom * Revert change --------- Co-authored-by: Federico Rodriguez Co-authored-by: Chantal Belén kelm <99441266+chantal-kelm@users.noreply.github.com> --- .../config/wazuh_cluster/wazuh_manager.conf | 353 ------------------ docker/osd-dev/dev.yml | 1 - 2 files changed, 354 deletions(-) delete mode 100755 docker/osd-dev/config/wazuh_cluster/wazuh_manager.conf diff --git a/docker/osd-dev/config/wazuh_cluster/wazuh_manager.conf b/docker/osd-dev/config/wazuh_cluster/wazuh_manager.conf deleted file mode 100755 index aff1af9d6c..0000000000 --- a/docker/osd-dev/config/wazuh_cluster/wazuh_manager.conf +++ /dev/null @@ -1,353 +0,0 @@ - - - yes - yes - no - no - no - smtp.example.wazuh.com - wazuh@example.wazuh.com - recipient@example.wazuh.com - 12 - alerts.log - 10m - 0 - - - - 3 - 12 - - - - - plain - - - - secure - 1514 - tcp - 131072 - - - - - no - yes - yes - yes - yes - yes - yes - yes - - - 43200 - - etc/rootcheck/rootkit_files.txt - etc/rootcheck/rootkit_trojans.txt - - yes - - - - yes - 1800 - 1d - yes - - wodles/java - wodles/ciscat - - - - - yes - yes - /var/log/osquery/osqueryd.results.log - /etc/osquery/osquery.conf - yes - - - - - no - 1h - yes - yes - yes - yes - yes - yes - yes - - - - 10 - - - - - yes - yes - 12h - yes - - - - no - 5m - 6h - yes - - - - no - trusty - xenial - bionic - focal - 1h - - - - - no - stretch - buster - bullseye - 1h - - - - - no - 5 - 6 - 7 - 8 - 1h - - - - - no - amazon-linux - amazon-linux-2 - 1h - - - - - no - 1h - - - - - yes - 1h - - - - - yes - 2010 - 1h - - - - - - - no - - - 43200 - - yes - - - yes - - - no - - - /etc,/usr/bin,/usr/sbin - /bin,/sbin,/boot - - - /etc/mtab - /etc/hosts.deny - /etc/mail/statistics - /etc/random-seed - /etc/random.seed - /etc/adjtime - /etc/httpd/logs - /etc/utmpx - /etc/wtmpx - /etc/cups/certs - /etc/dumpdates - /etc/svc/volatile - - - .log$|.swp$ - - - /etc/ssl/private.key - - yes - yes - yes - yes - - - 10 - - - 100 - - - - yes - 5m - 1h - 10 - - - - - - 127.0.0.1 - ^localhost.localdomain$ - 10.0.0.106 - - - - disable-account - disable-account - yes - - - - restart-wazuh - restart-wazuh - - - - firewall-drop - firewall-drop - yes - - - - host-deny - host-deny - yes - - - - route-null - route-null - yes - - - - win_route-null - route-null.exe - yes - - - - netsh - netsh.exe - yes - - - - - - - command - df -P - 360 - - - - full_command - netstat -tulpn | sed 's/\([[:alnum:]]\+\)\ \+[[:digit:]]\+\ \+[[:digit:]]\+\ \+\(.*\):\([[:digit:]]*\)\ \+\([0-9\.\:\*]\+\).\+\ \([[:digit:]]*\/[[:alnum:]\-]*\).*/\1 \2 == \3 == \4 \5/' | sort -k 4 -g | sed 's/ == \(.*\) ==/:\1/' | sed 1,2d - netstat listening ports - 360 - - - - full_command - last -n 20 - 360 - - - - - ruleset/decoders - ruleset/rules - 0215-policy_rules.xml - etc/lists/audit-keys - etc/lists/amazon/aws-eventnames - etc/lists/security-eventchannel - - - etc/decoders - etc/rules - - - - yes - 1 - 64 - 15m - - - - - no - 1515 - no - yes - no - HIGH:!ADH:!EXP:!MD5:!RC4:!3DES:!CAMELLIA:@STRENGTH - - no - etc/sslmanager.cert - etc/sslmanager.key - no - - - - wazuh - node01 - master - - 1516 - 0.0.0.0 - - NODE_IP - - no - yes - - - - - - - syslog - /var/ossec/logs/active-responses.log - - - diff --git a/docker/osd-dev/dev.yml b/docker/osd-dev/dev.yml index 11f37f04af..9b8982cd5b 100755 --- a/docker/osd-dev/dev.yml +++ b/docker/osd-dev/dev.yml @@ -357,7 +357,6 @@ services: - API_PASSWORD=MyS3cr37P450r.*- volumes: - wm_certs:/etc/ssl/wazuh - - ./config/wazuh_cluster/wazuh_manager.conf:/wazuh-config-mount/etc/ossec.conf ports: - '514:514' - '1514:1514' From 9fd33dbd617bda225bfed5b579e000a0dfc60de5 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Thu, 25 Jan 2024 11:21:02 +0100 Subject: [PATCH 20/64] Add agent columns to vulnerabilities inventory table (#6355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add agent columns to Vulnerabilities Inventory * Removed vulnerability.score.base column * Removed vulnerability.score.version column * Fix the useDockedSideNav to consider the width of the window * Update check-health snapshot --------- Co-authored-by: Chantal Belén kelm <99441266+chantal-kelm@users.noreply.github.com> --- .../__snapshots__/check-result.test.tsx.snap | 10 +++-- .../health-check/components/check-result.scss | 4 ++ .../health-check/components/check-result.tsx | 7 ++- .../dashboards/inventory/config/index.ts | 43 ++++++++++--------- .../public/hooks/use-docked-side-nav.tsx | 39 +++++++++++++++-- 5 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 plugins/main/public/components/health-check/components/check-result.scss diff --git a/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap b/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap index 8b1d3e8143..436f919ef7 100644 --- a/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap +++ b/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap @@ -16,9 +16,11 @@ exports[`Check result component should render a Check result screen 1`] = ` title="Check Test" validationService={[MockFunction]} > - +
Check Test
@@ -27,7 +29,9 @@ exports[`Check result component should render a Check result screen 1`] = `
-

+

- {props.title} + + {props.title} + -

+

{showLogButton ? ( { - const [sideNavDocked, setSideNavDocked] = useState(false); + const [sideNavDocked, _setSideNavDocked] = useState(false); + const [isDockedSideNavVisible, setIsDockedSideNavVisible] = + useState(false); + + /* + We have to create a reference to the state of the react component, + because the event handler cannot read the latest state otherwise + */ + const setSideNavDocked = (value: boolean) => { + currentSideNavDocked.current = value; + _setSideNavDocked(value); + }; + + // Create references so the event handler can read the latest values + let timeoutID = useRef(0); + const currentSideNavDocked = useRef(sideNavDocked); + + // If the inner width of the window is less than 992px, the side nav is always hidden. + // The use of useCallback is to keep the function reference the same so we can remove it in the event listener + const onWindowResize = useCallback(() => { + // Clear the timeout so we don't call the function multiple times while the window is being resized + clearTimeout(timeoutID.current); + timeoutID.current = setTimeout(() => { + setIsDockedSideNavVisible( + currentSideNavDocked.current && window.innerWidth > 991, + ); + }, 100); + }, []); + + useEffect(() => { + onWindowResize(); + }, [sideNavDocked]); useEffect(() => { const isNavDrawerSubscription = getChrome() @@ -11,10 +42,12 @@ export const useDockedSideNav = () => { setSideNavDocked(value); }); + window.addEventListener('resize', onWindowResize, true); return () => { isNavDrawerSubscription.unsubscribe(); + window.removeEventListener('resize', onWindowResize, true); }; }, []); - return sideNavDocked; + return isDockedSideNavVisible; }; From 6bd7ab78aba99a239bea9ff4c1196ebf0bcc84ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chantal=20Bel=C3=A9n=20kelm?= <99441266+chantal-kelm@users.noreply.github.com> Date: Fri, 26 Jan 2024 06:42:33 -0300 Subject: [PATCH 21/64] Change api configuration title (#6373) * change api configuration title * Update changelog --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + plugins/main/public/components/settings/api/api-table.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fde11bdc6..2b60be94f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Changed dashboards. [#6035](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6035) - Change the display order of tabs in all modules. [#6067](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6067) - Upgraded the `axios` dependency to `1.6.1` [#5062](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5062) +- Changed the api configuration title in the Server APIs section. [#6373](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6373) ### Fixed diff --git a/plugins/main/public/components/settings/api/api-table.js b/plugins/main/public/components/settings/api/api-table.js index 59eb0f8415..defc942ca4 100644 --- a/plugins/main/public/components/settings/api/api-table.js +++ b/plugins/main/public/components/settings/api/api-table.js @@ -522,7 +522,7 @@ export const ApiTable = compose( -

API Configuration

+

API Connections

From 9a6611b1c7e4606865b5e0242b84932dd29c99d3 Mon Sep 17 00:00:00 2001 From: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:41:59 -0300 Subject: [PATCH 22/64] Fix duplicated help menu (#6374) * Remove added help menu * Remove reference to the deleted file * Modify changelog --- CHANGELOG.md | 1 + plugins/main/public/app.js | 5 +- .../public/utils/add_help_menu_to_app.tsx | 52 ------------------- plugins/main/public/utils/index.ts | 2 - 4 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 plugins/main/public/utils/add_help_menu_to_app.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b60be94f9..c8ed96f6d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed unnecessary scrolling in Vulnerability Inventory table [#6345](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6345) - Fixed wrong value at server stat Archives queue usage [#6342](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6342) - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) +- Fixed the help menu, to be consistent and avoid duplication [#6374](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6374) ### Removed diff --git a/plugins/main/public/app.js b/plugins/main/public/app.js index 6fdb2de6be..f8e23658ea 100644 --- a/plugins/main/public/app.js +++ b/plugins/main/public/app.js @@ -48,7 +48,6 @@ import { updateCurrentPlatform } from './redux/actions/appStateActions'; import { WzAuthentication, loadAppConfig } from './react-services'; import { getAngularModule, getHttp } from './kibana-services'; -import { addHelpMenuToAppChrome } from './utils'; const app = getAngularModule(); @@ -78,7 +77,7 @@ app.run([ .then(item => { store.dispatch(updateCurrentPlatform(item)); }) - .catch(() => {}); + .catch(() => { }); // Init the process of refreshing the user's token when app start. checkPluginVersion().finally(WzAuthentication.refresh); @@ -102,8 +101,6 @@ app.run(function ($rootElement) {
`); - // Add plugin help links as extension to plugin platform help menu - addHelpMenuToAppChrome(); // Bind deleteExistentToken on Log out component. $('.euiHeaderSectionItem__button, .euiHeaderSectionItemButton').on( diff --git a/plugins/main/public/utils/add_help_menu_to_app.tsx b/plugins/main/public/utils/add_help_menu_to_app.tsx deleted file mode 100644 index d3afecd102..0000000000 --- a/plugins/main/public/utils/add_help_menu_to_app.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Wazuh app - Add the plugin help links as extension in plugin platform help menu - * Copyright (C) 2015-2022 Wazuh, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Find more information about this on the LICENSE file. - */ - -import React from 'react'; -import { - EuiIcon, -} from '@elastic/eui'; -import { getChrome, getHttp} from '../kibana-services'; -import { - WAZUH_LINK_GITHUB, - WAZUH_LINK_GOOGLE_GROUPS, - WAZUH_LINK_SLACK -} from '../../common/constants'; -import { getThemeAssetURL, getAssetURL } from './assets'; -import { webDocumentationLink } from '../../common/services/web_documentation'; - -export function addHelpMenuToAppChrome(){ - getChrome().setHelpExtension({ - appName: 'Wazuh support', - links: [ - { - linkType: 'custom', - href: webDocumentationLink(''), - content: Documentation - }, - { - linkType: 'custom', - href: WAZUH_LINK_SLACK, - content: Slack channel - }, - { - linkType: 'custom', - href: WAZUH_LINK_GITHUB, - content: Projects on Github - }, - { - linkType: 'custom', - href: WAZUH_LINK_GOOGLE_GROUPS, - content: Google Group - } - ] - }); -} diff --git a/plugins/main/public/utils/index.ts b/plugins/main/public/utils/index.ts index 007a96971b..b037b2ff68 100644 --- a/plugins/main/public/utils/index.ts +++ b/plugins/main/public/utils/index.ts @@ -1,3 +1 @@ export { checkPluginVersion } from './check-plugin-version'; - -export { addHelpMenuToAppChrome } from './add_help_menu_to_app'; \ No newline at end of file From 22cb27694343f869d8f699dea9e4fc50e7c7f473 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:47:12 +0100 Subject: [PATCH 23/64] Remove it hygiene section (#6372) * Remove it hygiene section and change breadcrunb * Agent menu restored * Remove Vulnerability detection from agent menu * Update breadcrumbs --- plugins/main/common/wazuh-modules.ts | 6 +- .../add-modules-data-main.tsx | 2 +- .../components/agents/stats/agent-stats.tsx | 8 +- .../components/agents/syscollector/main.tsx | 8 +- .../globalBreadcrumb/platformBreadcrumb.tsx | 4 +- .../modules/events-enhance-discover-fields.ts | 4 +- .../components/common/modules/main-agent.tsx | 19 +- .../modules/overview-current-section.tsx | 2 +- .../common/welcome/agents-welcome.js | 282 +++++++++++++++--- .../common/welcome/components/menu-agent.js | 218 ++++++++++++++ .../common/welcome/overview-welcome.js | 6 +- .../components/common/welcome/welcome.scss | 38 --- .../main/public/components/security/main.tsx | 2 +- .../public/components/wz-menu/wz-menu.scss | 8 + .../agent/components/agents-preview.js | 8 +- .../agent/components/agents-table.js | 8 +- .../cdblists/views/cdblists-overview.tsx | 2 +- .../configuration/configuration-main.js | 10 +- .../decoders/views/decoders-overview.tsx | 2 +- .../management/groups/group-agents-table.js | 4 +- .../management/groups/groups-main.js | 2 +- .../components/management/mg-logs/logs.js | 2 +- .../management/reporting/reporting-main.js | 2 +- .../ruleset/views/ruleset-overview.tsx | 2 +- .../statistics/statistics-overview.js | 2 +- .../management/status/status-overview.js | 2 +- .../controllers/management/monitoring.js | 6 +- .../controllers/overview/components/stats.js | 4 +- .../public/controllers/settings/settings.js | 4 +- .../main/public/controllers/tools/tools.ts | 7 +- plugins/main/public/utils/applications.ts | 152 ++++++++-- 31 files changed, 667 insertions(+), 159 deletions(-) create mode 100644 plugins/main/public/components/common/welcome/components/menu-agent.js diff --git a/plugins/main/common/wazuh-modules.ts b/plugins/main/common/wazuh-modules.ts index 35b0221bfe..c7b1307849 100644 --- a/plugins/main/common/wazuh-modules.ts +++ b/plugins/main/common/wazuh-modules.ts @@ -114,20 +114,20 @@ export const WAZUH_MODULES = { syscollector: { title: 'Inventory data', // This appId is not used, for consistency was added. - appId: 'it-hygiene', + appId: 'endpoint-summary', description: 'Applications, network configuration, open ports and processes running on your monitored systems.', }, stats: { title: 'Stats', // This appId is not used, for consistency was added. - appId: 'it-hygiene', + appId: 'endpoint-summary', description: 'Stats for agent and logcollector', }, configuration: { title: 'Configuration', // This appId is not used, for consistency was added. - appId: 'it-hygiene', + appId: 'endpoint-summary', description: 'Check the current agent configuration remotely applied by its group.', }, diff --git a/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx b/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx index 9fdba4d3db..ee490a2033 100644 --- a/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx +++ b/plugins/main/public/components/add-modules-data/add-modules-data-main.tsx @@ -177,6 +177,6 @@ class WzAddModulesData extends Component< export default compose( withGlobalBreadcrumb(props => { - return [{ text: sampleData.title }]; + return [{ text: sampleData.breadcrumbLabel }]; }), )(WzAddModulesData); diff --git a/plugins/main/public/components/agents/stats/agent-stats.tsx b/plugins/main/public/components/agents/stats/agent-stats.tsx index 4f4e8b462b..a77b125b56 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.tsx @@ -46,7 +46,8 @@ import { UI_LOGGER_LEVELS, } from '../../../../common/constants'; import { getErrorOrchestrator } from '../../../react-services/common-services'; -import { itHygiene } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; +import { getCore } from '../../../kibana-services'; const tableColumns = [ { @@ -106,7 +107,10 @@ export const MainAgentStats = compose( withReduxProvider, withGlobalBreadcrumb(({ agent }) => [ { - text: itHygiene.title, + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), }, { agent }, { diff --git a/plugins/main/public/components/agents/syscollector/main.tsx b/plugins/main/public/components/agents/syscollector/main.tsx index a3234947cf..cdec38ef3e 100644 --- a/plugins/main/public/components/agents/syscollector/main.tsx +++ b/plugins/main/public/components/agents/syscollector/main.tsx @@ -18,7 +18,8 @@ import { } from '../../common/hocs'; import { SyscollectorInventory } from './inventory'; import { compose } from 'redux'; -import { itHygiene } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; +import { getCore } from '../../../kibana-services'; export const MainSyscollector = compose( withReduxProvider, @@ -26,7 +27,10 @@ export const MainSyscollector = compose( withGlobalBreadcrumb(({ agent }) => { return [ { - text: itHygiene.title, + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), }, { agent }, { diff --git a/plugins/main/public/components/common/globalBreadcrumb/platformBreadcrumb.tsx b/plugins/main/public/components/common/globalBreadcrumb/platformBreadcrumb.tsx index 18fc1578af..1c5a5ee8b4 100644 --- a/plugins/main/public/components/common/globalBreadcrumb/platformBreadcrumb.tsx +++ b/plugins/main/public/components/common/globalBreadcrumb/platformBreadcrumb.tsx @@ -1,5 +1,5 @@ import { getCore } from '../../../kibana-services'; -import { itHygiene } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; export const setBreadcrumbs = (breadcrumbs, router) => { if (breadcrumbs === '' || breadcrumbs === undefined) { @@ -12,7 +12,7 @@ export const setBreadcrumbs = (breadcrumbs, router) => { 'euiLink euiLink--subdued osdBreadcrumbs wz-vertical-align-middle', onClick: ev => { ev.stopPropagation(); - getCore().application.navigateToApp(itHygiene.id, { + getCore().application.navigateToApp(endpointSummary.id, { path: `#/agents?tab=welcome&agent=${breadcrumb.agent.id}`, }); router.reload(); diff --git a/plugins/main/public/components/common/modules/events-enhance-discover-fields.ts b/plugins/main/public/components/common/modules/events-enhance-discover-fields.ts index 9c0a70771d..e5e5f5fc97 100644 --- a/plugins/main/public/components/common/modules/events-enhance-discover-fields.ts +++ b/plugins/main/public/components/common/modules/events-enhance-discover-fields.ts @@ -121,7 +121,7 @@ export const EventsEnhanceDiscoverCell = { ...buttonStyles, href: content => content !== '000' - ? getCore().application.getUrlForApp('it-hygiene', { + ? getCore().application.getUrlForApp('endpoints-summary', { path: `#/agents?tab=welcome&agent=${content}`, }) : undefined, @@ -131,7 +131,7 @@ export const EventsEnhanceDiscoverCell = { href: (content, rowData) => { const agentId = (((rowData || {})._source || {}).agent || {}).id; return agentId !== '000' - ? getCore().application.getUrlForApp('it-hygiene', { + ? getCore().application.getUrlForApp('endpoints-summary', { path: `#/agents?tab=welcome&agent=${agentId}`, }) : undefined; diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index d4b88b6d4a..6baa5d2ab9 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -25,10 +25,10 @@ import { AppState } from '../../../react-services/app-state'; import { ReportingService } from '../../../react-services/reporting'; import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; import { AgentInfo } from '../../common/welcome/agents-info'; -import { getAngularModule } from '../../../kibana-services'; +import { getAngularModule, getCore } from '../../../kibana-services'; import { compose } from 'redux'; import { withGlobalBreadcrumb } from '../hocs'; -import { itHygiene } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; export class MainModuleAgent extends Component { props!: { @@ -226,11 +226,22 @@ export class MainModuleAgent extends Component { export default compose( withGlobalBreadcrumb(({ agent, section }) => { if (section === 'welcome') { - return [{ text: itHygiene.title }, { text: agent.id }]; + return [ + { + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), + }, + { text: agent.id }, + ]; } else { return [ { - text: itHygiene.title, + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), }, { agent: agent }, { diff --git a/plugins/main/public/components/common/modules/overview-current-section.tsx b/plugins/main/public/components/common/modules/overview-current-section.tsx index f83b4b2425..28f3eb91d6 100644 --- a/plugins/main/public/components/common/modules/overview-current-section.tsx +++ b/plugins/main/public/components/common/modules/overview-current-section.tsx @@ -29,7 +29,7 @@ class WzCurrentOverviewSection extends Component { const section = Applications.find( ({ id }) => getWzCurrentAppID() === id, - )?.title; + )?.breadcrumbLabel; if (section) { const breadcrumb = currentAgent.id diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 53b0ec9bbf..cb4b63fb54 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -21,10 +21,12 @@ import { EuiFlexGrid, EuiButtonEmpty, EuiPage, + EuiPopover, EuiLoadingChart, EuiToolTip, EuiButtonIcon, EuiPageBody, + EuiLink, } from '@elastic/eui'; import { FimEventsTable, @@ -34,6 +36,7 @@ import { } from './components'; import { AgentInfo } from './agents-info'; import WzReduxProvider from '../../../redux/wz-redux-provider'; +import MenuAgent from './components/menu-agent'; import './welcome.scss'; import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker'; import KibanaVis from '../../../kibana-integrations/kibana-vis'; @@ -51,6 +54,7 @@ import { getCore, getDataPlugin, } from '../../../kibana-services'; +import { hasAgentSupportModule } from '../../../react-services/wz-agents'; import { withErrorBoundary, withGlobalBreadcrumb, @@ -59,6 +63,7 @@ import { } from '../hocs'; import { compose } from 'redux'; import { API_NAME_AGENT_STATUS } from '../../../../common/constants'; +import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; import { PromptAgentNeverConnected, PromptNoSelectedAgent, @@ -67,8 +72,12 @@ import { connect } from 'react-redux'; import { WzButton } from '../buttons'; import { Applications, - itHygiene, + configurationAssessment, + fileIntegrityMonitoring, + endpointSummary, mitreAttack, + threatHunting, + malwareDetection, } from '../../../utils/applications'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; @@ -89,7 +98,10 @@ export const AgentsWelcome = compose( withGlobalBreadcrumb(({ agent }) => { return [ { - text: itHygiene.title, + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), }, ...(agent?.name ? [ @@ -103,7 +115,25 @@ export const AgentsWelcome = compose( }), withGuard( props => !(props.agent && props.agent.id), - () => , + () => ( + <> + + You need to select an agent or return to + + + Endpoint summary + + + + } + /> + + ), ), withGuard( props => props.agent.status === API_NAME_AGENT_STATUS.NEVER_CONNECTED, @@ -112,9 +142,14 @@ export const AgentsWelcome = compose( )( class AgentsWelcome extends Component { _isMount = false; + sidebarSizeDefault; constructor(props) { super(props); + this.offset = 275; + + this.sidebarSizeDefault = 320; + this.state = { lastScans: [], isLoading: true, @@ -122,12 +157,43 @@ export const AgentsWelcome = compose( sortDirection: 'desc', actionAgents: true, // Hide actions agents selectedRequirement: 'pci', + menuAgent: [], + maxModules: 5, widthWindow: window.innerWidth, + isLocked: false, }; } updateWidth = () => { - this.setState({ widthWindow: window.innerWidth }); + let menuSize; + if (this.state.isLocked) { + menuSize = window.innerWidth - this.offset - this.sidebarSizeDefault; + } else { + menuSize = window.innerWidth - this.offset; + } + let maxModules = 5; + if (menuSize > 1400) { + maxModules = 5; + } else { + if (menuSize > 1250) { + maxModules = 4; + } else { + if (menuSize > 1100) { + maxModules = 3; + } else { + if (menuSize > 900) { + maxModules = 2; + } else { + maxModules = 1; + if (menuSize < 750) { + maxModules = null; + } + } + } + } + } + + this.setState({ maxModules: maxModules, widthWindow: window.innerWidth }); }; /* TODO: we should to create a unique Explore agent button instead @@ -152,6 +218,7 @@ export const AgentsWelcome = compose( /* WORKAROUND: ensure the $scope.agent is synced with the agent stored in Redux (this.props.agent). See agents.js controller. */ this.props.setAgent(this.props.agent); + this.updatePinnedApplications(); this.updateWidth(); const tabVisualizations = new TabVisualizations(); tabVisualizations.removeAll(); @@ -163,8 +230,10 @@ export const AgentsWelcome = compose( const $injector = getAngularModule().$injector; this.drawerLokedSubscribtion = getChrome() .getIsNavDrawerLocked$() - .subscribe(() => { - this.updateWidth(); + .subscribe(isLocked => { + this.setState({ isLocked }, () => { + this.updateWidth(); + }); }); this.router = $injector.get('$route'); this.location = $injector.get('$location'); @@ -188,26 +257,111 @@ export const AgentsWelcome = compose( this.drawerLokedSubscribtion?.unsubscribe(); } - renderEndpointsSummaryButton() { - const application = Applications.find( - ({ id }) => id === 'endpoints-summary', + updatePinnedApplications(applications) { + let pinnedApplications; + + if (applications) { + pinnedApplications = applications; + } else { + pinnedApplications = window.localStorage.getItem( + 'wz-menu-agent-apps-pinned', + ) + ? JSON.parse(window.localStorage.getItem('wz-menu-agent-apps-pinned')) + : [ + // Default pinned applications + threatHunting.id, + fileIntegrityMonitoring.id, + configurationAssessment.id, + mitreAttack.id, + malwareDetection.id, + ]; + } + + // Ensure the pinned applications are supported + pinnedApplications = pinnedApplications.filter(pinnedApplication => + Applications.some(({ id }) => id === pinnedApplication), + ); + + window.localStorage.setItem( + 'wz-menu-agent-apps-pinned', + JSON.stringify(pinnedApplications), ); + this.setState({ menuAgent: pinnedApplications }); + } + + renderModules() { return ( - - - {application.title} - - + + {this.state.menuAgent.map((applicationId, i) => { + const moduleID = Object.keys(WAZUH_MODULES).find( + key => WAZUH_MODULES[key]?.appId === applicationId, + ).appId; + if ( + i < this.state.maxModules && + hasAgentSupportModule(this.props.agent, moduleID) + ) { + return ( + + + + + { + Applications.find(({ id }) => id === applicationId) + .title + } +   + + + + + ); + } + })} + + + this.setState({ switchModule: !this.state.switchModule }) + } + > + More... + + } + isOpen={this.state.switchModule} + closePopover={() => this.setState({ switchModule: false })} + repositionOnScroll={false} + anchorPosition='downCenter' + > +
+ +
+ + this.updatePinnedApplications(applications) + } + closePopover={() => { + this.setState({ switchModule: false }); + }} + switchTab={module => this.props.switchTab(module)} + > +
+
+
+
+
+
); } @@ -224,9 +378,47 @@ export const AgentsWelcome = compose( > - - {this.renderEndpointsSummaryButton()} - + {(this.state.maxModules !== null && this.renderModules()) || ( + + + this.setState({ + switchModule: !this.state.switchModule, + }) + } + > + Applications + + } + isOpen={this.state.switchModule} + closePopover={() => this.setState({ switchModule: false })} + repositionOnScroll={false} + anchorPosition='downCenter' + > +
+ +
+ + this.updatePinnedApplications(applications) + } + closePopover={() => { + this.setState({ switchModule: false }); + }} + switchTab={module => this.props.switchTab(module)} + > +
+
+
+
+
+ )}
@@ -272,13 +464,13 @@ export const AgentsWelcome = compose( this.props.switchTab('syscollector', notNeedStatus) } className='wz-it-hygiene-header-button' - tooltip={{ - position: 'bottom', - content: 'Inventory data', - className: 'wz-it-hygiene-header-button-tooltip', - }} + tooltip={ + this.state.maxModules === null + ? { position: 'bottom', content: 'Inventory data' } + : undefined + } > - Inventory data + {this.state.maxModules !== null ? 'Inventory data' : ''} @@ -287,13 +479,13 @@ export const AgentsWelcome = compose( iconType='stats' onClick={() => this.props.switchTab('stats', notNeedStatus)} className='wz-it-hygiene-header-button' - tooltip={{ - position: 'bottom', - content: 'Stats', - className: 'wz-it-hygiene-header-button-tooltip', - }} + tooltip={ + this.state.maxModules === null + ? { position: 'bottom', content: 'Stats' } + : undefined + } > - Stats + {this.state.maxModules !== null ? 'Stats' : ''} @@ -304,13 +496,13 @@ export const AgentsWelcome = compose( this.props.switchTab('configuration', notNeedStatus) } className='wz-it-hygiene-header-button' - tooltip={{ - position: 'bottom', - content: 'Configuration', - className: 'wz-it-hygiene-header-button-tooltip', - }} + tooltip={ + this.state.maxModules === null + ? { position: 'bottom', content: 'Configuration' } + : undefined + } > - Configuration + {this.state.maxModules !== null ? 'Configuration' : ''}
diff --git a/plugins/main/public/components/common/welcome/components/menu-agent.js b/plugins/main/public/components/common/welcome/components/menu-agent.js new file mode 100644 index 0000000000..f11013ad54 --- /dev/null +++ b/plugins/main/public/components/common/welcome/components/menu-agent.js @@ -0,0 +1,218 @@ +/* + * Wazuh app - React component for registering agents. + * Copyright (C) 2015-2022 Wazuh, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Find more information about this on the LICENSE file. + */ +import React, { Component } from 'react'; +import { + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiSideNav, + EuiLink, +} from '@elastic/eui'; +import { connect } from 'react-redux'; +import { hasAgentSupportModule } from '../../../../react-services/wz-agents'; +import { + getAngularModule, + getCore, + getToasts, +} from '../../../../kibana-services'; +import { updateCurrentAgentData } from '../../../../redux/actions/appStateActions'; +import { Applications, Categories } from '../../../../utils/applications'; +import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; + +class WzMenuAgent extends Component { + constructor(props) { + super(props); + this.state = { + hoverAddFilter: '', + }; + + this.appCategories = Applications.reduce((categories, app) => { + const existingCategory = categories.find( + category => category.id === app.category, + ); + if (app.showInAgentMenu) { + if (existingCategory) { + existingCategory.apps.push(app); + } else { + const category = Categories.find( + category => app.category === category.id, + ); + categories.push({ + id: category.id, + label: Categories.find(category => app.category === category.id) + .label, + icon: category.euiIconType, + apps: [app], + }); + } + } + return categories; + }, []).sort((a, b) => { + return ( + Categories.find(category => a.id === category.id).order - + Categories.find(category => b.id === category.id).order + ); + }); + } + + componentDidMount() { + const $injector = getAngularModule().$injector; + this.router = $injector.get('$route'); + } + + clickMenuItem = appId => { + this.props.closePopover(); + // do not redirect if we already are in that tab + this.props.updateCurrentAgentData(this.props.isAgent); + this.router.reload(); + }; + + addToast({ color, title, text, time = 3000 }) { + getToasts().add({ title, text, toastLifeTimeMs: time, color }); + } + + createItems = items => { + return items + .filter(item => + hasAgentSupportModule(this.props.currentAgentData, item.id), + ) + .map(item => this.createItem(item)); + }; + + createItem = (item, data = {}) => { + // NOTE: Duplicate `name` values will cause `id` collisions. + return { + ...data, + id: item.id, + name: ( + { + this.setState({ hoverAddFilter: item.id }); + }} + onMouseLeave={() => { + this.setState({ hoverAddFilter: '' }); + }} + > + (!item.isTitle ? this.clickMenuItem(item.id) : null)} + style={{ cursor: !item.isTitle ? 'pointer' : 'normal' }} + > + + + {item.title} + + + + {this.state.hoverAddFilter === item.id && + !item.isTitle && + (this.props.pinnedApplications.length < 6 || item.isPin) && + (this.props.pinnedApplications.length > 1 || !item.isPin) && ( + + { + if ( + !item.isPin && + this.props.pinnedApplications.length < 6 + ) { + this.props.updatePinnedApplications([ + ...this.props.pinnedApplications, + item.id, + ]); + } else if ( + this.props.pinnedApplications.includes(item.id) + ) { + this.props.updatePinnedApplications([ + ...this.props.pinnedApplications.filter( + id => id !== item.id, + ), + ]); + } else { + this.addToast({ + title: + 'The limit of pinned applications has been reached', + color: 'danger', + }); + } + }} + color='primary' + type={ + this.props.pinnedApplications.includes(item.id) + ? 'pinFilled' + : 'pin' + } + aria-label='Next' + style={{ cursor: 'pointer' }} + /> + + )} + + ), + isSelected: this.props.currentTab === item.id, + }; + }; + + render() { + const items = this.appCategories.map(({ apps, ...rest }) => ({ + ...rest, + items: this.createItems( + apps.map(app => ({ + id: app.id, + title: app.title, + isPin: this.props.pinnedApplications.includes(app.id), + })), + ), + })); + + return ( +
+
+ + {items.map(item => ( + + , + items: item.items, + }, + ]} + style={{ padding: '4px 12px' }} + /> + + ))} + +
+
+ ); + } +} + +const mapStateToProps = state => { + return { + currentAgentData: state.appStateReducers.currentAgentData, + currentTab: state.appStateReducers.currentTab, + }; +}; + +const mapDispatchToProps = dispatch => ({ + updateCurrentAgentData: agentData => + dispatch(updateCurrentAgentData(agentData)), +}); + +export default connect(mapStateToProps, mapDispatchToProps)(WzMenuAgent); diff --git a/plugins/main/public/components/common/welcome/overview-welcome.js b/plugins/main/public/components/common/welcome/overview-welcome.js index 4ae352cc7c..8b04833f5d 100644 --- a/plugins/main/public/components/common/welcome/overview-welcome.js +++ b/plugins/main/public/components/common/welcome/overview-welcome.js @@ -34,7 +34,7 @@ import { compose } from 'redux'; import { Applications, Categories, - endpointSumary, + endpointSummary, overview, } from '../../../utils/applications'; import { getCore } from '../../../kibana-services'; @@ -66,7 +66,7 @@ export const OverviewWelcome = compose( withReduxProvider, withErrorBoundary, withGlobalBreadcrumb(props => { - return [{ text: overview.title }]; + return [{ text: overview.breadcrumbLabel }]; }), )( class OverviewWelcome extends Component { @@ -87,7 +87,7 @@ export const OverviewWelcome = compose( No agents were added to this manager.{' '} diff --git a/plugins/main/public/components/common/welcome/welcome.scss b/plugins/main/public/components/common/welcome/welcome.scss index dab373eee2..65dd40462b 100644 --- a/plugins/main/public/components/common/welcome/welcome.scss +++ b/plugins/main/public/components/common/welcome/welcome.scss @@ -44,41 +44,3 @@ span.statWithLink:hover { text-decoration: underline; } - -// Header buttons of IT Hygiene application - -// Sidebar is open and locked -body.euiBody--hasFlyout:not(.euiBody-hasOverlayMask) { - @media only screen and (max-width: 1345px) { - // Hide button text depending on the window size - .wz-it-hygiene-header-button .euiButtonEmpty__text { - display: none; - } - } - - @media only screen and (min-width: 1346px) { - // Hide the tooltip of button depending on the window size - .wz-it-hygiene-header-button-tooltip { - display: none; - } - } -} - -// Sidebar is closed -body:not(.euiBody--hasFlyout) { - @media only screen and (max-width: 1025px) { - // Hide button text depending on the window size - .wz-it-hygiene-header-button .euiButtonEmpty__text { - display: none; - } - } - - @media only screen and (min-width: 1026px) { - // Hide the tooltip of button depending on the window size - .wz-it-hygiene-header-button-tooltip { - display: none; - } - } -} - -// Header buttons of IT Hygiene application diff --git a/plugins/main/public/components/security/main.tsx b/plugins/main/public/components/security/main.tsx index ed17f3667e..c2198d8096 100644 --- a/plugins/main/public/components/security/main.tsx +++ b/plugins/main/public/components/security/main.tsx @@ -57,7 +57,7 @@ const tabs = [ export const WzSecurity = compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb([{ text: security.title }]), + withGlobalBreadcrumb([{ text: security.breadcrumbLabel }]), )(() => { // Get the initial tab when the component is initiated const securityTabRegExp = new RegExp( diff --git a/plugins/main/public/components/wz-menu/wz-menu.scss b/plugins/main/public/components/wz-menu/wz-menu.scss index 7eed9064ed..02afe9d394 100644 --- a/plugins/main/public/components/wz-menu/wz-menu.scss +++ b/plugins/main/public/components/wz-menu/wz-menu.scss @@ -244,3 +244,11 @@ md-toolbar .md-button { height: 16px !important; margin-right: 6px; } + +.WzManagementSideMenu { + padding: 16px; +} + +.WzManagementSideMenu span { + font-size: 14px !important; +} diff --git a/plugins/main/public/controllers/agent/components/agents-preview.js b/plugins/main/public/controllers/agent/components/agents-preview.js index a077afea2e..60d8fb2b76 100644 --- a/plugins/main/public/controllers/agent/components/agents-preview.js +++ b/plugins/main/public/controllers/agent/components/agents-preview.js @@ -56,14 +56,14 @@ import { agentStatusColorByAgentStatus, agentStatusLabelByAgentStatus, } from '../../../../common/services/wz_agent_status'; -import { endpointSumary, itHygiene } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; import { getCore } from '../../../kibana-services'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; export const AgentsPreview = compose( withErrorBoundary, withReduxProvider, - withGlobalBreadcrumb([{ text: endpointSumary.title }]), + withGlobalBreadcrumb([{ text: endpointSummary.breadcrumbLabel }]), withUserAuthorizationPrompt([ [ { action: 'agent:read', resource: 'agent:id:*' }, @@ -330,7 +330,7 @@ export const AgentsPreview = compose( > { this.props.updateCurrentAgentData(item); - getCore().application.navigateToApp(itHygiene.id, { + getCore().application.navigateToApp(endpointSummary.id, { path: `#/agents?tab=welcome&agent=${item.id}`, }); }, diff --git a/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx b/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx index f12aea47d4..6cdce20c0e 100644 --- a/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/cdblists/views/cdblists-overview.tsx @@ -60,7 +60,7 @@ function WzCDBListsOverview(props) { export default compose( withGlobalBreadcrumb(props => { - return [{ text: cdbLists.title }]; + return [{ text: cdbLists.breadcrumbLabel }]; }), withUserAuthorizationPrompt(props => [ { diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js index 78d4682bfd..9c183ab145 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js @@ -17,7 +17,8 @@ import { withReduxProvider, } from '../../../../../components/common/hocs'; import { compose } from 'redux'; -import { itHygiene, settings } from '../../../../../utils/applications'; +import { endpointSummary, settings } from '../../../../../utils/applications'; +import { getCore } from '../../../../../kibana-services'; export default compose( withErrorBoundary, @@ -25,11 +26,14 @@ export default compose( withGlobalBreadcrumb(props => { let breadcrumb = false; if (props.agent.id === '000') { - breadcrumb = [{ text: settings.title }]; + breadcrumb = [{ text: settings.breadcrumbLabel }]; } else { breadcrumb = [ { - text: itHygiene.title, + text: endpointSummary.breadcrumbLabel, + href: getCore().application.getUrlForApp(endpointSummary.id, { + path: `#/agents-preview`, + }), }, { agent: props.agent }, { text: 'Configuration' }, diff --git a/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx b/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx index f5c29dcf44..84bc049ad9 100644 --- a/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/decoders/views/decoders-overview.tsx @@ -61,7 +61,7 @@ function WzDecodersOverview(props) { export default compose( withGlobalBreadcrumb(props => { - return [{ text: decoders.title }]; + return [{ text: decoders.breadcrumbLabel }]; }), withUserAuthorizationPrompt(props => [ { diff --git a/plugins/main/public/controllers/management/components/management/groups/group-agents-table.js b/plugins/main/public/controllers/management/components/management/groups/group-agents-table.js index 234923622b..04cb23d7b6 100644 --- a/plugins/main/public/controllers/management/components/management/groups/group-agents-table.js +++ b/plugins/main/public/controllers/management/components/management/groups/group-agents-table.js @@ -39,7 +39,7 @@ import { UI_ERROR_SEVERITIES } from '../../../../../react-services/error-orchest import { getErrorOrchestrator } from '../../../../../react-services/common-services'; import { AgentStatus } from '../../../../../components/agents/agent-status'; import { WzRequest } from '../../../../../react-services'; -import { itHygiene } from '../../../../../utils/applications'; +import { endpointSummary } from '../../../../../utils/applications'; import { updateCurrentAgentData } from '../../../../../redux/actions/appStateActions'; class WzGroupAgentsTable extends Component { @@ -121,7 +121,7 @@ class WzGroupAgentsTable extends Component { iconType='eye' onClick={async () => { this.props.updateCurrentAgentData(item); - getCore().application.navigateToApp(itHygiene.id, { + getCore().application.navigateToApp(endpointSummary.id, { path: `#/agents?agent=${item.id}`, }); }} diff --git a/plugins/main/public/controllers/management/components/management/groups/groups-main.js b/plugins/main/public/controllers/management/components/management/groups/groups-main.js index 3337ca6230..3898978ec3 100644 --- a/plugins/main/public/controllers/management/components/management/groups/groups-main.js +++ b/plugins/main/public/controllers/management/components/management/groups/groups-main.js @@ -121,6 +121,6 @@ const mapDispatchToProps = dispatch => { export default compose( connect(mapStateToProps, mapDispatchToProps), withGlobalBreadcrumb(props => { - return [{ text: endpointGroups.title }]; + return [{ text: endpointGroups.breadcrumbLabel }]; }), )(WzGroups); diff --git a/plugins/main/public/controllers/management/components/management/mg-logs/logs.js b/plugins/main/public/controllers/management/components/management/mg-logs/logs.js index 1a4fd7aaa0..e43fedf64f 100644 --- a/plugins/main/public/controllers/management/components/management/mg-logs/logs.js +++ b/plugins/main/public/controllers/management/components/management/mg-logs/logs.js @@ -44,7 +44,7 @@ import { WzFieldSearchDelay } from '../../../../../components/common/search'; import { logs } from '../../../../../utils/applications'; export default compose( - withGlobalBreadcrumb([{ text: logs.title }]), + withGlobalBreadcrumb([{ text: logs.breadcrumbLabel }]), withUserAuthorizationPrompt([ { action: 'cluster:status', resource: '*:*:*' }, { action: 'cluster:read', resource: 'node:id:*' }, diff --git a/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js b/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js index 9c53891632..8d64ac9915 100644 --- a/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js +++ b/plugins/main/public/controllers/management/components/management/reporting/reporting-main.js @@ -39,6 +39,6 @@ class WzReporting extends Component { export default compose( withReduxProvider, withGlobalBreadcrumb(props => { - return [{ text: reporting.title }]; + return [{ text: reporting.breadcrumbLabel }]; }), )(WzReporting); diff --git a/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx b/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx index d0ded8e439..349458aa89 100644 --- a/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx +++ b/plugins/main/public/controllers/management/components/management/ruleset/views/ruleset-overview.tsx @@ -60,7 +60,7 @@ function WzRulesetOverview(props) { export default compose( withGlobalBreadcrumb(props => { - return [{ text: rules.title }]; + return [{ text: rules.breadcrumbLabel }]; }), withUserAuthorizationPrompt(props => [ { diff --git a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js index 7cd5cb998b..e7f9f1b549 100644 --- a/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js +++ b/plugins/main/public/controllers/management/components/management/statistics/statistics-overview.js @@ -282,7 +282,7 @@ export class WzStatisticsOverview extends Component { } export default compose( - withGlobalBreadcrumb([{ text: statistics.title }]), + withGlobalBreadcrumb([{ text: statistics.breadcrumbLabel }]), withGuard(props => { return !(wzConfig.getConfig() || {})['cron.statistics.status']; // if 'cron.statistics.status' is false, then it renders PromptStatisticsDisabled component }, PromptStatisticsDisabled), diff --git a/plugins/main/public/controllers/management/components/management/status/status-overview.js b/plugins/main/public/controllers/management/components/management/status/status-overview.js index 32b91a612f..0d3c8b75f8 100644 --- a/plugins/main/public/controllers/management/components/management/status/status-overview.js +++ b/plugins/main/public/controllers/management/components/management/status/status-overview.js @@ -264,7 +264,7 @@ const mapDispatchToProps = dispatch => { }; export default compose( - withGlobalBreadcrumb([{ text: serverStatus.title }]), + withGlobalBreadcrumb([{ text: serverStatus.breadcrumbLabel }]), withUserAuthorizationPrompt([ [ { action: 'agent:read', resource: 'agent:id:*' }, diff --git a/plugins/main/public/controllers/management/monitoring.js b/plugins/main/public/controllers/management/monitoring.js index 4548e46718..be56f6ab53 100644 --- a/plugins/main/public/controllers/management/monitoring.js +++ b/plugins/main/public/controllers/management/monitoring.js @@ -20,7 +20,7 @@ import { updateGlobalBreadcrumb } from '../../redux/actions/globalBreadcrumbActi import { ModulesHelper } from '../../components/common/modules/modules-helper'; import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../common/constants'; import { getCore, getDataPlugin } from '../../kibana-services'; -import { cluster, endpointSumary } from '../../utils/applications'; +import { cluster, endpointSummary } from '../../utils/applications'; export function ClusterController( $scope, @@ -81,7 +81,7 @@ export function ClusterController( * This navigates to agents preview */ $scope.goAgents = () => { - getCore().application.navigateToApp(endpointSumary.id, { + getCore().application.navigateToApp(endpointSummary.id, { path: '#/agents-preview', }); }; @@ -323,7 +323,7 @@ export function ClusterController( $scope.expandArray = [false, false]; - const breadcrumb = [{ text: cluster.title }]; + const breadcrumb = [{ text: cluster.breadcrumbLabel }]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); if (clusterEnabled) load(); diff --git a/plugins/main/public/controllers/overview/components/stats.js b/plugins/main/public/controllers/overview/components/stats.js index e98c252409..c77300113f 100644 --- a/plugins/main/public/controllers/overview/components/stats.js +++ b/plugins/main/public/controllers/overview/components/stats.js @@ -26,7 +26,7 @@ import { agentStatusColorByAgentStatus, } from '../../../../common/services/wz_agent_status'; import { getCore } from '../../../kibana-services'; -import { endpointSumary } from '../../../utils/applications'; +import { endpointSummary } from '../../../utils/applications'; export const Stats = withErrorBoundary( class Stats extends Component { @@ -55,7 +55,7 @@ export const Stats = withErrorBoundary( } else if (sessionStorage.getItem('wz-agents-overview-table-filter')) { sessionStorage.removeItem('wz-agents-overview-table-filter'); } - getCore().application.navigateToApp(endpointSumary.id, { + getCore().application.navigateToApp(endpointSummary.id, { path: '#/agents-preview', }); } diff --git a/plugins/main/public/controllers/settings/settings.js b/plugins/main/public/controllers/settings/settings.js index b405243fb0..76206c378b 100644 --- a/plugins/main/public/controllers/settings/settings.js +++ b/plugins/main/public/controllers/settings/settings.js @@ -83,11 +83,11 @@ export class SettingsController { this.tab = location.tab; const tabActiveName = Applications.find( ({ id }) => getWzCurrentAppID() === id, - ).title; + ).breadcrumbLabel; const breadcrumb = [{ text: tabActiveName }]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); } else { - const breadcrumb = [{ text: serverApis.title }]; + const breadcrumb = [{ text: serverApis.breadcrumbLabel }]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); } diff --git a/plugins/main/public/controllers/tools/tools.ts b/plugins/main/public/controllers/tools/tools.ts index 14d114a15e..8fd33b0f88 100644 --- a/plugins/main/public/controllers/tools/tools.ts +++ b/plugins/main/public/controllers/tools/tools.ts @@ -54,7 +54,12 @@ export class ToolsController { this.load = false; const breadcrumb = [ - { text: this.tab === 'devTools' ? devTools.title : rulesetTest.title }, + { + text: + this.tab === 'devTools' + ? devTools.breadcrumbLabel + : rulesetTest.breadcrumbLabel, + }, ]; store.dispatch(updateGlobalBreadcrumb(breadcrumb)); } catch (error) { diff --git a/plugins/main/public/utils/applications.ts b/plugins/main/public/utils/applications.ts index aa675cd06b..36fa358ec2 100644 --- a/plugins/main/public/utils/applications.ts +++ b/plugins/main/public/utils/applications.ts @@ -34,6 +34,9 @@ export const overview = { title: i18n.translate('wz-app-home-title', { defaultMessage: 'Overview', }), + breadcrumbLabel: i18n.translate('wz-app-home-breadcrumbLabel', { + defaultMessage: 'Overview', + }), description: i18n.translate('wz-app-overview-description', { defaultMessage: 'This application provides you with an overview of Wazuh applications.', @@ -51,6 +54,12 @@ export const fileIntegrityMonitoring = { title: i18n.translate('wz-app-file-integrity-monitoring-title', { defaultMessage: 'File Integrity Monitoring', }), + breadcrumbLabel: i18n.translate( + 'wz-app-file-integrity-monitoring-breadcrumbLabel', + { + defaultMessage: 'File Integrity Monitoring', + }, + ), description: i18n.translate('wz-app-file-integrity-monitoring-description', { defaultMessage: 'Alerts related to file changes, including permissions, content, ownership, and attributes.', @@ -67,12 +76,15 @@ export const fileIntegrityMonitoring = { }`, }; -export const endpointSumary = { +export const endpointSummary = { category: 'wz-category-server-management', id: 'endpoints-summary', title: i18n.translate('wz-app-endpoints-summary-title', { defaultMessage: 'Endpoints Summary', }), + breadcrumbLabel: i18n.translate('wz-app-endpoints-summary-breadcrumbLabel', { + defaultMessage: 'Endpoints', + }), description: i18n.translate('wz-app-endpoints-summary-description', { defaultMessage: 'Summary of agents and their status.', }), @@ -89,6 +101,9 @@ export const malwareDetection = { title: i18n.translate('wz-app-malware-detection-title', { defaultMessage: 'Malware Detection', }), + breadcrumbLabel: i18n.translate('wz-app-malware-detection-breadcrumbLabel', { + defaultMessage: 'Malware Detection', + }), description: i18n.translate('wz-app-malware-detection-description', { defaultMessage: 'Verify that your systems are configured according to your security policies baseline.', @@ -111,6 +126,12 @@ export const configurationAssessment = { title: i18n.translate('wz-app-configuration-assessment-title', { defaultMessage: 'Configuration Assessment', }), + breadcrumbLabel: i18n.translate( + 'wz-app-configuration-assessment-breadcrumbLabel', + { + defaultMessage: 'Configuration Assessment', + }, + ), description: i18n.translate('wz-app-configuration-assessment-description', { defaultMessage: 'Scan your assets as part of a configuration assessment audit.', @@ -133,6 +154,9 @@ export const threatHunting = { title: i18n.translate('wz-app-threat-hunting-title', { defaultMessage: 'Threat Hunting', }), + breadcrumbLabel: i18n.translate('wz-app-threat-hunting-breadcrumbLabel', { + defaultMessage: 'Threat Hunting', + }), description: i18n.translate('wz-app-threat-hunting-description', { defaultMessage: 'Browse through your security alerts, identifying issues and threats in your environment.', @@ -155,6 +179,12 @@ export const vulnerabilityDetection = { title: i18n.translate('wz-app-vulnerability-detection-title', { defaultMessage: 'Vulnerability Detection', }), + breadcrumbLabel: i18n.translate( + 'wz-app-vulnerability-detection-breadcrumbLabel', + { + defaultMessage: 'Vulnerability Detection', + }, + ), description: i18n.translate('wz-app-vulnerability-detection-description', { defaultMessage: 'Discover what applications in your environment are affected by well-known vulnerabilities.', @@ -162,7 +192,7 @@ export const vulnerabilityDetection = { euiIconType: 'heartbeatApp', order: 301, showInOverviewApp: true, - showInAgentMenu: true, + showInAgentMenu: false, redirectTo: () => `/overview/?tab=vuls&tabView=panels${ store.getState()?.appStateReducers?.currentAgentData?.id @@ -177,6 +207,9 @@ export const mitreAttack = { title: i18n.translate('wz-app-mitre-attack-title', { defaultMessage: 'MITRE ATT&CK', }), + breadcrumbLabel: i18n.translate('wz-app-mitre-attack-breadcrumbLabel', { + defaultMessage: 'MITRE ATT&CK', + }), description: i18n.translate('wz-app-mitre-attack-description', { defaultMessage: 'Security events from the knowledge base of adversary tactics and techniques based on real-world observations.', @@ -199,6 +232,9 @@ export const virustotal = { title: i18n.translate('wz-app-virustotal-title', { defaultMessage: 'Virustotal', }), + breadcrumbLabel: i18n.translate('wz-app-virustotal-breadcrumbLabel', { + defaultMessage: 'Virustotal', + }), description: i18n.translate('wz-app-virustotal-description', { defaultMessage: 'Alerts resulting from VirusTotal analysis of suspicious files via an integration with their API.', @@ -221,6 +257,9 @@ const pciDss = { title: i18n.translate('wz-app-pci-dss-title', { defaultMessage: 'PCI DSS', }), + breadcrumbLabel: i18n.translate('wz-app-pci-dss-breadcrumbLabel', { + defaultMessage: 'PCI DSS', + }), description: i18n.translate('wz-app-pci-dss-description', { defaultMessage: 'Global security standard for entities that process, store, or transmit payment cardholder data.', @@ -243,6 +282,9 @@ const hipaa = { title: i18n.translate('wz-app-hipaa-title', { defaultMessage: 'HIPAA', }), + breadcrumbLabel: i18n.translate('wz-app-hipaa-breadcrumbLabel', { + defaultMessage: 'HIPAA', + }), description: i18n.translate('wz-app-hipaa-description', { defaultMessage: 'Health Insurance Portability and Accountability Act of 1996 (HIPAA) provides data privacy and security provisions for safeguarding medical information.', @@ -265,6 +307,9 @@ const gdpr = { title: i18n.translate('wz-app-gdpr-title', { defaultMessage: 'GDPR', }), + breadcrumbLabel: i18n.translate('wz-app-gdpr-breadcrumbLabel', { + defaultMessage: 'GDPR', + }), description: i18n.translate('wz-app-gdpr-description', { defaultMessage: 'General Data Protection Regulation (GDPR) sets guidelines for processing of personal data.', @@ -287,6 +332,9 @@ const nist80053 = { title: i18n.translate('wz-app-nist-800-53-title', { defaultMessage: 'NIST 800-53', }), + breadcrumbLabel: i18n.translate('wz-app-nist-800-53-breadcrumbLabel', { + defaultMessage: 'NIST 800-53', + }), description: i18n.translate('wz-app-nist-800-53-description', { defaultMessage: 'National Institute of Standards and Technology Special Publication 800-53 (NIST 800-53) sets guidelines for federal information systems.', @@ -309,6 +357,9 @@ const tsc = { title: i18n.translate('wz-app-tsc-title', { defaultMessage: 'TSC', }), + breadcrumbLabel: i18n.translate('wz-app-tsc-breadcrumbLabel', { + defaultMessage: 'TSC', + }), description: i18n.translate('wz-app-tsc-description', { defaultMessage: 'Trust Services Criteria for Security, Availability, Processing Integrity, Confidentiality, and Privacy.', @@ -325,34 +376,18 @@ const tsc = { }`, }; -export const itHygiene = { - category: 'wz-category-security-operations', - id: 'it-hygiene', - title: i18n.translate('wz-app-it-hygiene-title', { - defaultMessage: 'IT Hygiene', - }), - description: i18n.translate('wz-app-it-hygiene-description', { - defaultMessage: - 'Applications, network configuration, open ports, and processes running on your monitored systems.', - }), - euiIconType: 'visualizeApp', - order: 405, - showInOverviewApp: true, - showInAgentMenu: false, - redirectTo: () => - `/agents/?tab=welcome${ - store.getState()?.appStateReducers?.currentAgentData?.id - ? `&agent=${store.getState()?.appStateReducers?.currentAgentData?.id}` - : '' - }`, -}; - export const amazonWebServices = { category: 'wz-category-cloud-security', id: 'amazon-web-services', title: i18n.translate('wz-app-amazon-web-services-title', { defaultMessage: 'Amazon Web Services', }), + breadcrumbLabel: i18n.translate( + 'wz-app-amazon-web-services-breadcrumbLabel', + { + defaultMessage: 'Amazon Web Services', + }, + ), description: i18n.translate('wz-app-amazon-web-services-description', { defaultMessage: 'Security events related to your Amazon AWS services, collected directly via AWS API.', @@ -375,6 +410,9 @@ export const googleCloud = { title: i18n.translate('wz-app-google-cloud-title', { defaultMessage: 'Google Cloud', }), + breadcrumbLabel: i18n.translate('wz-app-google-cloud-breadcrumbLabel', { + defaultMessage: 'Google Cloud', + }), description: i18n.translate('wz-app-google-cloud-description', { defaultMessage: 'Security events related to your Google Cloud Platform services, collected directly via GCP API.', @@ -397,6 +435,9 @@ export const github = { title: i18n.translate('wz-app-github-title', { defaultMessage: 'GitHub', }), + breadcrumbLabel: i18n.translate('wz-app-github-breadcrumbLabel', { + defaultMessage: 'GitHub', + }), description: i18n.translate('wz-app-github-description', { defaultMessage: 'Monitoring events from audit logs of your GitHub organizations.', @@ -419,6 +460,9 @@ export const office365 = { title: i18n.translate('wz-app-office365-title', { defaultMessage: 'Office 365', }), + breadcrumbLabel: i18n.translate('wz-app-office365-breadcrumbLabel', { + defaultMessage: 'Office 365', + }), description: i18n.translate('wz-app-office365-description', { defaultMessage: 'Security events related to your Office 365 services.', }), @@ -440,6 +484,9 @@ export const docker = { title: i18n.translate('wz-app-docker-title', { defaultMessage: 'Docker', }), + breadcrumbLabel: i18n.translate('wz-app-docker-breadcrumbLabel', { + defaultMessage: 'Docker', + }), description: i18n.translate('wz-app-docker-description', { defaultMessage: 'Monitor and collect the activity from Docker containers such as creation, running, starting, stopping or pausing events.', @@ -462,6 +509,9 @@ export const rules = { title: i18n.translate('wz-app-rules-title', { defaultMessage: 'Rules', }), + breadcrumbLabel: i18n.translate('wz-app-rules-breadcrumbLabel', { + defaultMessage: 'Rules', + }), description: i18n.translate('wz-app-rules-description', { defaultMessage: 'Manage your Wazuh cluster rules.', }), @@ -478,6 +528,9 @@ export const decoders = { title: i18n.translate('wz-app-decoders-title', { defaultMessage: 'Decoders', }), + breadcrumbLabel: i18n.translate('wz-app-decoders-breadcrumbLabel', { + defaultMessage: 'Decoders', + }), description: i18n.translate('wz-app-decoders-description', { defaultMessage: 'Manage your Wazuh cluster decoders.', }), @@ -494,6 +547,9 @@ export const cdbLists = { title: i18n.translate('wz-app-lists-title', { defaultMessage: 'CDB Lists', }), + breadcrumbLabel: i18n.translate('wz-app-cdb-lists-breadcrumbLabel', { + defaultMessage: 'CDB Lists', + }), description: i18n.translate('wz-app-cdb-lists-description', { defaultMessage: 'Manage your Wazuh cluster CDB list.', }), @@ -510,6 +566,9 @@ export const endpointGroups = { title: i18n.translate('wz-app-endpoint-groups-title', { defaultMessage: 'Endpoint Groups', }), + breadcrumbLabel: i18n.translate('wz-app-endpoint-groups-breadcrumbLabel', { + defaultMessage: 'Endpoint Groups', + }), description: i18n.translate('wz-app-endpoint-groups-description', { defaultMessage: 'Manage your agent groups.', }), @@ -526,6 +585,9 @@ export const serverStatus = { title: i18n.translate('wz-app-status-title', { defaultMessage: 'Status', }), + breadcrumbLabel: i18n.translate('wz-app-server-status-breadcrumbLabel', { + defaultMessage: 'Status', + }), description: i18n.translate('wz-app-server-status-description', { defaultMessage: 'Manage your Wazuh cluster status.', }), @@ -542,6 +604,9 @@ export const cluster = { title: i18n.translate('wz-app-cluster-title', { defaultMessage: 'Cluster', }), + breadcrumbLabel: i18n.translate('wz-app-cluster-breadcrumbLabel', { + defaultMessage: 'Cluster', + }), description: i18n.translate('wz-app-cluster-description', { defaultMessage: 'Manage your Wazuh cluster.', }), @@ -558,6 +623,9 @@ export const statistics = { title: i18n.translate('wz-app-statistics-title', { defaultMessage: 'Statistics', }), + breadcrumbLabel: i18n.translate('wz-app-statistics-breadcrumbLabel', { + defaultMessage: 'Statistics', + }), description: i18n.translate('wz-app-statistics-description', { defaultMessage: 'Information about the Wazuh enviroment.', }), @@ -574,6 +642,9 @@ export const logs = { title: i18n.translate('wz-app-logs-title', { defaultMessage: 'Logs', }), + breadcrumbLabel: i18n.translate('wz-app-logs-breadcrumbLabel', { + defaultMessage: 'Logs', + }), description: i18n.translate('wz-app-logs-description', { defaultMessage: 'Logs from your Wazuh cluster.', }), @@ -590,6 +661,9 @@ export const reporting = { title: i18n.translate('wz-app-reporting-title', { defaultMessage: 'Reporting', }), + breadcrumbLabel: i18n.translate('wz-app-reporting-breadcrumbLabel', { + defaultMessage: 'Reporting', + }), description: i18n.translate('wz-app-reporting-description', { defaultMessage: 'Check your stored Wazuh reports.', }), @@ -606,6 +680,9 @@ export const settings = { title: i18n.translate('wz-app-settings-title', { defaultMessage: 'Settings', }), + breadcrumbLabel: i18n.translate('wz-app-settings-breadcrumbLabel', { + defaultMessage: 'Settings', + }), description: i18n.translate('wz-app-settings-description', { defaultMessage: 'Manage your Wazuh cluster configuration.', }), @@ -622,6 +699,9 @@ export const devTools = { title: i18n.translate('wz-app-dev-tools-title', { defaultMessage: 'Dev Tools', }), + breadcrumbLabel: i18n.translate('wz-app-dev-tools-breadcrumbLabel', { + defaultMessage: 'Dev Tools', + }), description: i18n.translate('wz-app-dev-tools-description', { defaultMessage: 'Test the Wazuh API endpoints.', }), @@ -638,6 +718,9 @@ export const rulesetTest = { title: i18n.translate('wz-app-ruleset-test-title', { defaultMessage: 'Ruleset Test', }), + breadcrumbLabel: i18n.translate('wz-app-ruleset-test-breadcrumbLabel', { + defaultMessage: 'Ruleset Test', + }), description: i18n.translate('wz-app-ruleset-test-description', { defaultMessage: 'Check your ruleset testing logs.', }), @@ -654,6 +737,9 @@ export const security = { title: i18n.translate('wz-app-security-title', { defaultMessage: 'Security', }), + breadcrumbLabel: i18n.translate('wz-app-security-breadcrumbLabel', { + defaultMessage: 'Security', + }), description: i18n.translate('wz-app-security-description', { defaultMessage: 'Manage permissions to system resources based on the roles and policies.', @@ -671,6 +757,9 @@ export const serverApis = { title: i18n.translate('wz-app-server-apis-title', { defaultMessage: 'Server APIs', }), + breadcrumbLabel: i18n.translate('wz-app-server-apis-breadcrumbLabel', { + defaultMessage: 'Server APIs', + }), description: i18n.translate('wz-app-server-apis-description', { defaultMessage: 'Manage and configure the API entries.', }), @@ -687,6 +776,9 @@ export const sampleData = { title: i18n.translate('wz-app-sample-data-title', { defaultMessage: 'Sample Data', }), + breadcrumbLabel: i18n.translate('wz-app-sample-data-breadcrumbLabel', { + defaultMessage: 'Sample Data', + }), description: i18n.translate('wz-app-sample-data-description', { defaultMessage: 'Add sample data with events to the modules.', }), @@ -703,6 +795,9 @@ export const appSettings = { title: i18n.translate('wz-app-settings-title', { defaultMessage: 'App Settings', }), + breadcrumbLabel: i18n.translate('wz-app-settings-breadcrumbLabel', { + defaultMessage: 'App Settings', + }), description: i18n.translate('wz-app-settings-description', { defaultMessage: 'Manage your Wazuh cluster configuration.', }), @@ -719,6 +814,9 @@ const appLogs = { title: i18n.translate('wz-app-app-logs-title', { defaultMessage: 'App Logs', }), + breadcrumbLabel: i18n.translate('wz-app-app-logs-breadcrumbLabel', { + defaultMessage: 'App Logs', + }), description: i18n.translate('wz-app-app-logs-description', { defaultMessage: 'Explore the logs related to the applications.', }), @@ -735,6 +833,9 @@ const about = { title: i18n.translate('wz-app-about-title', { defaultMessage: 'About', }), + breadcrumbLabel: i18n.translate('wz-app-about-breadcrumbLabel', { + defaultMessage: 'About', + }), description: i18n.translate('wz-app-about-description', { defaultMessage: 'Show information about App Versions and community links.', }), @@ -759,7 +860,6 @@ export const Applications = [ gdpr, nist80053, tsc, - itHygiene, devTools, rulesetTest, security, @@ -768,7 +868,7 @@ export const Applications = [ github, office365, docker, - endpointSumary, + endpointSummary, rules, decoders, cdbLists, From e606a35857959b2b72e94b43145f2ef58986a4a3 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:22:34 -0300 Subject: [PATCH 24/64] Split index dashboard management menu (#6371) * Split index/dashboard management menu * Update menu options orders --------- Co-authored-by: Federico Rodriguez --- .../main/public/react-services/reporting.js | 47 ++++++++++------ plugins/main/public/services/reporting.js | 55 ++++++++++++++----- plugins/main/public/utils/applications.ts | 35 +++++++----- 3 files changed, 94 insertions(+), 43 deletions(-) diff --git a/plugins/main/public/react-services/reporting.js b/plugins/main/public/react-services/reporting.js index 13a29777b2..2306b60d80 100644 --- a/plugins/main/public/react-services/reporting.js +++ b/plugins/main/public/react-services/reporting.js @@ -48,9 +48,10 @@ export class ReportingService { } removeAgentStatusVis(idArray) { - const monitoringEnabled = this.wazuhConfig.getConfig()['wazuh.monitoring.enabled']; + const monitoringEnabled = + this.wazuhConfig.getConfig()['wazuh.monitoring.enabled']; if (!monitoringEnabled) { - const visArray = idArray.filter((vis) => { + const visArray = idArray.filter(vis => { return vis !== 'Wazuh-App-Overview-General-Agents-status'; }); return visArray; @@ -70,13 +71,17 @@ export class ReportingService { this.vis2png.clear(); - const rawVisualizations = this.rawVisualizations.getList().filter(this.removeTableVis); + const rawVisualizations = this.rawVisualizations + .getList() + .filter(this.removeTableVis); let idArray = []; if (tab === 'general') { - idArray = this.removeAgentStatusVis(rawVisualizations.map((item) => item.id)); + idArray = this.removeAgentStatusVis( + rawVisualizations.map(item => item.id), + ); } else { - idArray = rawVisualizations.map((item) => item.id); + idArray = rawVisualizations.map(item => item.id); } const visualizationIDList = []; @@ -88,7 +93,9 @@ export class ReportingService { } } - const appliedFilters = await this.visHandlers.getAppliedFilters(syscollectorFilters); + const appliedFilters = await this.visHandlers.getAppliedFilters( + syscollectorFilters, + ); const dataplugin = await getDataPlugin(); const serverSideQuery = dataplugin.query.getOpenSearchQuery(); const array = await this.vis2png.checkArray(visualizationIDList); @@ -106,12 +113,16 @@ export class ReportingService { section: agents ? 'agents' : 'overview', agents, browserTimezone, - indexPatternTitle: (await getDataPlugin().indexPatterns.get(AppState.getCurrentPattern())).title, - apiId: JSON.parse(AppState.getCurrentAPI()).id + indexPatternTitle: ( + await getDataPlugin().indexPatterns.get(AppState.getCurrentPattern()) + ).title, + apiId: JSON.parse(AppState.getCurrentAPI()).id, }; const apiEndpoint = - tab === 'syscollector' ? `/reports/agents/${agents}/inventory` : `/reports/modules/${tab}`; + tab === 'syscollector' + ? `/reports/agents/${agents}/inventory` + : `/reports/modules/${tab}`; await WzRequest.genericReq('POST', apiEndpoint, data); this.$rootScope.reportBusy = false; @@ -120,8 +131,8 @@ export class ReportingService { this.showToast( 'success', 'Created report', - 'Success. Go to Indexer/dashboard management > Reporting', - 4000 + 'Success. Go to Dashboard management > Reporting', + 4000, ); return; } catch (error) { @@ -152,13 +163,17 @@ export class ReportingService { const browserTimezone = moment.tz.guess(true); const data = { - filters: [type === 'agentConfig' ? { agent: obj.id } : { group: obj.name }], + filters: [ + type === 'agentConfig' ? { agent: obj.id } : { group: obj.name }, + ], browserTimezone, components, - apiId: JSON.parse(AppState.getCurrentAPI()).id + apiId: JSON.parse(AppState.getCurrentAPI()).id, }; const apiEndpoint = - type === 'agentConfig' ? `/reports/agents/${obj.id}` : `/reports/groups/${obj.name}`; + type === 'agentConfig' + ? `/reports/agents/${obj.id}` + : `/reports/groups/${obj.name}`; await WzRequest.genericReq('POST', apiEndpoint, data); this.$rootScope.reportBusy = false; @@ -167,8 +182,8 @@ export class ReportingService { this.showToast( 'success', 'Created report', - 'Success. Go to Indexer/dashboard management > Reporting', - 4000 + 'Success. Go to Dashboard management > Reporting', + 4000, ); return; } catch (error) { diff --git a/plugins/main/public/services/reporting.js b/plugins/main/public/services/reporting.js index 6bcc5c45d1..e44106bb66 100644 --- a/plugins/main/public/services/reporting.js +++ b/plugins/main/public/services/reporting.js @@ -17,7 +17,13 @@ import { GenericRequest } from '../react-services/generic-request'; import { ErrorHandler } from '../react-services/error-handler'; export class ReportingService { - constructor($rootScope, vis2png, rawVisualizations, visHandlers, errorHandler) { + constructor( + $rootScope, + vis2png, + rawVisualizations, + visHandlers, + errorHandler, + ) { this.$rootScope = $rootScope; this.vis2png = vis2png; this.rawVisualizations = rawVisualizations; @@ -32,9 +38,10 @@ export class ReportingService { } removeAgentStatusVis(idArray) { - const monitoringEnabled = this.wazuhConfig.getConfig()['wazuh.monitoring.enabled']; + const monitoringEnabled = + this.wazuhConfig.getConfig()['wazuh.monitoring.enabled']; if (!monitoringEnabled) { - const visArray = idArray.filter((vis) => { + const visArray = idArray.filter(vis => { return vis !== 'Wazuh-App-Overview-General-Agents-status'; }); return visArray; @@ -45,7 +52,9 @@ export class ReportingService { async startVis2Png(tab, isAgents = false, syscollectorFilters = null) { try { if (this.vis2png.isWorking()) { - ErrorHandler.handle('Report in progress', 'Reporting', { warning: true }); + ErrorHandler.handle('Report in progress', 'Reporting', { + warning: true, + }); return; } this.$rootScope.reportBusy = true; @@ -54,13 +63,17 @@ export class ReportingService { this.vis2png.clear(); - const rawVisualizations = this.rawVisualizations.getList().filter(this.removeTableVis); + const rawVisualizations = this.rawVisualizations + .getList() + .filter(this.removeTableVis); let idArray = []; if (tab === 'general') { - idArray = this.removeAgentStatusVis(rawVisualizations.map((item) => item.id)); + idArray = this.removeAgentStatusVis( + rawVisualizations.map(item => item.id), + ); } else { - idArray = rawVisualizations.map((item) => item.id); + idArray = rawVisualizations.map(item => item.id); } for (const item of idArray) { @@ -68,11 +81,14 @@ export class ReportingService { this.vis2png.assignHTMLItem(item, tmpHTMLElement); } - const appliedFilters = await this.visHandlers.getAppliedFilters(syscollectorFilters); + const appliedFilters = await this.visHandlers.getAppliedFilters( + syscollectorFilters, + ); const array = await this.vis2png.checkArray(idArray); - const name = `wazuh-${isAgents ? 'agents' : 'overview'}-${tab}-${(Date.now() / 1000) | 0 - }.pdf`; + const name = `wazuh-${isAgents ? 'agents' : 'overview'}-${tab}-${ + (Date.now() / 1000) | 0 + }.pdf`; const browserTimezone = moment.tz.guess(true); @@ -95,7 +111,10 @@ export class ReportingService { this.$rootScope.reportBusy = false; this.$rootScope.reportStatus = false; this.$rootScope.$applyAsync(); - ErrorHandler.info('Success. Go to Indexer/dashboard management > Reporting', 'Reporting'); + ErrorHandler.info( + 'Success. Go to Dashboard management > Reporting', + 'Reporting', + ); return; } catch (error) { @@ -111,7 +130,10 @@ export class ReportingService { this.$rootScope.reportStatus = 'Generating PDF document...'; this.$rootScope.$applyAsync(); - const docType = type === 'agentConfig' ? `wazuh-agent-${obj.id}` : `wazuh-group-${obj.name}`; + const docType = + type === 'agentConfig' + ? `wazuh-agent-${obj.id}` + : `wazuh-group-${obj.name}`; const name = `${docType}-configuration-${(Date.now() / 1000) | 0}.pdf`; const browserTimezone = moment.tz.guess(true); @@ -119,7 +141,9 @@ export class ReportingService { const data = { array: [], name, - filters: [type === 'agentConfig' ? { agent: obj.id } : { group: obj.name }], + filters: [ + type === 'agentConfig' ? { agent: obj.id } : { group: obj.name }, + ], time: '', searchBar: '', tables: [], @@ -133,7 +157,10 @@ export class ReportingService { this.$rootScope.reportBusy = false; this.$rootScope.reportStatus = false; this.$rootScope.$applyAsync(); - ErrorHandler.info('Success. Go to Indexer/dashboard management > Reporting', 'Reporting'); + ErrorHandler.info( + 'Success. Go to Dashboard management > Reporting', + 'Reporting', + ); return; } catch (error) { diff --git a/plugins/main/public/utils/applications.ts b/plugins/main/public/utils/applications.ts index 36fa358ec2..317fc12320 100644 --- a/plugins/main/public/utils/applications.ts +++ b/plugins/main/public/utils/applications.ts @@ -25,7 +25,8 @@ Threat intelligence: 300 Security operations: 400 Cloud security: 500 Server management: 600 -Dashboard/indexer management (added to Wazuh dashboard default categories): 9000 +Dashboard management: 700 +Indexer management (added to Wazuh dashboard default categories): 9000 */ export const overview = { @@ -656,7 +657,7 @@ export const logs = { }; export const reporting = { - category: 'management', + category: 'wz-category-dashboard-management', id: 'reporting', title: i18n.translate('wz-app-reporting-title', { defaultMessage: 'Reporting', @@ -668,7 +669,7 @@ export const reporting = { defaultMessage: 'Check your stored Wazuh reports.', }), euiIconType: 'indexRollupApp', - order: 8900, + order: 702, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=reporting', @@ -752,7 +753,7 @@ export const security = { }; export const serverApis = { - category: 'management', + category: 'wz-category-dashboard-management', id: 'server-apis', title: i18n.translate('wz-app-server-apis-title', { defaultMessage: 'Server APIs', @@ -764,7 +765,7 @@ export const serverApis = { defaultMessage: 'Manage and configure the API entries.', }), euiIconType: 'indexRollupApp', - order: 8901, + order: 703, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/settings?tab=api', @@ -783,14 +784,14 @@ export const sampleData = { defaultMessage: 'Add sample data with events to the modules.', }), euiIconType: 'indexRollupApp', - order: 8902, + order: 9040, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/settings?tab=sample_data', }; export const appSettings = { - category: 'management', + category: 'wz-category-dashboard-management', id: 'app-settings', title: i18n.translate('wz-app-settings-title', { defaultMessage: 'App Settings', @@ -802,14 +803,14 @@ export const appSettings = { defaultMessage: 'Manage your Wazuh cluster configuration.', }), euiIconType: 'indexRollupApp', - order: 8903, + order: 704, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/settings?tab=configuration', }; const appLogs = { - category: 'management', + category: 'wz-category-dashboard-management', id: 'app-logs', title: i18n.translate('wz-app-app-logs-title', { defaultMessage: 'App Logs', @@ -821,14 +822,14 @@ const appLogs = { defaultMessage: 'Explore the logs related to the applications.', }), euiIconType: 'indexRollupApp', - order: 8904, + order: 705, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/settings?tab=logs', }; const about = { - category: 'management', + category: 'wz-category-dashboard-management', id: 'about', title: i18n.translate('wz-app-about-title', { defaultMessage: 'About', @@ -840,7 +841,7 @@ const about = { defaultMessage: 'Show information about App Versions and community links.', }), euiIconType: 'indexRollupApp', - order: 8905, + order: 706, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/settings?tab=about', @@ -945,9 +946,17 @@ export const Categories = [ order: 600, euiIconType: 'indexRollupApp', }, + { + id: 'wz-category-dashboard-management', + label: i18n.translate('wz-app-category-dashboard-management', { + defaultMessage: 'Dashboard management', + }), + order: 700, + euiIconType: 'dashboardApp', + }, { id: 'management', - label: 'Indexer/dashboard management', + label: 'Indexer management', order: 5e3, euiIconType: 'managementApp', }, From a791fed437c53185c16095d4a6228d134e1d0126 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:56:27 -0300 Subject: [PATCH 25/64] Avoid force check updates when user logins (#6375) * Avoid force check updates when user logins * Update documentation * Update check updates button tooltip --- .../components/settings/api/api-table.js | 13 +++++++---- plugins/wazuh-check-updates/README.md | 5 ++++- .../public/services/available-updates.ts | 11 ++++++---- plugins/wazuh-check-updates/public/types.ts | 5 ++++- .../server/routes/updates/get-updates.test.ts | 2 +- .../server/routes/updates/get-updates.ts | 6 +++-- .../server/services/updates/get-updates.ts | 22 ++++++++++++------- 7 files changed, 43 insertions(+), 21 deletions(-) diff --git a/plugins/main/public/components/settings/api/api-table.js b/plugins/main/public/components/settings/api/api-table.js index defc942ca4..43e45e8ffa 100644 --- a/plugins/main/public/components/settings/api/api-table.js +++ b/plugins/main/public/components/settings/api/api-table.js @@ -58,11 +58,14 @@ export const ApiTable = compose( }; } - async getApisAvailableUpdates(forceUpdate = false) { + async getApisAvailableUpdates(queryApi = false, forceQuery = false) { try { this.setState({ refreshingAvailableUpdates: true }); const availableUpdates = - await getWazuhCheckUpdatesPlugin().getAvailableUpdates(forceUpdate); + await getWazuhCheckUpdatesPlugin().getAvailableUpdates( + queryApi, + forceQuery, + ); this.setState({ availableUpdates }); } catch (error) { const options = { @@ -548,12 +551,14 @@ export const ApiTable = compose( await this.getApisAvailableUpdates(true)} + onClick={async () => + await this.getApisAvailableUpdates(true, true) + } > Check updates{' '} => { +export const getAvailableUpdates = async ( + queryApi = false, + forceQuery = false, +): Promise => { const checkUpdates = sessionStorage.getItem('checkUpdates'); const alreadyCheckUpdates = checkUpdates === 'executed'; const availableUpdates = await getCore().http.get(routes.checkUpdates, { query: { - checkAvailableUpdates: forceUpdate || !alreadyCheckUpdates, + query_api: queryApi || !alreadyCheckUpdates, + force_query: forceQuery, }, }); diff --git a/plugins/wazuh-check-updates/public/types.ts b/plugins/wazuh-check-updates/public/types.ts index 4d5f2a77ab..eee0d141b0 100644 --- a/plugins/wazuh-check-updates/public/types.ts +++ b/plugins/wazuh-check-updates/public/types.ts @@ -5,7 +5,10 @@ export interface WazuhCheckUpdatesPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface WazuhCheckUpdatesPluginStart { UpdatesNotification: () => JSX.Element | null; - getAvailableUpdates: (forceUpdate: boolean) => Promise; + getAvailableUpdates: ( + queryApi: boolean, + forceQuery: boolean, + ) => Promise; DismissNotificationCheck: () => JSX.Element | null; } diff --git a/plugins/wazuh-check-updates/server/routes/updates/get-updates.test.ts b/plugins/wazuh-check-updates/server/routes/updates/get-updates.test.ts index 7172b12182..71e049ee5b 100644 --- a/plugins/wazuh-check-updates/server/routes/updates/get-updates.test.ts +++ b/plugins/wazuh-check-updates/server/routes/updates/get-updates.test.ts @@ -100,7 +100,7 @@ describe(`[endpoint] GET ${routes.checkUpdates}`, () => { mockedGetUpdates.mockImplementation(() => mockResponse); const response = await supertest(innerServer.listener) - .get(`${routes.checkUpdates}?checkAvailableUpdates=true`) + .get(`${routes.checkUpdates}?query_api=true`) .send(mockResponse) .expect(200); diff --git a/plugins/wazuh-check-updates/server/routes/updates/get-updates.ts b/plugins/wazuh-check-updates/server/routes/updates/get-updates.ts index a03704c7dd..5f91813919 100644 --- a/plugins/wazuh-check-updates/server/routes/updates/get-updates.ts +++ b/plugins/wazuh-check-updates/server/routes/updates/get-updates.ts @@ -9,14 +9,16 @@ export const getUpdatesRoute = (router: IRouter) => { path: routes.checkUpdates, validate: { query: schema.object({ - checkAvailableUpdates: schema.maybe(schema.string()), + query_api: schema.maybe(schema.string()), + force_query: schema.maybe(schema.string()), }), }, }, async (context, request, response) => { try { const updates = await getUpdates( - request.query?.checkAvailableUpdates === 'true', + request.query?.query_api === 'true', + request.query?.force_query === 'true', ); return response.ok({ body: updates, diff --git a/plugins/wazuh-check-updates/server/services/updates/get-updates.ts b/plugins/wazuh-check-updates/server/services/updates/get-updates.ts index 7f1cf39312..9c8c190014 100644 --- a/plugins/wazuh-check-updates/server/services/updates/get-updates.ts +++ b/plugins/wazuh-check-updates/server/services/updates/get-updates.ts @@ -7,10 +7,15 @@ import { SAVED_OBJECT_UPDATES } from '../../../common/constants'; import { getSavedObject, setSavedObject } from '../saved-object'; import { getWazuhCore } from '../../plugin-services'; -export const getUpdates = async (checkAvailableUpdates?: boolean): Promise => { +export const getUpdates = async ( + queryApi = false, + forceQuery = false, +): Promise => { try { - if (!checkAvailableUpdates) { - const availableUpdates = (await getSavedObject(SAVED_OBJECT_UPDATES)) as AvailableUpdates; + if (!queryApi) { + const availableUpdates = (await getSavedObject( + SAVED_OBJECT_UPDATES, + )) as AvailableUpdates; return availableUpdates; } @@ -21,13 +26,14 @@ export const getUpdates = async (checkAvailableUpdates?: boolean): Promise { + hosts?.map(async api => { const data = {}; const method = 'GET'; - const path = '/manager/version/check?force_query=true'; + const path = `/manager/version/check?force_query=${forceQuery}`; const options = { apiHostID: api.id, forceRefresh: true, @@ -37,7 +43,7 @@ export const getUpdates = async (checkAvailableUpdates?: boolean): Promise Date: Tue, 30 Jan 2024 16:04:36 -0300 Subject: [PATCH 26/64] Fix vulnerability detector event filter (#6346) * Changed hideCloseButtons modules-helper method * Activation of non-implicit filters is improved * Add CHANGELOG * Fixed isImplicit filters on hideCloseButtons --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + .../common/modules/modules-helper.js | 170 +++++++++++++----- .../use_search_bar_configuration.tsx | 1 + plugins/main/public/utils/filter-handler.js | 47 ++--- 4 files changed, 153 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8ed96f6d5..282cba069b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed unnecessary scrolling in Vulnerability Inventory table [#6345](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6345) - Fixed wrong value at server stat Archives queue usage [#6342](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6342) - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) +- Fixed implicit filter close button in the search bar [#6346](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6346) - Fixed the help menu, to be consistent and avoid duplication [#6374](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6374) ### Removed diff --git a/plugins/main/public/components/common/modules/modules-helper.js b/plugins/main/public/components/common/modules/modules-helper.js index 4482664952..91ebc10f87 100644 --- a/plugins/main/public/components/common/modules/modules-helper.js +++ b/plugins/main/public/components/common/modules/modules-helper.js @@ -1,11 +1,13 @@ import { getAngularModule, getDataPlugin } from '../../../kibana-services'; +import { AppState } from '../../../react-services/app-state'; +import { FilterHandler } from '../../../utils/filter-handler'; export class ModulesHelper { static async getDiscoverScope() { const $injector = getAngularModule().$injector; const location = $injector.get('$location'); const initialTab = location.search().tab; - return new Promise((resolve) => { + return new Promise(resolve => { const checkExist = setInterval(() => { const app = getAngularModule(); if (app.discoverScope) { @@ -21,9 +23,11 @@ export class ModulesHelper { } static async cleanAvailableFields() { - const fields = document.querySelectorAll(`.dscFieldChooser .dscFieldList--unpopular li`); + const fields = document.querySelectorAll( + `.dscFieldChooser .dscFieldList--unpopular li`, + ); if (fields.length) { - fields.forEach((field) => { + fields.forEach(field => { const attr = field.getAttribute('data-attr-field'); if (attr.startsWith('_')) { field.style.display = 'none'; @@ -36,53 +40,133 @@ export class ModulesHelper { this.activeNoImplicitsFilters(); }; - static activeNoImplicitsFilters() { + static async activeNoImplicitsFilters(generatedImplicitFilters) { const { filterManager } = getDataPlugin().query; - const implicitFilters = filterManager.getFilters().filter((x) => { - return x.$state.isImplicit; - }); - if (!(implicitFilters || []).length) { + const filters = filterManager.getFilters(); + const implicitFilters = generatedImplicitFilters + ? generatedImplicitFilters + : filters.filter(filter => filter.$state.isImplicit); + + /* + Since the OSD filter definition does not include the "isImplicit" attribute that Wazuh adds, there may be cases where the "isImplicit" attribute is lost, since any action regarding filters that is done with the filterManager ( addFilters, setFilters, setGlobalFilters, setAppFilters) does a mapAndFlattenFilters mapping to the filters that removes any attributes that are not part of the filter definition. +If this case happens, the implicit filters are regenerated and the function is called again with the generated implicit filters. + */ + if (implicitFilters.length === 0) { + const generatedImplicitFilters = ModulesHelper.getImplicitFilter(); setTimeout(() => { - this.activeNoImplicitsFilters(); + this.activeNoImplicitsFilters(generatedImplicitFilters); }, 100); + return; } - // With the filter classes decide if they are from the module view or not + + this.processFilters(implicitFilters); + } + + static processFilters(filters) { const allFilters = $(`.globalFilterItem .euiBadge__childButton`); - for (let i = 0; i < allFilters.length; i++) { - const data = allFilters[i].attributes['data-test-subj']; - let found = false; - (implicitFilters || []).forEach((moduleFilter) => { - // Checks if the filter is already in use - // Check which of the filters are from the module view and which are not pinned filters - if (!moduleFilter.used) { - const objKey = moduleFilter.query?.match - ? Object.keys(moduleFilter.query.match)[0] - : moduleFilter.meta.key; - const objValue = moduleFilter.query?.match - ? moduleFilter.query.match[objKey].query - : moduleFilter.meta.value; - const key = `filter-key-${objKey}`; - const value = `filter-value-${objValue}`; - - const noExcludedValues = - !data.value.includes('filter-pinned') && !data.value.includes('filter-negated'); - const acceptedValues = data.value.includes(key) && data.value.includes(value); - - if (acceptedValues && noExcludedValues) { - found = true; - moduleFilter.used = true; - } + + allFilters.each((_index, filter) => { + const data = filter.attributes['data-test-subj']; + + /* With the filter classes decide if they are from the module view or not */ + const isImplicitFilter = this.checkFilterValues(data, filters); + + this.updateFilterState(isImplicitFilter, filter); + }); + } + + static checkFilterValues(data, filters) { + /* + Checks if the filter is already in use + Check which of the filters are from the module view and which are not pinned filters + */ + for (const moduleFilter of filters) { + if (!moduleFilter.used) { + const { objKey, objValue } = this.extractKeyAndValue(moduleFilter); + + const noExcludedValues = + !data.value.includes('filter-pinned') && + !data.value.includes('filter-negated'); + const acceptedValues = + data.value.includes(`filter-key-${objKey}`) && + data.value.includes(`filter-value-${objValue}`); + + if (acceptedValues && noExcludedValues) { + moduleFilter.used = true; + return true; } - }); - if (!found) { - $(allFilters[i]).siblings('.euiBadge__iconButton').removeClass('hide-close-button'); - $(allFilters[i]).off('click'); - } else { - $(allFilters[i]).siblings('.euiBadge__iconButton').addClass('hide-close-button'); - $(allFilters[i]).on('click', (ev) => { - ev.stopPropagation(); - }); } } + return false; + } + + static extractKeyAndValue(moduleFilter) { + const objKey = moduleFilter.query?.match + ? Object.keys(moduleFilter.query.match)[0] + : moduleFilter.meta.key; + const objValue = moduleFilter.query?.match + ? moduleFilter.query.match[objKey].query + : moduleFilter.meta.value; + + return { objKey, objValue }; + } + + static updateFilterState(isImplicitFilter, filter) { + const closeButton = $(filter).siblings('.euiBadge__iconButton'); + if (!isImplicitFilter) { + closeButton.removeClass('hide-close-button'); + $(filter).off('click'); + } else { + closeButton.addClass('hide-close-button'); + $(filter).on('click', ev => ev.stopPropagation()); + } + } + + static getImplicitFilter() { + const tabFilters = { + general: { group: '' }, + welcome: { group: '' }, + fim: { group: 'syscheck' }, + pm: { group: 'rootcheck' }, + vuls: { group: 'vulnerability-detector' }, + oscap: { group: 'oscap' }, + ciscat: { group: 'ciscat' }, + audit: { group: 'audit' }, + pci: { group: 'pci_dss' }, + gdpr: { group: 'gdpr' }, + hipaa: { group: 'hipaa' }, + nist: { group: 'nist' }, + tsc: { group: 'tsc' }, + aws: { group: 'amazon' }, + gcp: { group: 'gcp' }, + office: { group: 'office365' }, + virustotal: { group: 'virustotal' }, + osquery: { group: 'osquery' }, + sca: { group: 'sca' }, + docker: { group: 'docker' }, + github: { group: 'github' }, + }; + const filterHandler = new FilterHandler(AppState.getCurrentPattern()); + const filters = []; + const isCluster = AppState.getClusterInfo().status == 'enabled'; + filters.push( + filterHandler.managerQuery( + isCluster + ? AppState.getClusterInfo().cluster + : AppState.getClusterInfo().manager, + isCluster, + ), + ); + filters.push(filterHandler.pciQuery()); + filters.push(filterHandler.gdprQuery()); + filters.push(filterHandler.hipaaQuery()); + filters.push(filterHandler.nistQuery()); + filters.push(filterHandler.tscQuery()); + filters.push(filterHandler.mitreQuery()); + Object.keys(tabFilters).forEach(tab => { + filters.push(filterHandler.ruleGroupQuery(tabFilters[tab].group)); + }); + + return filters; } } diff --git a/plugins/main/public/components/overview/vulnerabilities/search_bar/use_search_bar_configuration.tsx b/plugins/main/public/components/overview/vulnerabilities/search_bar/use_search_bar_configuration.tsx index 06e4bb7648..d9e6452fda 100644 --- a/plugins/main/public/components/overview/vulnerabilities/search_bar/use_search_bar_configuration.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/search_bar/use_search_bar_configuration.tsx @@ -76,6 +76,7 @@ const useSearchBarConfiguration = ( const previousFilters = JSON.parse(storagePreviousFilters); const cleanedFilters = cleanFilters(previousFilters); filterManager.setFilters(cleanedFilters); + sessionStorage.removeItem(SESSION_STORAGE_FILTERS_NAME); } }; }, []); diff --git a/plugins/main/public/utils/filter-handler.js b/plugins/main/public/utils/filter-handler.js index 7bbe688692..29c7e210af 100644 --- a/plugins/main/public/utils/filter-handler.js +++ b/plugins/main/public/utils/filter-handler.js @@ -27,15 +27,16 @@ export class FilterHandler { value: null, params: { query: null, - type: 'phrase' - } + type: 'phrase', + }, }, query: { - match: null + match: null, }, $state: { - store: 'appState' - } + store: 'appState', + isImplicit: true, + }, }; } @@ -47,8 +48,8 @@ export class FilterHandler { result.query.match = { 'agent.id': { query: agent, - type: 'phrase' - } + type: 'phrase', + }, }; return result; } @@ -61,8 +62,8 @@ export class FilterHandler { result.query.match = { 'cluster.node': { query: node, - type: 'phrase' - } + type: 'phrase', + }, }; return result; } @@ -75,8 +76,8 @@ export class FilterHandler { result.query.match = { 'rule.groups': { query: group, - type: 'phrase' - } + type: 'phrase', + }, }; return result; } @@ -90,8 +91,8 @@ export class FilterHandler { result.query.match = { 'rule.id': { query: ruleId, - type: 'phrase' - } + type: 'phrase', + }, }; return result; } @@ -105,14 +106,14 @@ export class FilterHandler { ? { 'cluster.name': { query: manager, - type: 'phrase' - } + type: 'phrase', + }, } : { 'manager.name': { query: manager, - type: 'phrase' - } + type: 'phrase', + }, }; return result; } @@ -123,7 +124,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.pci_dss'; result.exists = { - field: 'rule.pci_dss' + field: 'rule.pci_dss', }; delete result.query; return result; @@ -135,7 +136,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.gdpr'; result.exists = { - field: 'rule.gdpr' + field: 'rule.gdpr', }; delete result.query; return result; @@ -147,7 +148,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.hipaa'; result.exists = { - field: 'rule.hipaa' + field: 'rule.hipaa', }; delete result.query; return result; @@ -159,7 +160,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.nist_800_53'; result.exists = { - field: 'rule.nist_800_53' + field: 'rule.nist_800_53', }; delete result.query; return result; @@ -171,7 +172,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.tsc'; result.exists = { - field: 'rule.tsc' + field: 'rule.tsc', }; delete result.query; return result; @@ -183,7 +184,7 @@ export class FilterHandler { result.meta.value = 'exists'; result.meta.key = 'rule.mitre.id'; result.exists = { - field: 'rule.mitre.id' + field: 'rule.mitre.id', }; delete result.query; return result; From a0e4c865d192a962c8b275cf5050a677857d17c9 Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Thu, 1 Feb 2024 16:34:38 +0100 Subject: [PATCH 27/64] Fix axis label from dashboards (#6378) * Fixed axis label form dashboards * Add changelog * Version tab in agent table change his width to 10% * Snaps reloaded --- CHANGELOG.md | 1 + .../__snapshots__/agent-table.test.tsx.snap | 3 +++ .../controllers/agent/components/agents-table.js | 1 + plugins/main/public/styles/layout.scss | 16 +++++----------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 282cba069b..a0a7c0751d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed the inventory data table when maximized and the docked menu [#6344](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6344) - Fixed implicit filter close button in the search bar [#6346](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6346) - Fixed the help menu, to be consistent and avoid duplication [#6374](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6374) +- Fixed the axis label visual bug from dashboards [#6378](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6378) ### Removed diff --git a/plugins/main/public/controllers/agent/components/__snapshots__/agent-table.test.tsx.snap b/plugins/main/public/controllers/agent/components/__snapshots__/agent-table.test.tsx.snap index c13fb6e2cd..b98d6c7eec 100644 --- a/plugins/main/public/controllers/agent/components/__snapshots__/agent-table.test.tsx.snap +++ b/plugins/main/public/controllers/agent/components/__snapshots__/agent-table.test.tsx.snap @@ -469,6 +469,7 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` data-test-subj="tableHeaderCell_version_6" role="columnheader" scope="col" + style="width:10%" >

@@ -67,12 +68,13 @@ exports[`Stats component renders correctly to match the snapshot 1`] = ` - - - +

@@ -107,7 +109,7 @@ exports[`Stats component renders correctly to match the snapshot 1`] = ` class="euiLink euiLink--primary statWithLink" href="" rel="noreferrer" - style="font-weight: normal;" + style="font-weight: normal; color: rgb(0, 120, 113);" > - diff --git a/plugins/main/public/controllers/overview/components/last-alerts-stat/last-alerts-stat.tsx b/plugins/main/public/controllers/overview/components/last-alerts-stat/last-alerts-stat.tsx index f493d8535b..950e659e15 100644 --- a/plugins/main/public/controllers/overview/components/last-alerts-stat/last-alerts-stat.tsx +++ b/plugins/main/public/controllers/overview/components/last-alerts-stat/last-alerts-stat.tsx @@ -46,7 +46,10 @@ export function LastAlertsStat() { {countLastAlerts ?? '-'} diff --git a/plugins/main/public/controllers/overview/components/stats.js b/plugins/main/public/controllers/overview/components/stats.js index a14758e3f3..6701993a02 100644 --- a/plugins/main/public/controllers/overview/components/stats.js +++ b/plugins/main/public/controllers/overview/components/stats.js @@ -18,6 +18,7 @@ import { EuiFlexGroup, EuiPage, EuiToolTip, + EuiLink, } from '@elastic/eui'; import { withErrorBoundary } from '../../../components/common/hocs'; import { API_NAME_AGENT_STATUS } from '../../../../common/constants'; @@ -56,7 +57,7 @@ export const Stats = withErrorBoundary( sessionStorage.removeItem('wz-agents-overview-table-filter'); } getCore().application.navigateToApp(endpointSummary.id, { - path: '#/agents-preview', + path: `#${endpointSummary.redirectTo()}`, }); } @@ -81,15 +82,15 @@ export const Stats = withErrorBoundary( position='top' content={`Go to ${label.toLowerCase()} agents`} > - {typeof this.props[status] !== 'undefined' ? this.props[status] : '-'} - + } description={`${label} agents`} From ac505175946cc3c4b64db550e445522d7b300f88 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:56:52 +0100 Subject: [PATCH 35/64] Replace discover AWS (#6288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace discover * Update CHANGELOG.md * Fix CHANGELOG * Change styles * Replace hook with wazuhCore hook --------- Co-authored-by: Julio César Biset <43619595+jbiset@users.noreply.github.com> Co-authored-by: jbiset Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- .../common/doc-viewer/doc-viewer.tsx | 17 ++++++---------- .../public/components/common/hooks/index.ts | 1 - .../common/hooks/useDockedSideNav.tsx | 20 ------------------- .../common/modules/modules-defaults.js | 6 +++++- .../common/wazuh-discover/wz-discover.tsx | 4 ++-- .../events/amazon-web-services-columns.tsx | 16 +++++++++++++++ 7 files changed, 30 insertions(+), 36 deletions(-) delete mode 100644 plugins/main/public/components/common/hooks/useDockedSideNav.tsx create mode 100644 plugins/main/public/components/overview/amazon-web-services/events/amazon-web-services-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e69f1130e..d46e33536d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) diff --git a/plugins/main/public/components/common/doc-viewer/doc-viewer.tsx b/plugins/main/public/components/common/doc-viewer/doc-viewer.tsx index c7ce052e16..70315ae2fc 100644 --- a/plugins/main/public/components/common/doc-viewer/doc-viewer.tsx +++ b/plugins/main/public/components/common/doc-viewer/doc-viewer.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import { escapeRegExp } from 'lodash'; import { i18n } from '@osd/i18n'; import { FieldIcon } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; const COLLAPSE_LINE_LENGTH = 350; const DOT_PREFIX_RE = /(.).+?\./g; @@ -134,15 +134,10 @@ const DocViewer = (props: tDocViewerProps) => { {...fieldIconProps} /> - - - {displayName} - + + + {displayName} + @@ -156,7 +151,7 @@ const DocViewer = (props: tDocViewerProps) => { */ // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: value as string }} - style={{ overflowY: 'auto' }} + style={{ overflowY: 'auto', wordBreak: 'break-all' }} /> diff --git a/plugins/main/public/components/common/hooks/index.ts b/plugins/main/public/components/common/hooks/index.ts index a4cd7dbf91..e3ce7584c7 100644 --- a/plugins/main/public/components/common/hooks/index.ts +++ b/plugins/main/public/components/common/hooks/index.ts @@ -28,4 +28,3 @@ export * from './use_async_action_run_on_start'; export { useEsSearch } from './use-es-search'; export { useValueSuggestion, IValueSuggestion } from './use-value-suggestion'; export * from './use-state-storage'; -export * from './useDockedSideNav'; diff --git a/plugins/main/public/components/common/hooks/useDockedSideNav.tsx b/plugins/main/public/components/common/hooks/useDockedSideNav.tsx deleted file mode 100644 index 489536b4d6..0000000000 --- a/plugins/main/public/components/common/hooks/useDockedSideNav.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect, useState } from 'react'; -import { getChrome } from '../../../kibana-services'; - -export const useDockedSideNav = () => { - const [sideNavDocked, setSideNavDocked] = useState(false); - - useEffect(() => { - const isNavDrawerSubscription = getChrome() - .getIsNavDrawerLocked$() - .subscribe((value: boolean) => { - setSideNavDocked(value); - }); - - return () => { - isNavDrawerSubscription.unsubscribe(); - }; - }, []); - - return sideNavDocked; -}; diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index 41f5391fe3..eacc114770 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -27,6 +27,7 @@ import { vulnerabilitiesColumns } from '../../overview/vulnerabilities/events/vu import { DashboardFim } from '../../overview/fim/dashboard/dashboard'; import { InventoryFim } from '../../overview/fim/inventory/inventory'; import React from 'react'; +import { amazonWebServicesColumns } from '../../overview/amazon-web-services/events/amazon-web-services-columns'; import { office365Columns } from '../../overview/office-panel/events/office-365-columns'; import { fileIntegrityMonitoringColumns } from '../../overview/fim/events/file-integrity-monitoring-columns'; import { configurationAssessmentColumns } from '../../agents/sca/events/configuration-assessment-columns'; @@ -99,7 +100,10 @@ export const ModulesDefaults = { }, aws: { init: 'dashboard', - tabs: [DashboardTab, EventsTab], + tabs: [ + DashboardTab, + renderDiscoverTab(DEFAULT_INDEX_PATTERN, amazonWebServicesColumns), + ], availableFor: ['manager', 'agent'], }, gcp: { diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index 8b72bb01e4..0eec91a272 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -37,7 +37,7 @@ import useSearchBar from '../search-bar/use-search-bar'; import { search } from '../search-bar'; import { getPlugins } from '../../../kibana-services'; import { histogramChartInput } from './config/histogram-chart'; -import { useDockedSideNav } from '../hooks/useDockedSideNav'; +import { getWazuhCorePlugin } from '../../../kibana-services'; const DashboardByRenderer = getPlugins().dashboard.DashboardContainerByValueRenderer; import './discover.scss'; @@ -60,7 +60,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { ); const [isSearching, setIsSearching] = useState(false); const [isExporting, setIsExporting] = useState(false); - const sideNavDocked = useDockedSideNav(); + const sideNavDocked = getWazuhCorePlugin().hooks.useDockedSideNav(); const onClickInspectDoc = useMemo( () => (index: number) => { diff --git a/plugins/main/public/components/overview/amazon-web-services/events/amazon-web-services-columns.tsx b/plugins/main/public/components/overview/amazon-web-services/events/amazon-web-services-columns.tsx new file mode 100644 index 0000000000..f8a901f748 --- /dev/null +++ b/plugins/main/public/components/overview/amazon-web-services/events/amazon-web-services-columns.tsx @@ -0,0 +1,16 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const amazonWebServicesColumns: tDataGridColumn[] = [ + { + id: 'data.aws.source', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; From 0d95e5591c607ee912c29d67c65373bcf9e4c17c Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:37:13 +0100 Subject: [PATCH 36/64] Check the existence of the index pattern of vulnerabilities states in Vulnerabilities Detection tabs (#6405) * feat: add withGuardAsync HOC * feat(vulnerabilities): add the usage of HOC in the Vulnerabilities Detection tabs - Add the usage of HOC in the Vulnerabilities Detection to check if the index pattern exist or try to create if exist matching indices: - Dashboard - Inventory - Events - Add a callout to the Dashboard and Inventory tabs of Vulnerabilities Detection module that displays a warning message about the module is not enabled. * fix(vulnerabilities): property in the API response related to module is enabled * feat(vulnerabilities): remove the check existence of the index pattern in the Dashboard and Inventory tab * changelog: add entry * fix(vulnerabilities): fix typo * fix(vulnerabilities): fix documentation URL * fix(workaround): refresh the page when the wazuh-vulnerabilities-states index pattern is created This solves a problem of there are not implicit filters on the Events tab of Vulnerabilities Detection application if the HOC is passed and the filters could not be set when unmounting Dashboard or Event tabs due to the protection of the HOC that checks the existence of the index pattern. * Fix request * feat: add loading effect to vulnerabilities check index HOC - Create LoadingSpinnerDataSource * fix: loading spinner data source styles * fix: double request on Vulnerabilities Detection > Inventory --------- Co-authored-by: Ian Yenien Serrano --- CHANGELOG.md | 2 +- .../components/common/hocs/withGuard.tsx | 68 +++++- .../loading/loading-spinner-data-source.tsx | 36 ++++ .../common/modules/modules-defaults.js | 3 +- .../components/check-module-enabled.tsx | 115 +++++++++++ ...e-vulnerabilities-states-index-pattern.tsx | 169 +++++++++++++++ .../dashboards/inventory/inventory.tsx | 195 +++++++++--------- .../dashboards/overview/dashboard.tsx | 42 ++-- 8 files changed, 494 insertions(+), 136 deletions(-) create mode 100644 plugins/main/public/components/common/loading/loading-spinner-data-source.tsx create mode 100644 plugins/main/public/components/overview/vulnerabilities/common/components/check-module-enabled.tsx create mode 100644 plugins/main/public/components/overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d548f3328..9419d05659 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/public/components/common/hocs/withGuard.tsx b/plugins/main/public/components/common/hocs/withGuard.tsx index 1a2c689f5e..e29d42ba7a 100644 --- a/plugins/main/public/components/common/hocs/withGuard.tsx +++ b/plugins/main/public/components/common/hocs/withGuard.tsx @@ -9,8 +9,68 @@ * * Find more information about this on the LICENSE file. */ -import React from 'react'; +import React, { useEffect, useState } from 'react'; -export const withGuard = (condition, ComponentFulfillsCondition) => WrappedComponent => props => { - return condition(props) ? : -} \ No newline at end of file +export const withGuard = + (condition: (props: any) => boolean, ComponentFulfillsCondition) => + WrappedComponent => + props => { + return condition(props) ? ( + + ) : ( + + ); + }; + +export const withGuardAsync = + ( + condition: (props: any) => { ok: boolean; data: any }, + ComponentFulfillsCondition: React.JSX.Element, + ComponentLoadingResolution: null | React.JSX.Element = null, + ) => + WrappedComponent => + props => { + const [loading, setLoading] = useState(true); + const [fulfillsCondition, setFulfillsCondition] = useState({ + ok: false, + data: {}, + }); + + const execCondition = async () => { + try { + setLoading(true); + setFulfillsCondition({ ok: false, data: {} }); + setFulfillsCondition( + await condition({ ...props, check: execCondition }), + ); + } catch (error) { + setFulfillsCondition({ ok: false, data: { error } }); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + execCondition(); + }, []); + + if (loading) { + return ComponentLoadingResolution ? ( + + ) : null; + } + + return fulfillsCondition.ok ? ( + + ) : ( + + ); + }; diff --git a/plugins/main/public/components/common/loading/loading-spinner-data-source.tsx b/plugins/main/public/components/common/loading/loading-spinner-data-source.tsx new file mode 100644 index 0000000000..36c4b49930 --- /dev/null +++ b/plugins/main/public/components/common/loading/loading-spinner-data-source.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { + EuiTitle, + EuiPanel, + EuiEmptyPrompt, + EuiLoadingSpinner, +} from '@elastic/eui'; +import { FormattedMessage } from '@osd/i18n/react'; +import { IntlProvider } from 'react-intl'; + +export function LoadingSpinnerDataSource() { + return ( + + + } + title={ + +

+ +

+
+ } + /> +
+
+ ); +} diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index 942f3b92e1..22105127e2 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -24,6 +24,7 @@ import { DashboardVuls, InventoryVuls } from '../../overview/vulnerabilities'; import { withModuleNotForAgent } from '../hocs'; import React from 'react'; import { WAZUH_VULNERABILITIES_PATTERN } from '../../../../common/constants'; +import { withVulnerabilitiesStateDataSource } from '../../overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern'; const DashboardTab = { id: 'dashboard', @@ -177,7 +178,7 @@ export const ModulesDefaults = { ), ], }, - EventsTab, + { ...EventsTab, component: withVulnerabilitiesStateDataSource(Events) }, ], buttons: ['settings'], availableFor: ['manager', 'agent'], diff --git a/plugins/main/public/components/overview/vulnerabilities/common/components/check-module-enabled.tsx b/plugins/main/public/components/overview/vulnerabilities/common/components/check-module-enabled.tsx new file mode 100644 index 0000000000..f254dbde95 --- /dev/null +++ b/plugins/main/public/components/overview/vulnerabilities/common/components/check-module-enabled.tsx @@ -0,0 +1,115 @@ +import React, { useEffect, useState } from 'react'; +import { + clusterReq, + clusterNodes, +} from '../../../../../controllers/management/components/management/configuration/utils/wz-fetch'; +import { WzRequest } from '../../../../../react-services'; +import { webDocumentationLink } from '../../../../../../common/services/web_documentation'; +import { EuiCallOut, EuiLink } from '@elastic/eui'; +import { UI_LOGGER_LEVELS } from '../../../../../../common/constants'; +import { UI_ERROR_SEVERITIES } from '../../../../../react-services/error-orchestrator/types'; +import { getErrorOrchestrator } from '../../../../../react-services/common-services'; +import { useUserPermissionsRequirements } from '../../../../common/hooks'; + +async function checkVDIsEnabledCluster() { + // Get nodes + const responseNodes = await clusterNodes(); + + const nodes = responseNodes.data.data.affected_items.map(({ name }) => name); + + // Check if at least some of the nodes has the module enabled + for (const node of nodes) { + const responseNodeWmodules = await WzRequest.apiReq( + 'GET', + `/cluster/${node}/configuration/wmodules/wmodules`, + {}, + ); + const vdConfiguration = + responseNodeWmodules.data.data?.affected_items?.[0]?.wmodules?.find( + ({ ['vulnerability-detection']: wmodule }) => wmodule, + ); + if (vdConfiguration?.['vulnerability-detection']?.enabled === 'yes') { + return true; + } + } + return false; +} + +async function checkVDIsEnabledManager() { + const responseWmodules = await WzRequest.apiReq( + 'GET', + `/manager/configuration/wmodules/wmodules`, + {}, + ); + + const vdConfiguration = + responseWmodules.data.data?.affected_items?.[0]?.wmodules?.find( + ({ ['vulnerability-detection']: wmodule }) => wmodule, + ); + return vdConfiguration?.['vulnerability-detection']?.enabled === 'yes'; +} + +export const ModuleEnabledCheck = () => { + const [data, setData] = useState<{ enabled: boolean } | null>(null); + const [userPermissionRequirements] = useUserPermissionsRequirements([ + { action: 'cluster:status', resource: '*:*:*' }, + { action: 'cluster:read', resource: 'node:id:*' }, + { action: 'manager:read', resource: '*:*:*' }, + ]); + + const checkVDIsEnabled = async () => { + try { + // Check cluster status + setData(null); + const clusterStatus = await clusterReq(); + + // Check if the module is enabled + const enabled = + clusterStatus.data.data.enabled === 'yes' && + clusterStatus.data.data.running === 'yes' + ? await checkVDIsEnabledCluster() + : await checkVDIsEnabledManager(); + setData({ enabled }); + } catch (error) { + const options = { + context: `${ModuleEnabledCheck.name}.useEffect`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.BUSINESS, + error: { + error: error, + message: error.message || error, + title: 'Error checking if the module is enabled', + }, + }; + getErrorOrchestrator().handleError(options); + } + }; + + useEffect(() => { + /* Only check if the module is enabled if the user has the expected permissions to + do the API requests */ + if (!userPermissionRequirements) { + checkVDIsEnabled(); + } + }, [userPermissionRequirements]); + + return data?.enabled === false ? ( + +

+ Vulnerabilies detection module is not enabled. You can learn to how to + configure following the{' '} + + documentation + + . +

+
+ ) : null; +}; diff --git a/plugins/main/public/components/overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern.tsx b/plugins/main/public/components/overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern.tsx new file mode 100644 index 0000000000..c021ace475 --- /dev/null +++ b/plugins/main/public/components/overview/vulnerabilities/common/hocs/validate-vulnerabilities-states-index-pattern.tsx @@ -0,0 +1,169 @@ +import React from 'react'; +import { compose } from 'redux'; +import { connect } from 'react-redux'; +import { withGuardAsync, withReduxProvider } from '../../../../common/hocs'; +import { + getAngularModule, + getCore, + getSavedObjects, +} from '../../../../../kibana-services'; +import { SavedObject } from '../../../../../react-services'; +import { NOT_TIME_FIELD_NAME_INDEX_PATTERN } from '../../../../../../common/constants'; +import { EuiButton, EuiEmptyPrompt, EuiLink } from '@elastic/eui'; +import { webDocumentationLink } from '../../../../../../common/services/web_documentation'; +import { vulnerabilityDetection } from '../../../../../utils/applications'; +import { LoadingSpinnerDataSource } from '../../../../common/loading/loading-spinner-data-source'; + +const INDEX_PATTERN_CREATION_NO_INDEX = 'INDEX_PATTERN_CREATION_NO_INDEX'; + +async function checkExistenceIndexPattern(indexPatternID: string) { + const response = await getSavedObjects().client.get( + 'index-pattern', + indexPatternID, + ); + + return response?.error?.statusCode !== 404; +} + +async function checkExistenceIndices(indexPatternTitle: string) { + try { + const fields = await SavedObject.getIndicesFields(indexPatternTitle); + return { exist: true, fields }; + } catch (error) { + return { exist: false }; + } +} + +async function createIndexPattern(indexPattern, fields: any) { + try { + await SavedObject.createSavedObject( + 'index-pattern', + indexPattern, + { + attributes: { + title: indexPattern, + timeFieldName: NOT_TIME_FIELD_NAME_INDEX_PATTERN, + }, + }, + fields, + ); + await SavedObject.validateIndexPatternSavedObjectCanBeFound([indexPattern]); + } catch (error) { + return { error: error.message }; + } +} + +export async function validateVulnerabilitiesStateDataSources({ + vulnerabilitiesStatesindexPatternID: indexPatternID, +}) { + try { + // Check the existence of related index pattern + const existIndexPattern = await checkExistenceIndexPattern(indexPatternID); + + // If the idnex pattern does not exist, then check the existence of index + if (!existIndexPattern) { + // Check the existence of indices + const { exist, fields } = await checkExistenceIndices(indexPatternID); + + if (!exist) { + return { + ok: true, + data: { + error: { + title: + 'Vulnerability detection seems to be disabled or has a problem', + type: INDEX_PATTERN_CREATION_NO_INDEX, + }, + }, + }; + } + // If the some index match the index pattern, then create the index pattern + const resultCreateIndexPattern = await createIndexPattern( + indexPatternID, + fields, + ); + if (resultCreateIndexPattern?.error) { + return { + ok: true, + data: { + error: { + title: 'There was a problem creating the index pattern', + message: resultCreateIndexPattern?.error, + }, + }, + }; + } + /* WORKAROUND: Redirect to the root of Vulnerabilities Detection application that should + redirects to the Dashboard tab. We want to redirect to this view, because we need the + component is visible (visualizations) to ensure the process that defines the filters for the + Events tab is run when the Dashboard component is unmounted. This workaround solves a + problem in the Events tabs related there are no implicit filters when accessing if the HOC + that protect the view is passed. + */ + getCore().application.navigateToApp(vulnerabilityDetection.id); + } + return { + ok: false, + data: {}, + }; + } catch (error) { + return { + ok: true, + data: { + error: { title: 'There was a problem', message: error.message }, + }, + }; + } +} + +const errorPromptBody = { + INDEX_PATTERN_CREATION_NO_INDEX: ( +

+ Please check the cluster status. Also, you can check the{' '} + + vulnerability detection documentation. + +

+ ), +}; + +export const PromptCheckIndex = props => { + const { refresh } = props; + const { title, message } = props?.error; + const body = errorPromptBody?.[props?.error?.type] ||

{message}

; + + return ( + {title}} + body={body} + actions={ + + Refresh + + } + /> + ); +}; + +const mapStateToProps = state => ({ + vulnerabilitiesStatesindexPatternID: + state.appConfig.data['vulnerabilities.pattern'], +}); + +export const withVulnerabilitiesStateDataSource = compose( + withReduxProvider, + connect(mapStateToProps), + withGuardAsync( + validateVulnerabilitiesStateDataSources, + ({ error, check }) => , + () => , + ), +); diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index aef216431c..1a51c2b282 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -35,13 +35,14 @@ import { withErrorBoundary } from '../../../../common/hocs'; import { HitsCounter } from '../../../../../kibana-integrations/discover/application/components/hits_counter/hits_counter'; import { formatNumWithCommas } from '../../../../../kibana-integrations/discover/application/helpers'; import { useAppConfig } from '../../../../common/hooks'; -import { WAZUH_INDEX_TYPE_VULNERABILITIES } from '../../../../../../common/constants'; -import useCheckIndexFields from '../../common/hooks/useCheckIndexFields'; import { vulnerabilityIndexFiltersAdapter, onUpdateAdapter, restorePrevIndexFiltersAdapter, } from '../../common/vulnerability_detector_adapters'; +import { compose } from 'redux'; +import { withVulnerabilitiesStateDataSource } from '../../common/hocs/validate-vulnerabilities-states-index-pattern'; +import { ModuleEnabledCheck } from '../../common/components/check-module-enabled'; const InventoryVulsComponent = () => { const appConfig = useAppConfig(); @@ -103,18 +104,8 @@ const InventoryVulsComponent = () => { indexPattern: indexPattern as IndexPattern, }); - const { - isError, - error, - isSuccess, - isLoading: isLoadingCheckIndex, - } = useCheckIndexFields( - VULNERABILITIES_INDEX_PATTERN_ID, - WAZUH_INDEX_TYPE_VULNERABILITIES, - ); - useEffect(() => { - if (!isLoading && isSuccess) { + if (!isLoading) { setIndexPattern(indexPatterns?.[0] as IndexPattern); search({ indexPattern: indexPatterns?.[0] as IndexPattern, @@ -140,7 +131,6 @@ const InventoryVulsComponent = () => { JSON.stringify(searchBarProps), JSON.stringify(pagination), JSON.stringify(sorting), - isLoadingCheckIndex, ]); const onClickExportResults = async () => { @@ -171,96 +161,95 @@ const InventoryVulsComponent = () => { return ( - - <> - {isLoading || isLoadingCheckIndex ? ( - - ) : ( - - )} - {isSearching ? : null} - {!isLoadingCheckIndex && - !isLoading && - !isSearching && - (isError || results?.hits?.total === 0) ? ( - - ) : null} - {!isLoadingCheckIndex && - !isLoading && - !isSearching && - isSuccess && - results?.hits?.total > 0 ? ( - - {}} - tooltip={ - results?.hits?.total && - results?.hits?.total > MAX_ENTRIES_PER_QUERY - ? { - ariaLabel: 'Warning', - content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( - MAX_ENTRIES_PER_QUERY, - )} hits.`, - iconType: 'alert', - position: 'top', - } - : undefined - } - /> - - Export Formated - - - ), - }} - /> - ) : null} - {inspectedHit && ( - setInspectedHit(undefined)} size='m'> - - -

Document details

-
-
- - - - - - - -
- )} - -
+ <> + + + <> + {isLoading ? ( + + ) : ( + + )} + {isSearching ? : null} + {!isLoading && !isSearching && results?.hits?.total === 0 ? ( + + ) : null} + {!isLoading && !isSearching && results?.hits?.total > 0 ? ( + + {}} + tooltip={ + results?.hits?.total && + results?.hits?.total > MAX_ENTRIES_PER_QUERY + ? { + ariaLabel: 'Warning', + content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( + MAX_ENTRIES_PER_QUERY, + )} hits.`, + iconType: 'alert', + position: 'top', + } + : undefined + } + /> + + Export Formated + + + ), + }} + /> + ) : null} + {inspectedHit && ( + setInspectedHit(undefined)} size='m'> + + +

Document details

+
+
+ + + + + + + +
+ )} + +
+
); }; -export const InventoryVuls = withErrorBoundary(InventoryVulsComponent); +export const InventoryVuls = compose( + withErrorBoundary, + withVulnerabilitiesStateDataSource, +)(InventoryVulsComponent); diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx index bdbd6bf054..c5443803c9 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx @@ -11,9 +11,7 @@ import { getKPIsPanel } from './dashboard_panels_kpis'; import { useAppConfig } from '../../../../common/hooks'; import { withErrorBoundary } from '../../../../common/hocs'; import { DiscoverNoResults } from '../../common/components/no_results'; -import { WAZUH_INDEX_TYPE_VULNERABILITIES } from '../../../../../../common/constants'; import { LoadingSpinner } from '../../common/components/loading_spinner'; -import useCheckIndexFields from '../../common/hooks/useCheckIndexFields'; import { vulnerabilityIndexFiltersAdapter, restorePrevIndexFiltersAdapter, @@ -26,6 +24,9 @@ import { ErrorHandler, HttpError, } from '../../../../../react-services/error-management'; +import { compose } from 'redux'; +import { withVulnerabilitiesStateDataSource } from '../../common/hocs/validate-vulnerabilities-states-index-pattern'; +import { ModuleEnabledCheck } from '../../common/components/check-module-enabled'; const plugins = getPlugins(); @@ -52,18 +53,8 @@ const DashboardVulsComponent: React.FC = () => { const [isSearching, setIsSearching] = useState(false); const [results, setResults] = useState({} as SearchResponse); - const { - isError, - error, - isSuccess, - isLoading: isLoadingCheckIndex, - } = useCheckIndexFields( - VULNERABILITIES_INDEX_PATTERN_ID, - WAZUH_INDEX_TYPE_VULNERABILITIES, - ); - useEffect(() => { - if (!isLoading && isSuccess) { + if (!isLoading) { search({ indexPattern: indexPatterns?.[0] as IndexPattern, filters, @@ -82,14 +73,15 @@ const DashboardVulsComponent: React.FC = () => { setIsSearching(false); }); } - }, [JSON.stringify(searchBarProps), isLoadingCheckIndex]); + }, [JSON.stringify(searchBarProps)]); return ( <> <> - {isLoading || isLoadingCheckIndex ? : null} - {!isLoading && !isLoadingCheckIndex ? ( + + {isLoading ? : null} + {!isLoading ? ( { /> ) : null} {isSearching ? : null} - {!isLoadingCheckIndex && - !isLoading && - !isSearching && - (isError || results?.hits?.total === 0) ? ( - + {!isLoading && !isSearching && results?.hits?.total === 0 ? ( + ) : null} - {!isLoadingCheckIndex && - !isLoading && - !isSearching && - isSuccess && - results?.hits?.total > 0 ? ( + {!isLoading && !isSearching && results?.hits?.total > 0 ? (
{ ); }; -export const DashboardVuls = withErrorBoundary(DashboardVulsComponent); +export const DashboardVuls = compose( + withErrorBoundary, + withVulnerabilitiesStateDataSource, +)(DashboardVulsComponent); From 4bdde789d4ae6cd03c83168079b7fa5a3e3b96bb Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Thu, 15 Feb 2024 18:51:21 +0100 Subject: [PATCH 37/64] Add manager filter with cluster mode disabled (#6410) * Add manager filter with cluster mode disabled * Add changelog --------- Co-authored-by: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> --- CHANGELOG.md | 2 +- plugins/main/common/constants.ts | 5 ++++- .../components/common/modules/modules-helper.js | 6 ++++-- .../common/vulnerability_detector_adapters.tsx | 16 ++++++++++++---- plugins/main/public/services/common-data.js | 8 ++++++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9419d05659..313686e0cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/common/constants.ts b/plugins/main/common/constants.ts index f78d27eba6..b6bf45e8df 100644 --- a/plugins/main/common/constants.ts +++ b/plugins/main/common/constants.ts @@ -51,7 +51,10 @@ export const WAZUH_STATISTICS_DEFAULT_CRON_FREQ = '0 */5 * * * *'; // Wazuh vulnerabilities export const WAZUH_VULNERABILITIES_PATTERN = 'wazuh-states-vulnerabilities'; export const WAZUH_INDEX_TYPE_VULNERABILITIES = 'vulnerabilities'; -export const VULNERABILITY_CLUSTER_KEY = 'wazuh.cluster.name'; +export const VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER = { + enabled: 'wazuh.cluster.name', + disabled: 'wazuh.manager.name', +}; // Job - Wazuh initialize export const WAZUH_PLUGIN_PLATFORM_TEMPLATE_NAME = 'wazuh-kibana'; diff --git a/plugins/main/public/components/common/modules/modules-helper.js b/plugins/main/public/components/common/modules/modules-helper.js index f2c8d34468..0443f4a40b 100644 --- a/plugins/main/public/components/common/modules/modules-helper.js +++ b/plugins/main/public/components/common/modules/modules-helper.js @@ -1,7 +1,7 @@ import { getAngularModule, getDataPlugin } from '../../../kibana-services'; import { AppState } from '../../../react-services/app-state'; import { FilterHandler } from '../../../utils/filter-handler'; -import { VULNERABILITY_CLUSTER_KEY } from '../../../../common/constants'; +import { VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER } from '../../../../common/constants'; export class ModulesHelper { static async getDiscoverScope() { @@ -165,7 +165,9 @@ If this case happens, the implicit filters are regenerated and the function is c ? AppState.getClusterInfo().cluster : AppState.getClusterInfo().manager, isCluster, - VULNERABILITY_CLUSTER_KEY, + VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER[ + AppState.getClusterInfo().status + ], ), ); filters.push(filterHandler.pciQuery()); diff --git a/plugins/main/public/components/overview/vulnerabilities/common/vulnerability_detector_adapters.tsx b/plugins/main/public/components/overview/vulnerabilities/common/vulnerability_detector_adapters.tsx index 02d97401eb..c2a6e117c8 100644 --- a/plugins/main/public/components/overview/vulnerabilities/common/vulnerability_detector_adapters.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/common/vulnerability_detector_adapters.tsx @@ -1,6 +1,6 @@ import { AUTHORIZED_AGENTS, - VULNERABILITY_CLUSTER_KEY, + VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER, WAZUH_ALERTS_PATTERN, } from '../../../../../common/constants'; import { AppState } from '../../../../react-services'; @@ -46,7 +46,9 @@ export const vulnerabilityIndexFiltersAdapter = ( ? AppState.getClusterInfo().cluster : AppState.getClusterInfo().manager, true, - VULNERABILITY_CLUSTER_KEY, // Vulnerability module does not have manager.name in the index pattern template, only fixed wazuh.cluster.name + VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER[ + AppState.getClusterInfo().status + ], ); // rule.groups is added so that the events tab can use it @@ -95,11 +97,17 @@ export const restorePrevIndexFiltersAdapter = ( defaultIndexPatternID: string, ) => { const filterHandler = new FilterHandler(AppState.getCurrentPattern()); + const isCluster = AppState.getClusterInfo().status == 'enabled'; const cleanedFilters = cleanFilters( previousFilters, defaultIndexPatternID, - ).filter((filter: Filter) => filter?.meta?.key !== VULNERABILITY_CLUSTER_KEY); - const isCluster = AppState.getClusterInfo().status == 'enabled'; + ).filter( + (filter: Filter) => + filter?.meta?.key !== + VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER[ + AppState.getClusterInfo().status + ], + ); /* Restore original manager implicit filter */ const managerFilter = filterHandler.managerQuery( isCluster diff --git a/plugins/main/public/services/common-data.js b/plugins/main/public/services/common-data.js index 450cecd6bd..bd5d18d0f4 100644 --- a/plugins/main/public/services/common-data.js +++ b/plugins/main/public/services/common-data.js @@ -14,7 +14,7 @@ import { GenericRequest } from '../react-services/generic-request'; import { ShareAgent } from '../factories/share-agent'; import { ModulesHelper } from '../components/common/modules/modules-helper'; import rison from 'rison-node'; -import { VULNERABILITY_CLUSTER_KEY } from '../../common/constants'; +import { VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER } from '../../common/constants'; export class CommonData { /** @@ -159,7 +159,11 @@ export class CommonData { ? AppState.getClusterInfo().cluster : AppState.getClusterInfo().manager, isCluster, - tab === 'vuls' ? VULNERABILITY_CLUSTER_KEY : undefined, + tab === 'vuls' + ? VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER[ + AppState.getClusterInfo().status + ] + : undefined, ), ); if (tab !== 'general' && tab !== 'welcome') { From ce8f50f1ae4b44c9c2ff851799d4111bec947059 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Fri, 16 Feb 2024 08:59:48 +0100 Subject: [PATCH 38/64] Change text in endpoint summary most active agent tooltip (#6421) * Change Most active agent tooltip text * Add changelog --- CHANGELOG.md | 2 +- .../main/public/controllers/agent/components/agents-preview.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 313686e0cc..be6424f387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) -- Added information icon with tooltip on the most active agent in the endpoint summary view [#6364](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6364) +- Added information icon with tooltip on the most active agent in the endpoint summary view [#6364](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6364) [#6421](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6421) - Added a dash with a tooltip in the server APIs table when the run as is disabled [#6354](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6354) ### Changed diff --git a/plugins/main/public/controllers/agent/components/agents-preview.js b/plugins/main/public/controllers/agent/components/agents-preview.js index 60d8fb2b76..a694292ab6 100644 --- a/plugins/main/public/controllers/agent/components/agents-preview.js +++ b/plugins/main/public/controllers/agent/components/agents-preview.js @@ -391,7 +391,7 @@ export const AgentsPreview = compose( } From e317a0be6804ebb1ec89a818aca6c7e5a55298f9 Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:32:17 +0100 Subject: [PATCH 39/64] Add the Vulnerabilities Detection application to the menu in Endpoints summary view (#6423) * fix(endpoint-summary): add a link to the Vulnerabilities Detection application to the menu * changelog: add pull request entry - Add pull request entry - Move pull request reference to another entry --- CHANGELOG.md | 3 +-- plugins/main/public/utils/applications.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be6424f387..104a9d3397 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Moved the plugin menu to platform applications into the side menu [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) [#6226](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6226) [#6244](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6244) +- Moved the plugin menu to platform applications into the side menu [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) [#6226](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6226) [#6244](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6244) [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) [#6423](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6423) - Changed dashboards. [#6035](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6035) - Change the display order of tabs in all modules. [#6067](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6067) - Upgraded the `axios` dependency to `1.6.1` [#5062](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5062) @@ -49,7 +49,6 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed the `disabled_roles` and `customization.logo.sidebar` settings [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Removed the ability to configure the visibility of modules and removed `extensions.*` settings [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) -- Removed the application menu in the IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) - Removed the implicit filter of WQL language of the search bar UI [#6174](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6174) - Removed notice of old Discover deprecation [#6341](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6341) - Removed compilation date field from the app [#6366](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6366) diff --git a/plugins/main/public/utils/applications.ts b/plugins/main/public/utils/applications.ts index 317fc12320..457cfdd300 100644 --- a/plugins/main/public/utils/applications.ts +++ b/plugins/main/public/utils/applications.ts @@ -193,7 +193,7 @@ export const vulnerabilityDetection = { euiIconType: 'heartbeatApp', order: 301, showInOverviewApp: true, - showInAgentMenu: false, + showInAgentMenu: true, redirectTo: () => `/overview/?tab=vuls&tabView=panels${ store.getState()?.appStateReducers?.currentAgentData?.id From cbe0d85ba94fa6f182c5d9590604f5329510aa27 Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:28:55 +0100 Subject: [PATCH 40/64] Change the value to display in the Top 5 agents table in Vulnerabilities Detection dashboard (#6424) * feat(vulnerabilities-detection): display the agent.name in the Top 5 agents table of Vulnerabilities Detection > Dashboard * changelog: add pull request entry --- CHANGELOG.md | 2 +- .../overview/dashboard_panels_filters.ts | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 104a9d3397..4fc57485cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) [#6424](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6424) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts index 7d8e2c64be..6f3c07cb35 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels_filters.ts @@ -6,7 +6,7 @@ const getVisStateFilter = ( indexPatternId: string, title: string, label: string, - fieldName: string + fieldName: string, ) => { return { id, @@ -79,9 +79,11 @@ const getVisStateFilter = ( }; export const getDashboardFilters = ( - indexPatternId: string + indexPatternId: string, ): { - [panelId: string]: DashboardPanelState; + [panelId: string]: DashboardPanelState< + EmbeddableInput & { [k: string]: unknown } + >; } => { return { topPackageSelector: { @@ -100,7 +102,7 @@ export const getDashboardFilters = ( indexPatternId, 'Top packages vulnerabilities', 'Top 5 packages', - 'package.name' + 'package.name', ), }, }, @@ -120,7 +122,7 @@ export const getDashboardFilters = ( indexPatternId, 'Top operating system vulnerabilities', 'Top 5 OS', - 'host.os.full' + 'host.os.full', ), }, }, @@ -140,7 +142,7 @@ export const getDashboardFilters = ( indexPatternId, 'Agent filter', 'Top 5 agents', - 'agent.id' + 'agent.name', ), }, }, @@ -160,7 +162,7 @@ export const getDashboardFilters = ( indexPatternId, 'Top vulnerabilities', 'Top 5 vulnerabilities', - 'vulnerability.id' + 'vulnerability.id', ), }, }, From ff9c26f8a7dd615b13f7748bfdea890f39a50160 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Fri, 16 Feb 2024 15:49:41 +0100 Subject: [PATCH 41/64] Update the vulnerabilities events injector script (#6426) Update sample template and script --- docker/imposter/manager/configuration.js | 2 +- .../DIS_Template.json | 105 +----------------- .../dataInjectScript.py | 47 +++++--- 3 files changed, 36 insertions(+), 118 deletions(-) diff --git a/docker/imposter/manager/configuration.js b/docker/imposter/manager/configuration.js index 02984110f2..d85926ec49 100644 --- a/docker/imposter/manager/configuration.js +++ b/docker/imposter/manager/configuration.js @@ -17,7 +17,7 @@ switch (pathConfiguration[0]) { case 'wmodules': respond() .withStatusCode(200) - .withFile('manager/configuration/monitor_reports.json'); + .withFile('manager/configuration/wmodules_wmodules.json'); break; default: diff --git a/scripts/vulnerabilities-events-injector/DIS_Template.json b/scripts/vulnerabilities-events-injector/DIS_Template.json index edfd394a8d..c9cec7e26f 100644 --- a/scripts/vulnerabilities-events-injector/DIS_Template.json +++ b/scripts/vulnerabilities-events-injector/DIS_Template.json @@ -56,106 +56,6 @@ } } }, - "event": { - "properties": { - "action": { - "ignore_above": 1024, - "type": "keyword" - }, - "agent_id_status": { - "ignore_above": 1024, - "type": "keyword" - }, - "category": { - "ignore_above": 1024, - "type": "keyword" - }, - "code": { - "ignore_above": 1024, - "type": "keyword" - }, - "created": { - "type": "date" - }, - "dataset": { - "ignore_above": 1024, - "type": "keyword" - }, - "duration": { - "type": "long" - }, - "end": { - "type": "date" - }, - "hash": { - "ignore_above": 1024, - "type": "keyword" - }, - "id": { - "ignore_above": 1024, - "type": "keyword" - }, - "ingested": { - "type": "date" - }, - "kind": { - "ignore_above": 1024, - "type": "keyword" - }, - "module": { - "ignore_above": 1024, - "type": "keyword" - }, - "original": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "outcome": { - "ignore_above": 1024, - "type": "keyword" - }, - "provider": { - "ignore_above": 1024, - "type": "keyword" - }, - "reason": { - "ignore_above": 1024, - "type": "keyword" - }, - "reference": { - "ignore_above": 1024, - "type": "keyword" - }, - "risk_score": { - "type": "float" - }, - "risk_score_norm": { - "type": "float" - }, - "sequence": { - "type": "long" - }, - "severity": { - "type": "long" - }, - "start": { - "type": "date" - }, - "timezone": { - "ignore_above": 1024, - "type": "keyword" - }, - "type": { - "ignore_above": 1024, - "type": "keyword" - }, - "url": { - "ignore_above": 1024, - "type": "keyword" - } - } - }, "host": { "properties": { "os": { @@ -202,9 +102,6 @@ } } }, - "labels": { - "type": "object" - }, "message": { "type": "text" }, @@ -365,4 +262,4 @@ "refresh_interval": "2s" } } -} +} \ No newline at end of file diff --git a/scripts/vulnerabilities-events-injector/dataInjectScript.py b/scripts/vulnerabilities-events-injector/dataInjectScript.py index c54945764e..aa50604a3a 100644 --- a/scripts/vulnerabilities-events-injector/dataInjectScript.py +++ b/scripts/vulnerabilities-events-injector/dataInjectScript.py @@ -85,7 +85,6 @@ def generateRandomPackage(): package['checksum'] = 'checksum{}'.format(random.randint(0, 9999)) package['description'] = 'description{}'.format(random.randint(0, 9999)) package['install_scope'] = random.choice(['user','system']) - package['install_time'] = generateRandomDate() package['license'] = 'license{}'.format(random.randint(0, 9)) package['name'] = 'name{}'.format(random.randint(0, 99)) package['path'] = '/path/to/package{}'.format(random.randint(0, 99)) @@ -120,8 +119,7 @@ def generateRandomVulnerability(): def generateRandomWazuh(): wazuh = {} - wazuh['cluster'] = {'name':'wazuh.manager'} - wazuh['node'] = {'name':random.choice(['master','worker-01','worker-02','worker-03'])} + wazuh['cluster'] = {'name':random.choice(['wazuh.manager', 'wazuh']), 'node':random.choice(['master','worker-01','worker-02','worker-03'])} return(wazuh) def generateRandomData(number): @@ -130,9 +128,7 @@ def generateRandomData(number): '@timestamp':generateRandomDate(), 'agent':generateRandomAgent(), 'ecs':{'version':'1.7.0'}, - 'event':generateRandomEvent(), 'host':generateRandomHost(), - 'labels':generateRandomLabels(), 'message':'message{}'.format(random.randint(0, 99999)), 'package':generateRandomPackage(), 'tags':generateRandomTags(), @@ -179,14 +175,34 @@ def verifySettings(): print('\nDIS_Settings.json not found. Continuing without it.') if not verified: - ip = input("\nEnter the IP of your Indexer: \n") - port = input("\nEnter the port of your Indexer: \n") - index = input("\nEnter the index name: \n") + ip = input("\nEnter the IP of your Indexer [default=0.0.0.0]: \n") + if ip == '': + ip = '0.0.0.0' + + port = input("\nEnter the port of your Indexer [default=9200]: \n") + if port == '': + port = '9200' + + index = input("\nEnter the index name [default=wazuh-states-vulnerabilities]: \n") + if index == '': + index = 'wazuh-states-vulnerabilities' + url = 'https://{}:{}/{}/_doc'.format(ip, port, index) - username = input("\nUsername: \n") - password = input("\nPassword: \n") + + username = input("\nUsername [default=admin]: \n") + if username == '': + username = 'admin' + + password = input("\nPassword [default=admin]: \n") + if password == '': + password = 'admin' + config = {'ip':ip,'port':port,'index':index,'username':username,'password':password} - store = input("\nDo you want to store these settings for future use? (y/n) \n") + + store = input("\nDo you want to store these settings for future use? (y/n) [default=n] \n") + if store == '': + store = 'n' + while store != 'y' and store != 'n': store = input("\nInvalid option.\n Do you want to store these settings for future use? (y/n) \n") if store == 'y': @@ -213,10 +229,15 @@ def injectEvents(generator): def main(): - action = input("Do you want to inject data or save it to a file? (i/s) \n") + action = input("Do you want to inject data or save it to a file? (i/s) [default=i]\n") + if action == '': + action = 'i' + while(action != 'i' and action != 's'): action = input("\nInvalid option.\n Do you want to inject data or save it to a file? (i/s) \n") - number = input("\nHow many events do you want to generate? \n") + number = input("\nHow many events do you want to generate? [default=100]\n") + if number == '': + number = '100' while(not number.isdigit()): number = input("Invalid option.\n How many events do you want to generate? \n") data = generateRandomData(number) From 5befcbfce6cd6d0f818039b4d864a8d2212f4911 Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Fri, 16 Feb 2024 17:51:26 +0100 Subject: [PATCH 42/64] Changed most vulnerable endpoint label (#6422) * Changed most vulnerable label and package.path * Add Changelog * Change agent.id to agent.name * Fix commit * fix typo * Update changelog * Remove "-s" from endpoints --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- .../vulnerabilities/dashboards/overview/dashboard_panels.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fc57485cf..e5cbd674a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) [#6424](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6424) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) [#6424](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6424) [#6422](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6422) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels.ts b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels.ts index 3269a8d65b..b7c98727e1 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels.ts +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard_panels.ts @@ -245,7 +245,7 @@ const getVisStateTopVulnerabilitiesEndpoints = (indexPatternId: string) => { enabled: true, type: 'terms', params: { - field: 'agent.id', + field: 'agent.name', orderBy: '1', order: 'desc', size: 10, @@ -253,7 +253,7 @@ const getVisStateTopVulnerabilitiesEndpoints = (indexPatternId: string) => { otherBucketLabel: 'Other', missingBucket: false, missingBucketLabel: 'Missing', - customLabel: 'package.path', + customLabel: 'Endpoint name', }, schema: 'segment', }, From 810ab4aa074a1d4e8440b40c23af27372e7e3c92 Mon Sep 17 00:00:00 2001 From: Tostti Date: Fri, 16 Feb 2024 15:24:24 -0300 Subject: [PATCH 43/64] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71533135b6..596abb0be2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to the Wazuh app project will be documented in this file. +## Wazuh v4.7.3 - OpenSearch Dashboards 2.8.0 - Revision 00 + +### Added + +- Support for Wazuh 4.7.3 ## Wazuh v4.7.2 - OpenSearch Dashboards 2.8.0 - Revision 02 From 5fc2fe989c9ff9ff25cf7fd86f14832262285d36 Mon Sep 17 00:00:00 2001 From: Tostti Date: Fri, 16 Feb 2024 15:24:36 -0300 Subject: [PATCH 44/64] Update package.json --- plugins/main/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/main/package.json b/plugins/main/package.json index 61c22c2644..4c0732a19c 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", - "version": "4.7.2", - "revision": "02", + "version": "4.7.3", + "revision": "00", "pluginPlatform": { "version": "2.8.0" }, From a24a219e5348dc9c7a66f493b9de06c6567d9805 Mon Sep 17 00:00:00 2001 From: Tostti Date: Fri, 16 Feb 2024 15:24:50 -0300 Subject: [PATCH 45/64] update opensearch_dashboards.json --- plugins/main/opensearch_dashboards.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index a7321ce579..36ca2b458e 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.7.2-02", + "version": "4.7.3-00", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": [ "wazuh" From 8513a2320418d8412db4e10ecaa955bca20ffbfa Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:23:14 +0100 Subject: [PATCH 46/64] Replace discover Google cloud (#6289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace discover * Add changelog --------- Co-authored-by: Julio César Biset <43619595+jbiset@users.noreply.github.com> --- CHANGELOG.md | 2 +- .../common/modules/modules-defaults.js | 6 ++++- .../events/google-cloud-columns.tsx | 22 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 plugins/main/public/components/overview/google-cloud/events/google-cloud-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index d46e33536d..6269a5808f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index eacc114770..e660068c50 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -27,6 +27,7 @@ import { vulnerabilitiesColumns } from '../../overview/vulnerabilities/events/vu import { DashboardFim } from '../../overview/fim/dashboard/dashboard'; import { InventoryFim } from '../../overview/fim/inventory/inventory'; import React from 'react'; +import { googleCloudColumns } from '../../overview/google-cloud/events/google-cloud-columns'; import { amazonWebServicesColumns } from '../../overview/amazon-web-services/events/amazon-web-services-columns'; import { office365Columns } from '../../overview/office-panel/events/office-365-columns'; import { fileIntegrityMonitoringColumns } from '../../overview/fim/events/file-integrity-monitoring-columns'; @@ -108,7 +109,10 @@ export const ModulesDefaults = { }, gcp: { init: 'dashboard', - tabs: [DashboardTab, EventsTab], + tabs: [ + DashboardTab, + renderDiscoverTab(DEFAULT_INDEX_PATTERN, googleCloudColumns), + ], availableFor: ['manager', 'agent'], }, pm: { diff --git a/plugins/main/public/components/overview/google-cloud/events/google-cloud-columns.tsx b/plugins/main/public/components/overview/google-cloud/events/google-cloud-columns.tsx new file mode 100644 index 0000000000..78b351046b --- /dev/null +++ b/plugins/main/public/components/overview/google-cloud/events/google-cloud-columns.tsx @@ -0,0 +1,22 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const googleCloudColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'data.gcp.jsonPayload.vmInstanceName', + }, + { + id: 'data.gcp.resource.labels.location', + }, + { + id: 'data.gcp.resource.labels.project_id', + }, + { + id: 'data.gcp.resource.type', + }, + { + id: 'data.gcp.severity', + }, +]; From 85f4451ed6bbfa29ca5dbc083b685862a5d841d4 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:05:36 +0100 Subject: [PATCH 47/64] Replace discover Github (#6291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Replace discover * Add changelog --------- Co-authored-by: Julio César Biset <43619595+jbiset@users.noreply.github.com> --- CHANGELOG.md | 2 +- .../common/modules/modules-defaults.js | 3 ++- .../github-panel/events/github-columns.tsx | 25 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 plugins/main/public/components/overview/github-panel/events/github-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 6269a5808f..ed9da8a9ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6291) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index e660068c50..3d882abaf8 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -32,6 +32,7 @@ import { amazonWebServicesColumns } from '../../overview/amazon-web-services/eve import { office365Columns } from '../../overview/office-panel/events/office-365-columns'; import { fileIntegrityMonitoringColumns } from '../../overview/fim/events/file-integrity-monitoring-columns'; import { configurationAssessmentColumns } from '../../agents/sca/events/configuration-assessment-columns'; +import { githubColumns } from '../../overview/github-panel/events/github-columns'; const DashboardTab = { id: 'dashboard', @@ -182,7 +183,7 @@ export const ModulesDefaults = { buttons: [ButtonModuleExploreAgent], component: GitHubPanel, }, - EventsTab, + renderDiscoverTab(DEFAULT_INDEX_PATTERN, githubColumns), ], availableFor: ['manager', 'agent'], }, diff --git a/plugins/main/public/components/overview/github-panel/events/github-columns.tsx b/plugins/main/public/components/overview/github-panel/events/github-columns.tsx new file mode 100644 index 0000000000..28e0db7a4f --- /dev/null +++ b/plugins/main/public/components/overview/github-panel/events/github-columns.tsx @@ -0,0 +1,25 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const githubColumns: tDataGridColumn[] = [ + { + id: 'agent.id', + }, + { + id: 'data.github.repo', + }, + { + id: 'data.github.actor', + }, + { + id: 'data.github.org', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; From e70033f8d7c8ad9a8d70fca7d9ae16ae0ffa88cc Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Mon, 19 Feb 2024 21:35:14 +0100 Subject: [PATCH 48/64] Replace discover PCI DSS, GDPR, HIPAA, TSC and NIST 800-53 modules (#6297) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * replace discover * add DashboardTab * Add changelog * remove discover from security operations less it hygiene * Update CHANGELOG --------- Co-authored-by: Julio César Biset <43619595+jbiset@users.noreply.github.com> Co-authored-by: Maximiliano Ibarra <6089438+Machi3mfl@users.noreply.github.com> Co-authored-by: Maximiliano --- CHANGELOG.md | 2 +- .../common/modules/modules-defaults.js | 19 ++++++++++++------- .../overview/gdpr/events/gdpr-columns.tsx | 19 +++++++++++++++++++ .../overview/hipaa/events/hipaa-columns.tsx | 19 +++++++++++++++++++ .../overview/nist/events/nist-columns.tsx | 19 +++++++++++++++++++ .../overview/pci/events/pci-columns.tsx | 19 +++++++++++++++++++ .../overview/tsc/events/tsc-columns.tsx | 19 +++++++++++++++++++ 7 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 plugins/main/public/components/overview/gdpr/events/gdpr-columns.tsx create mode 100644 plugins/main/public/components/overview/hipaa/events/hipaa-columns.tsx create mode 100644 plugins/main/public/components/overview/nist/events/nist-columns.tsx create mode 100644 plugins/main/public/components/overview/pci/events/pci-columns.tsx create mode 100644 plugins/main/public/components/overview/tsc/events/tsc-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index ed9da8a9ac..c842e169d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6291) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index 3d882abaf8..1aa0a53574 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -32,6 +32,11 @@ import { amazonWebServicesColumns } from '../../overview/amazon-web-services/eve import { office365Columns } from '../../overview/office-panel/events/office-365-columns'; import { fileIntegrityMonitoringColumns } from '../../overview/fim/events/file-integrity-monitoring-columns'; import { configurationAssessmentColumns } from '../../agents/sca/events/configuration-assessment-columns'; +import { pciColumns } from '../../overview/pci/events/pci-columns'; +import { hipaaColumns } from '../../overview/hipaa/events/hipaa-columns'; +import { nistColumns } from '../../overview/nist/events/nist-columns'; +import { gdprColumns } from '../../overview/gdpr/events/gdpr-columns'; +import { tscColumns } from '../../overview/tsc/events/tsc-columns'; import { githubColumns } from '../../overview/github-panel/events/github-columns'; const DashboardTab = { @@ -61,7 +66,7 @@ const EventsTab = { component: Events, }; -const RegulatoryComplianceTabs = [ +const RegulatoryComplianceTabs = columns => [ DashboardTab, { id: 'inventory', @@ -69,7 +74,7 @@ const RegulatoryComplianceTabs = [ buttons: [ButtonModuleExploreAgent], component: ComplianceTable, }, - EventsTab, + renderDiscoverTab(DEFAULT_INDEX_PATTERN, columns), ]; export const ModulesDefaults = { @@ -262,27 +267,27 @@ export const ModulesDefaults = { }, pci: { init: 'dashboard', - tabs: RegulatoryComplianceTabs, + tabs: RegulatoryComplianceTabs(pciColumns), availableFor: ['manager', 'agent'], }, hipaa: { init: 'dashboard', - tabs: RegulatoryComplianceTabs, + tabs: RegulatoryComplianceTabs(hipaaColumns), availableFor: ['manager', 'agent'], }, nist: { init: 'dashboard', - tabs: RegulatoryComplianceTabs, + tabs: RegulatoryComplianceTabs(nistColumns), availableFor: ['manager', 'agent'], }, gdpr: { init: 'dashboard', - tabs: RegulatoryComplianceTabs, + tabs: RegulatoryComplianceTabs(gdprColumns), availableFor: ['manager', 'agent'], }, tsc: { init: 'dashboard', - tabs: RegulatoryComplianceTabs, + tabs: RegulatoryComplianceTabs(tscColumns), availableFor: ['manager', 'agent'], }, syscollector: { diff --git a/plugins/main/public/components/overview/gdpr/events/gdpr-columns.tsx b/plugins/main/public/components/overview/gdpr/events/gdpr-columns.tsx new file mode 100644 index 0000000000..f02c3d9464 --- /dev/null +++ b/plugins/main/public/components/overview/gdpr/events/gdpr-columns.tsx @@ -0,0 +1,19 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const gdprColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'rule.gdpr', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; diff --git a/plugins/main/public/components/overview/hipaa/events/hipaa-columns.tsx b/plugins/main/public/components/overview/hipaa/events/hipaa-columns.tsx new file mode 100644 index 0000000000..9a31860eec --- /dev/null +++ b/plugins/main/public/components/overview/hipaa/events/hipaa-columns.tsx @@ -0,0 +1,19 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const hipaaColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'rule.hipaa', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; diff --git a/plugins/main/public/components/overview/nist/events/nist-columns.tsx b/plugins/main/public/components/overview/nist/events/nist-columns.tsx new file mode 100644 index 0000000000..55ca628416 --- /dev/null +++ b/plugins/main/public/components/overview/nist/events/nist-columns.tsx @@ -0,0 +1,19 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const nistColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'rule.nist_800_53', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; diff --git a/plugins/main/public/components/overview/pci/events/pci-columns.tsx b/plugins/main/public/components/overview/pci/events/pci-columns.tsx new file mode 100644 index 0000000000..374705cefe --- /dev/null +++ b/plugins/main/public/components/overview/pci/events/pci-columns.tsx @@ -0,0 +1,19 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const pciColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'rule.pci_dss', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; diff --git a/plugins/main/public/components/overview/tsc/events/tsc-columns.tsx b/plugins/main/public/components/overview/tsc/events/tsc-columns.tsx new file mode 100644 index 0000000000..d67fb46b41 --- /dev/null +++ b/plugins/main/public/components/overview/tsc/events/tsc-columns.tsx @@ -0,0 +1,19 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const tscColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'rule.tsc', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, + { + id: 'rule.id', + }, +]; From 5bc336056951250148fbcd4d32a6833ff7a180af Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:29:34 +0100 Subject: [PATCH 49/64] Exclude server filters on Vulnerabilities Detection > Dashboard and Inventory (#6429) * feat: add hidden filters to Vulnerabilities Detection - Add hidden filters to Vulnerabilities Detection > Dashboard and Inventory - Exclude server data (depends on the hideManagerAlerts setting) - Restrict to allowed agents * fix: implicit filter could be removed on Vulnerabilities Detection > Inventory if resize the window * changelog: add pull request entry --- CHANGELOG.md | 2 +- plugins/main/common/constants.ts | 1 + .../dashboards/inventory/inventory.tsx | 12 ++- .../dashboards/overview/dashboard.tsx | 17 +++- .../react-services/data-sources/index.ts | 2 + .../react-services/data-sources/types.ts | 3 + .../data-sources/vulnerabilities-states.ts | 95 +++++++++++++++++++ 7 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 plugins/main/public/react-services/data-sources/index.ts create mode 100644 plugins/main/public/react-services/data-sources/types.ts create mode 100644 plugins/main/public/react-services/data-sources/vulnerabilities-states.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cbd674a3..bf98ae549d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328) - Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791) - Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083) -- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) [#6424](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6424) [#6422](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6422) +- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338) [#6356](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6356) [#6396](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6396) [#6399](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6399) [#6405](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6405) [#6410](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6410) [#6424](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6424) [#6422](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6422) [#6429](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6429) - Added an agent selector to the IT Hygiene application [#5840](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5840) - Added query results limit when the search exceed 10000 hits [#6106](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6106) - Added a redirection button to Endpoint Summary from IT Hygiene application [#6176](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6176) diff --git a/plugins/main/common/constants.ts b/plugins/main/common/constants.ts index b6bf45e8df..e23e4b6585 100644 --- a/plugins/main/common/constants.ts +++ b/plugins/main/common/constants.ts @@ -260,6 +260,7 @@ export enum WAZUH_MENU_SETTINGS_SECTIONS_ID { } export const AUTHORIZED_AGENTS = 'authorized-agents'; +export const DATA_SOURCE_FILTER_CONTROLLED_EXCLUDE_SERVER = 'exclude-server'; // Wazuh links export const WAZUH_LINK_GITHUB = 'https://github.com/wazuh'; diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index 1a51c2b282..4d96a4710a 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -43,6 +43,7 @@ import { import { compose } from 'redux'; import { withVulnerabilitiesStateDataSource } from '../../common/hocs/validate-vulnerabilities-states-index-pattern'; import { ModuleEnabledCheck } from '../../common/components/check-module-enabled'; +import { DataSourceFilterManagerVulnerabilitiesStates } from '../../../../../react-services/data-sources'; const InventoryVulsComponent = () => { const appConfig = useAppConfig(); @@ -54,6 +55,11 @@ const InventoryVulsComponent = () => { onUpdate: onUpdateAdapter, onUnMount: restorePrevIndexFiltersAdapter, }); + + const fetchFilters = DataSourceFilterManagerVulnerabilitiesStates.getFilters( + searchBarProps.filters, + VULNERABILITIES_INDEX_PATTERN_ID, + ); const { isLoading, filters, query, indexPatterns } = searchBarProps; const SearchBar = getPlugins().data.ui.SearchBar; const [results, setResults] = useState({} as SearchResponse); @@ -109,7 +115,7 @@ const InventoryVulsComponent = () => { setIndexPattern(indexPatterns?.[0] as IndexPattern); search({ indexPattern: indexPatterns?.[0] as IndexPattern, - filters, + filters: fetchFilters, query, pagination, sorting, @@ -131,12 +137,13 @@ const InventoryVulsComponent = () => { JSON.stringify(searchBarProps), JSON.stringify(pagination), JSON.stringify(sorting), + JSON.stringify(fetchFilters), ]); const onClickExportResults = async () => { const params = { indexPattern: indexPatterns?.[0] as IndexPattern, - filters, + filters: fetchFilters, query, fields: columnVisibility.visibleColumns, pagination: { @@ -166,7 +173,6 @@ const InventoryVulsComponent = () => { <> diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx index c5443803c9..fb85ae42a9 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/overview/dashboard.tsx @@ -27,6 +27,7 @@ import { import { compose } from 'redux'; import { withVulnerabilitiesStateDataSource } from '../../common/hocs/validate-vulnerabilities-states-index-pattern'; import { ModuleEnabledCheck } from '../../common/components/check-module-enabled'; +import { DataSourceFilterManagerVulnerabilitiesStates } from '../../../../../react-services/data-sources'; const plugins = getPlugins(); @@ -48,6 +49,12 @@ const DashboardVulsComponent: React.FC = () => { onUpdate: onUpdateAdapter, onUnMount: restorePrevIndexFiltersAdapter, }); + + const fetchFilters = DataSourceFilterManagerVulnerabilitiesStates.getFilters( + searchBarProps.filters, + VULNERABILITIES_INDEX_PATTERN_ID, + ); + const { isLoading, filters, query, indexPatterns } = searchBarProps; const [isSearching, setIsSearching] = useState(false); @@ -57,7 +64,7 @@ const DashboardVulsComponent: React.FC = () => { if (!isLoading) { search({ indexPattern: indexPatterns?.[0] as IndexPattern, - filters, + filters: fetchFilters, query, }) .then(results => { @@ -73,7 +80,7 @@ const DashboardVulsComponent: React.FC = () => { setIsSearching(false); }); } - }, [JSON.stringify(searchBarProps)]); + }, [JSON.stringify(searchBarProps), JSON.stringify(fetchFilters)]); return ( <> @@ -104,7 +111,7 @@ const DashboardVulsComponent: React.FC = () => { VULNERABILITIES_INDEX_PATTERN_ID, ), isFullScreenMode: false, - filters: searchBarProps.filters ?? [], + filters: fetchFilters ?? [], useMargins: false, id: 'vulnerability-detector-dashboard-tab-filters', timeRange: { @@ -128,7 +135,7 @@ const DashboardVulsComponent: React.FC = () => { viewMode: ViewMode.VIEW, panels: getKPIsPanel(VULNERABILITIES_INDEX_PATTERN_ID), isFullScreenMode: false, - filters: searchBarProps.filters ?? [], + filters: fetchFilters ?? [], useMargins: true, id: 'kpis-vulnerability-detector-dashboard-tab', timeRange: { @@ -150,7 +157,7 @@ const DashboardVulsComponent: React.FC = () => { viewMode: ViewMode.VIEW, panels: getDashboardPanels(VULNERABILITIES_INDEX_PATTERN_ID), isFullScreenMode: false, - filters: searchBarProps.filters ?? [], + filters: fetchFilters ?? [], useMargins: true, id: 'vulnerability-detector-dashboard-tab', timeRange: { diff --git a/plugins/main/public/react-services/data-sources/index.ts b/plugins/main/public/react-services/data-sources/index.ts new file mode 100644 index 0000000000..88e23ab274 --- /dev/null +++ b/plugins/main/public/react-services/data-sources/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './vulnerabilities-states'; diff --git a/plugins/main/public/react-services/data-sources/types.ts b/plugins/main/public/react-services/data-sources/types.ts new file mode 100644 index 0000000000..e5c1b13c2b --- /dev/null +++ b/plugins/main/public/react-services/data-sources/types.ts @@ -0,0 +1,3 @@ +export interface IDataSourcesFilterManager { + getFilters(searchBarFilters: any[], indexPatternTitle: string): any[]; +} diff --git a/plugins/main/public/react-services/data-sources/vulnerabilities-states.ts b/plugins/main/public/react-services/data-sources/vulnerabilities-states.ts new file mode 100644 index 0000000000..24b6585473 --- /dev/null +++ b/plugins/main/public/react-services/data-sources/vulnerabilities-states.ts @@ -0,0 +1,95 @@ +import { + AUTHORIZED_AGENTS, + DATA_SOURCE_FILTER_CONTROLLED_EXCLUDE_SERVER, +} from '../../../common/constants'; +import store from '../../redux/store'; +import { IDataSourcesFilterManager } from './types'; + +/** + * Get the filter that excludes the data related to Wazuh servers + * @param indexPatternTitle Index pattern title + * @returns + */ +function getFilterExcludeManager(indexPatternTitle: string) { + return { + meta: { + alias: null, + disabled: false, + key: 'agent.id', + negate: true, + params: { query: '000' }, + type: 'phrase', + index: indexPatternTitle, + controlledBy: DATA_SOURCE_FILTER_CONTROLLED_EXCLUDE_SERVER, + }, + query: { match_phrase: { 'agent.id': '000' } }, + $state: { store: 'appState' }, + }; +} + +/** + * Get the filter that restrict the search to the allowed agents + * @param agentsIds + * @param indexPatternTitle + * @returns + */ +function getFilterAllowedAgents( + agentsIds: string[], + indexPatternTitle: string, +) { + const field = 'agent.id'; + return { + meta: { + index: indexPatternTitle, + type: 'phrases', + key: field, + value: agentsIds.toString(), + params: agentsIds, + alias: null, + negate: false, + disabled: false, + controlledBy: AUTHORIZED_AGENTS, + }, + query: { + bool: { + should: agentsIds.map(id => { + return { + match_phrase: { + [field]: id, + }, + }; + }), + minimum_should_match: 1, + }, + }, + $state: { + store: 'appState', + }, + }; +} + +export const DataSourceFilterManagerVulnerabilitiesStates: IDataSourcesFilterManager = + { + getFilters(searchBarFilters: any[], indexPatternTitle: string) { + return [ + ...searchBarFilters, + /* Add the filter to exclude the data related to servers (managers) due to + the setting hideManagerAlerts is enabled */ + ...(store.getState().appConfig?.data?.hideManagerAlerts && + indexPatternTitle + ? [getFilterExcludeManager(indexPatternTitle)] + : []), + /* Add the allowed agents related to the user permissions to read data from agents in the + API server */ + ...(store.getState().appStateReducers?.allowedAgents?.length > 0 && + indexPatternTitle + ? [ + getFilterAllowedAgents( + store.getState().appStateReducers?.allowedAgents, + indexPatternTitle, + ), + ] + : []), + ]; + }, + }; From 8e0bc876d8a0a55cf226b7665ecdbb82ac8c9f8f Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Tue, 20 Feb 2024 11:40:20 +0100 Subject: [PATCH 50/64] Improve MITRE ATT&CK error handling (#6431) * Add checks to request * Add Changelog * fix typo in changelog --- CHANGELOG.md | 1 + .../mitre/components/tactics/tactics.tsx | 84 +++--- .../components/techniques/techniques.tsx | 240 ++++++++++++------ 3 files changed, 223 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf98ae549d..abce82d9b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed implicit filter close button in the search bar [#6346](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6346) - Fixed the help menu, to be consistent and avoid duplication [#6374](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6374) - Fixed the axis label visual bug from dashboards [#6378](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6378) +- Fixed a error pop-up spawn in MITRE ATT&CK [#6431](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6431) ### Removed diff --git a/plugins/main/public/components/overview/mitre/components/tactics/tactics.tsx b/plugins/main/public/components/overview/mitre/components/tactics/tactics.tsx index f89e4a28fd..24f183ec4f 100644 --- a/plugins/main/public/components/overview/mitre/components/tactics/tactics.tsx +++ b/plugins/main/public/components/overview/mitre/components/tactics/tactics.tsx @@ -20,10 +20,10 @@ import { EuiButtonIcon, EuiLoadingSpinner, EuiContextMenu, - EuiIcon -} from '@elastic/eui' + EuiIcon, +} from '@elastic/eui'; import { IFilterParams, getElasticAlerts } from '../../lib'; -import { getToasts } from '../../../../../kibana-services'; +import { getToasts } from '../../../../../kibana-services'; import { UI_LOGGER_LEVELS } from '../../../../../../common/constants'; import { UI_ERROR_SEVERITIES } from '../../../../../react-services/error-orchestrator/types'; import { getErrorOrchestrator } from '../../../../../react-services/common-services'; @@ -75,21 +75,30 @@ export class Tactics extends Component { } shouldComponentUpdate(nextProps, nextState) { - const { filterParams, indexPattern, selectedTactics, isLoading } = this.props; + const { filterParams, indexPattern, selectedTactics, isLoading } = + this.props; const { tacticsCount, loadingAlerts } = this.state; if (nextState.loadingAlerts !== loadingAlerts) return true; if (nextProps.isLoading !== isLoading) return true; - if (JSON.stringify(nextProps.filterParams) !== JSON.stringify(filterParams)) return true; - if (JSON.stringify(nextProps.indexPattern) !== JSON.stringify(indexPattern)) return true; - if (JSON.stringify(nextState.tacticsCount) !== JSON.stringify(tacticsCount)) return true; - if (JSON.stringify(nextState.selectedTactics) !== JSON.stringify(selectedTactics)) return true; + if (JSON.stringify(nextProps.filterParams) !== JSON.stringify(filterParams)) + return true; + if (JSON.stringify(nextProps.indexPattern) !== JSON.stringify(indexPattern)) + return true; + if (JSON.stringify(nextState.tacticsCount) !== JSON.stringify(tacticsCount)) + return true; + if ( + JSON.stringify(nextState.selectedTactics) !== + JSON.stringify(selectedTactics) + ) + return true; return false; } async componentDidUpdate(prevProps) { const { isLoading, tacticsObject } = this.props; if ( - JSON.stringify(prevProps.tacticsObject) !== JSON.stringify(tacticsObject) || + JSON.stringify(prevProps.tacticsObject) !== + JSON.stringify(tacticsObject) || isLoading !== prevProps.isLoading ) { this.getTacticsCount(this.state.firstTime); @@ -125,12 +134,16 @@ export class Tactics extends Component { // TODO: use `status` and `statusText` to show errors // @ts-ignore const { data } = await getElasticAlerts(indexPattern, filterParams, aggs); - const { buckets } = data.aggregations.tactics; + const buckets = data?.aggregations?.tactics?.buckets || []; if (firstTime) { - this.initTactics(buckets); // top tactics are checked on component mount + this.initTactics(); // top tactics are checked on component mount } this._isMount && - this.setState({ tacticsCount: buckets, loadingAlerts: false, firstTime: false }); + this.setState({ + tacticsCount: buckets, + loadingAlerts: false, + firstTime: false, + }); } catch (error) { const options = { context: `${Tactics.name}.getTacticsCount`, @@ -154,7 +167,8 @@ export class Tactics extends Component { } facetClicked(id) { - const { selectedTactics: oldSelected, onChangeSelectedTactics } = this.props; + const { selectedTactics: oldSelected, onChangeSelectedTactics } = + this.props; const selectedTactics = { ...oldSelected, [id]: !oldSelected[id], @@ -166,13 +180,14 @@ export class Tactics extends Component { const { tacticsCount } = this.state; const { selectedTactics } = this.props; const tacticsIds = Object.keys(this.props.tacticsObject); - const tacticsList: Array = tacticsIds.map((item) => { - const quantity = (tacticsCount.find((tactic) => tactic.key === item) || {}).doc_count || 0; + const tacticsList: Array = tacticsIds.map(item => { + const quantity = + (tacticsCount.find(tactic => tactic.key === item) || {}).doc_count || 0; return { id: item, label: item, quantity, - onClick: (id) => this.facetClicked(id), + onClick: id => this.facetClicked(id), }; }); @@ -180,7 +195,7 @@ export class Tactics extends Component { <> {tacticsList .sort((a, b) => b.quantity - a.quantity) - .map((facet) => { + .map(facet => { let iconNode; return ( facet.onClick(facet.id) : undefined} + onClick={ + facet.onClick ? () => facet.onClick(facet.id) : undefined + } > {facet.label} @@ -203,7 +220,7 @@ export class Tactics extends Component { checkAllChecked(tacticList: any[]) { const { selectedTactics } = this.props; let allSelected = true; - tacticList.forEach((item) => { + tacticList.forEach(item => { if (!selectedTactics[item.id]) allSelected = false; }); @@ -215,7 +232,7 @@ export class Tactics extends Component { onCheckAllClick() { const allSelected = !this.state.allSelected; const { selectedTactics, onChangeSelectedTactics } = this.props; - Object.keys(selectedTactics).map((item) => { + Object.keys(selectedTactics).map(item => { selectedTactics[item] = allSelected; }); @@ -233,7 +250,7 @@ export class Tactics extends Component { selectAll(status) { const { selectedTactics, onChangeSelectedTactics } = this.props; - Object.keys(selectedTactics).map((item) => { + Object.keys(selectedTactics).map(item => { selectedTactics[item] = status; }); onChangeSelectedTactics(selectedTactics); @@ -247,7 +264,7 @@ export class Tactics extends Component { items: [ { name: 'Select all', - icon: , + icon: , onClick: () => { this.closePopover(); this.selectAll(true); @@ -255,7 +272,7 @@ export class Tactics extends Component { }, { name: 'Unselect all', - icon: , + icon: , onClick: () => { this.closePopover(); this.selectAll(false); @@ -265,25 +282,34 @@ export class Tactics extends Component { }, ]; return ( -
+
- +

Tactics

- + this.onGearButtonClick()} aria-label={'tactics options'} > } isOpen={this.state.isPopoverOpen} - panelPaddingSize="none" + panelPaddingSize='none' closePopover={() => this.closePopover()} > @@ -292,7 +318,7 @@ export class Tactics extends Component {
{this.props.isLoading ? ( - + ) : ( {this.getTacticsList()} diff --git a/plugins/main/public/components/overview/mitre/components/techniques/techniques.tsx b/plugins/main/public/components/overview/mitre/components/techniques/techniques.tsx index 50c4f10b28..2daf6834cb 100644 --- a/plugins/main/public/components/overview/mitre/components/techniques/techniques.tsx +++ b/plugins/main/public/components/overview/mitre/components/techniques/techniques.tsx @@ -85,11 +85,21 @@ export const Techniques = withWindowSize( } shouldComponentUpdate(nextProps, nextState) { - const { filterParams, indexPattern, selectedTactics, isLoading } = this.props; + const { filterParams, indexPattern, selectedTactics, isLoading } = + this.props; if (nextProps.isLoading !== isLoading) return true; - if (JSON.stringify(nextProps.filterParams) !== JSON.stringify(filterParams)) return true; - if (JSON.stringify(nextProps.indexPattern) !== JSON.stringify(indexPattern)) return true; - if (JSON.stringify(nextState.selectedTactics) !== JSON.stringify(selectedTactics)) + if ( + JSON.stringify(nextProps.filterParams) !== JSON.stringify(filterParams) + ) + return true; + if ( + JSON.stringify(nextProps.indexPattern) !== JSON.stringify(indexPattern) + ) + return true; + if ( + JSON.stringify(nextState.selectedTactics) !== + JSON.stringify(selectedTactics) + ) return true; return false; } @@ -97,9 +107,11 @@ export const Techniques = withWindowSize( componentDidUpdate(prevProps) { const { isLoading, tacticsObject, filters } = this.props; if ( - JSON.stringify(prevProps.tacticsObject) !== JSON.stringify(tacticsObject) || + JSON.stringify(prevProps.tacticsObject) !== + JSON.stringify(tacticsObject) || isLoading !== prevProps.isLoading || - JSON.stringify(prevProps.filterParams) !== JSON.stringify(this.props.filterParams) + JSON.stringify(prevProps.filterParams) !== + JSON.stringify(this.props.filterParams) ) this.getTechniquesCount(); } @@ -108,7 +120,12 @@ export const Techniques = withWindowSize( this._isMount = false; } - showToast(color: string, title: string = '', text: string = '', time: number = 3000) { + showToast( + color: string, + title: string = '', + text: string = '', + time: number = 3000, + ) { getToasts().add({ color: color, title: title, @@ -134,9 +151,14 @@ export const Techniques = withWindowSize( this._isMount && this.setState({ loadingAlerts: true }); // TODO: use `status` and `statusText` to show errors // @ts-ignore - const { data, status, statusText } = await getElasticAlerts(indexPattern, filters, aggs); - const { buckets } = data.aggregations.techniques; - this._isMount && this.setState({ techniquesCount: buckets, loadingAlerts: false }); + const { data, status, statusText } = await getElasticAlerts( + indexPattern, + filters, + aggs, + ); + const buckets = data?.aggregations?.techniques?.buckets || []; + this._isMount && + this.setState({ techniquesCount: buckets, loadingAlerts: false }); } catch (error) { const options = { context: `${Techniques.name}.getTechniquesCount`, @@ -163,23 +185,31 @@ export const Techniques = withWindowSize( items: [ { name: 'Filter for value', - icon: , + icon: , onClick: () => { this.closeActionsMenu(); - this.addFilter({ key: 'rule.mitre.id', value: techniqueID, negate: false }); + this.addFilter({ + key: 'rule.mitre.id', + value: techniqueID, + negate: false, + }); }, }, { name: 'Filter out value', - icon: , + icon: , onClick: () => { this.closeActionsMenu(); - this.addFilter({ key: 'rule.mitre.id', value: techniqueID, negate: true }); + this.addFilter({ + key: 'rule.mitre.id', + value: techniqueID, + negate: true, + }); }, }, { name: 'View technique details', - icon: , + icon: , onClick: () => { this.closeActionsMenu(); this.showFlyout(techniqueID); @@ -192,7 +222,11 @@ export const Techniques = withWindowSize( techniqueColumnsResponsive() { if (this.props && this.props.windowSize) { - return this.props.windowSize.width < 930 ? 2 : this.props.windowSize.width < 1200 ? 3 : 4; + return this.props.windowSize.width < 930 + ? 2 + : this.props.windowSize.width < 1200 + ? 3 + : 4; } else { return 4; } @@ -224,10 +258,16 @@ export const Techniques = withWindowSize( const params = { limit: limitResults }; this.setState({ isSearching: true }); const output = await this.getMitreTechniques(params); - const totalItems = (((output || {}).data || {}).data || {}).total_affected_items; + const totalItems = (((output || {}).data || {}).data || {}) + .total_affected_items; let mitreTechniques = []; mitreTechniques.push(...output.data.data.affected_items); - if (totalItems && output.data && output.data.data && totalItems > limitResults) { + if ( + totalItems && + output.data && + output.data.data && + totalItems > limitResults + ) { const extraResults = await Promise.all( Array(Math.ceil((totalItems - params.limit) / params.limit)) .fill() @@ -237,7 +277,7 @@ export const Techniques = withWindowSize( offset: limitResults * (1 + index), }); return response.data.data.affected_items; - }) + }), ); mitreTechniques.push(...extraResults.flat()); } @@ -246,16 +286,22 @@ export const Techniques = withWindowSize( buildObjTechniques(techniques) { const techniquesObj = []; - techniques.forEach((element) => { - const mitreObj = this.state.mitreTechniques.find((item) => item.id === element); + techniques.forEach(element => { + const mitreObj = this.state.mitreTechniques.find( + item => item.id === element, + ); if (mitreObj) { const mitreTechniqueName = mitreObj.name; const mitreTechniqueID = mitreObj.source === MITRE_ATTACK ? mitreObj.external_id - : mitreObj.references.find((item) => item.source === MITRE_ATTACK).external_id; + : mitreObj.references.find(item => item.source === MITRE_ATTACK) + .external_id; mitreTechniqueID - ? techniquesObj.push({ id: mitreTechniqueID, name: mitreTechniqueName }) + ? techniquesObj.push({ + id: mitreTechniqueID, + name: mitreTechniqueName, + }) : ''; } }); @@ -268,47 +314,59 @@ export const Techniques = withWindowSize( let hash = {}; let tacticsToRender: Array = []; const currentTechniques = Object.keys(tacticsObject) - .map((tacticsKey) => ({ + .map(tacticsKey => ({ tactic: tacticsKey, - techniques: this.buildObjTechniques(tacticsObject[tacticsKey].techniques), + techniques: this.buildObjTechniques( + tacticsObject[tacticsKey].techniques, + ), })) - .filter((tactic) => this.props.selectedTactics[tactic.tactic]) - .map((tactic) => tactic.techniques) + .filter(tactic => this.props.selectedTactics[tactic.tactic]) + .map(tactic => tactic.techniques) .flat() - .filter((techniqueID, index, array) => array.indexOf(techniqueID) === index); + .filter( + (techniqueID, index, array) => array.indexOf(techniqueID) === index, + ); tacticsToRender = currentTechniques - .filter((technique) => + .filter(technique => this.state.filteredTechniques ? this.state.filteredTechniques.includes(technique.id) : technique.id && hash[technique.id] ? false - : (hash[technique.id] = true) + : (hash[technique.id] = true), ) - .map((technique) => { + .map(technique => { return { id: technique.id, label: `${technique.id} - ${technique.name}`, quantity: - (techniquesCount.find((item) => item.key === technique.id) || {}).doc_count || 0, + (techniquesCount.find(item => item.key === technique.id) || {}) + .doc_count || 0, }; }) - .filter((technique) => (this.state.hideAlerts ? technique.quantity !== 0 : true)); + .filter(technique => + this.state.hideAlerts ? technique.quantity !== 0 : true, + ); const tacticsToRenderOrdered = tacticsToRender .sort((a, b) => b.quantity - a.quantity) .map((item, idx) => { const tooltipContent = `View details of ${item.label} (${item.id})`; const toolTipAnchorClass = - 'wz-display-inline-grid' + (this.state.hover === item.id ? ' wz-mitre-width' : ' '); + 'wz-display-inline-grid' + + (this.state.hover === item.id ? ' wz-mitre-width' : ' '); return ( this.setState({ hover: item.id })} onMouseLeave={() => this.setState({ hover: '' })} key={idx} - style={{ border: '1px solid #8080804a', maxWidth: 'calc(25% - 8px)', maxHeight: 41 }} + style={{ + border: '1px solid #8080804a', + maxWidth: 'calc(25% - 8px)', + maxHeight: 41, + }} > this.showFlyout(item.id)} > @@ -340,25 +398,31 @@ export const Techniques = withWindowSize( {this.state.hover === item.id && ( - + { + onClick={e => { this.openDashboard(e, item.id); e.stopPropagation(); }} - color="primary" - type="visualizeApp" + color='primary' + type='visualizeApp' > {' '}   - + { + onClick={e => { this.openDiscover(e, item.id); e.stopPropagation(); }} - color="primary" - type="discoverApp" + color='primary' + type='discoverApp' > @@ -367,19 +431,28 @@ export const Techniques = withWindowSize( } isOpen={this.state.actionsOpen === item.id} closePopover={() => this.closeActionsMenu()} - panelPaddingSize="none" + panelPaddingSize='none' style={{ width: '100%' }} - anchorPosition="downLeft" + anchorPosition='downLeft' > - + ); }); - if (this.state.isSearching || this.state.loadingAlerts || this.props.isLoading) { + if ( + this.state.isSearching || + this.state.loadingAlerts || + this.props.isLoading + ) { return ( - - + + ); } @@ -387,7 +460,7 @@ export const Techniques = withWindowSize( return ( + ); } } openDiscover(e, techniqueID) { - this.addFilter({ key: 'rule.mitre.id', value: techniqueID, negate: false }); + this.addFilter({ + key: 'rule.mitre.id', + value: techniqueID, + negate: false, + }); this.props.onSelectedTabChanged('events'); } openDashboard(e, techniqueID) { - this.addFilter({ key: 'rule.mitre.id', value: techniqueID, negate: false }); + this.addFilter({ + key: 'rule.mitre.id', + value: techniqueID, + negate: false, + }); this.props.onSelectedTabChanged('dashboard'); } @@ -430,7 +515,8 @@ export const Techniques = withWindowSize( params: { query: filter.value }, type: 'phrase', negate: filter.negate || false, - index: AppState.getCurrentPattern() || getSettingDefaultValue('pattern'), + index: + AppState.getCurrentPattern() || getSettingDefaultValue('pattern'), }, query: { match_phrase: matchPhrase }, $state: { store: 'appState' }, @@ -438,13 +524,14 @@ export const Techniques = withWindowSize( filterManager.addFilters([newFilter]); } - onChange = (searchValue) => { + onChange = searchValue => { if (!searchValue) { - this._isMount && this.setState({ filteredTechniques: false, isSearching: false }); + this._isMount && + this.setState({ filteredTechniques: false, isSearching: false }); } }; - onSearch = async (searchValue) => { + onSearch = async searchValue => { try { if (searchValue) { this._isMount && this.setState({ isSearching: true }); @@ -453,12 +540,18 @@ export const Techniques = withWindowSize( search: searchValue, }, }); - const filteredTechniques = (((response || {}).data || {}).data.affected_items || []).map( - (item) => [item].filter((reference) => reference.source === MITRE_ATTACK)[0].external_id + const filteredTechniques = ( + ((response || {}).data || {}).data.affected_items || [] + ).map( + item => + [item].filter(reference => reference.source === MITRE_ATTACK)[0] + .external_id, ); - this._isMount && this.setState({ filteredTechniques, isSearching: false }); + this._isMount && + this.setState({ filteredTechniques, isSearching: false }); } else { - this._isMount && this.setState({ filteredTechniques: false, isSearching: false }); + this._isMount && + this.setState({ filteredTechniques: false, isSearching: false }); } } catch (error) { const options = { @@ -474,7 +567,8 @@ export const Techniques = withWindowSize( }, }; getErrorOrchestrator().handleError(options); - this._isMount && this.setState({ filteredTechniques: false, isSearching: false }); + this._isMount && + this.setState({ filteredTechniques: false, isSearching: false }); } }; async closeActionsMenu() { @@ -507,7 +601,7 @@ export const Techniques = withWindowSize(
- +

Techniques

@@ -518,26 +612,26 @@ export const Techniques = withWindowSize( Hide techniques with no alerts   this.hideAlerts()} + onChange={e => this.hideAlerts()} />
- + - +
{this.renderFacet()}
@@ -552,5 +646,5 @@ export const Techniques = withWindowSize(
); } - } + }, ); From 67f78319d72c16be03c1ec5003c58885cfac0ea4 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:28:31 +0100 Subject: [PATCH 51/64] Replace discover Docker (#6286) * Replace discover * Add changelog --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 2 +- .../common/modules/modules-defaults.js | 6 ++++- .../overview/docker/events/docker-columns.tsx | 22 +++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 plugins/main/public/components/overview/docker/events/docker-columns.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index c842e169d6..d68424a6da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6286](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6286) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) diff --git a/plugins/main/public/components/common/modules/modules-defaults.js b/plugins/main/public/components/common/modules/modules-defaults.js index 1aa0a53574..5e4e824109 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.js +++ b/plugins/main/public/components/common/modules/modules-defaults.js @@ -27,6 +27,7 @@ import { vulnerabilitiesColumns } from '../../overview/vulnerabilities/events/vu import { DashboardFim } from '../../overview/fim/dashboard/dashboard'; import { InventoryFim } from '../../overview/fim/inventory/inventory'; import React from 'react'; +import { dockerColumns } from '../../overview/docker/events/docker-columns'; import { googleCloudColumns } from '../../overview/google-cloud/events/google-cloud-columns'; import { amazonWebServicesColumns } from '../../overview/amazon-web-services/events/amazon-web-services-columns'; import { office365Columns } from '../../overview/office-panel/events/office-365-columns'; @@ -251,7 +252,10 @@ export const ModulesDefaults = { }, docker: { init: 'dashboard', - tabs: [DashboardTab, EventsTab], + tabs: [ + DashboardTab, + renderDiscoverTab(DEFAULT_INDEX_PATTERN, dockerColumns), + ], availableFor: ['manager', 'agent'], }, diff --git a/plugins/main/public/components/overview/docker/events/docker-columns.tsx b/plugins/main/public/components/overview/docker/events/docker-columns.tsx new file mode 100644 index 0000000000..1a3bb72832 --- /dev/null +++ b/plugins/main/public/components/overview/docker/events/docker-columns.tsx @@ -0,0 +1,22 @@ +import { tDataGridColumn } from '../../../common/data-grid'; + +export const dockerColumns: tDataGridColumn[] = [ + { + id: 'agent.name', + }, + { + id: 'data.docker.from', + }, + { + id: 'data.docker.Type', + }, + { + id: 'data.docker.Action', + }, + { + id: 'rule.description', + }, + { + id: 'rule.level', + }, +]; From 270bd8488a98f389944f1695f5b46046d9e76cb2 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:57:39 +0100 Subject: [PATCH 52/64] Fixed filebeat in development environments (#6433) Update filebeat curl in dev environments --- docker/osd-dev/dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/osd-dev/dev.yml b/docker/osd-dev/dev.yml index 9b8982cd5b..92c29e45af 100755 --- a/docker/osd-dev/dev.yml +++ b/docker/osd-dev/dev.yml @@ -204,8 +204,8 @@ services: mkdir -p /etc/filebeat echo admin | filebeat keystore add username --stdin --force echo ${PASSWORD}| filebeat keystore add password --stdin --force - curl -so /etc/filebeat/wazuh-template.json https://raw.githubusercontent.com/wazuh/wazuh/4.3/extensions/elasticsearch/7.x/wazuh-template.json - curl -s https://packages.wazuh.com/4.x/filebeat/wazuh-filebeat-0.4.tar.gz | tar -xvz -C /usr/share/filebeat/module + curl -so /etc/filebeat/wazuh-template.json https://raw.githubusercontent.com/wazuh/wazuh/v4.7.2/extensions/elasticsearch/7.x/wazuh-template.json + curl -s https://packages.wazuh.com/4.x/filebeat/wazuh-filebeat-0.3.tar.gz | tar -xvz -C /usr/share/filebeat/module # copy filebeat to preserve correct permissions without # affecting host filesystem cp /tmp/filebeat.yml /usr/share/filebeat/filebeat.yml From 7ae57cc74ad268d06a8bdf2317f1cc993e3500fe Mon Sep 17 00:00:00 2001 From: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:12:09 -0300 Subject: [PATCH 53/64] Bump revision 01 for 4.7.3 RC1 (#6437) * Update changelog * Update opensearch_dashboards.json * Update package json --- CHANGELOG.md | 2 +- plugins/main/opensearch_dashboards.json | 2 +- plugins/main/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596abb0be2..f8f5d044b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the Wazuh app project will be documented in this file. -## Wazuh v4.7.3 - OpenSearch Dashboards 2.8.0 - Revision 00 +## Wazuh v4.7.3 - OpenSearch Dashboards 2.8.0 - Revision 01 ### Added diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index 36ca2b458e..c2d141a13f 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.7.3-00", + "version": "4.7.3-01", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": [ "wazuh" diff --git a/plugins/main/package.json b/plugins/main/package.json index 4c0732a19c..799bcbc890 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", "version": "4.7.3", - "revision": "00", + "revision": "01", "pluginPlatform": { "version": "2.8.0" }, From f3d39043b1d021b1ef786ed1d710fba0476e9a7f Mon Sep 17 00:00:00 2001 From: Nicolas Agustin Guevara Pihen <42900763+Tostti@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:01:49 -0300 Subject: [PATCH 54/64] Bump revision 04 for 4.8.0 Beta 2 (#6445) Bump revision --- CHANGELOG.md | 2 +- plugins/main/common/api-info/endpoints.json | 2 ++ plugins/main/opensearch_dashboards.json | 4 ++-- plugins/main/package.json | 4 ++-- plugins/wazuh-check-updates/opensearch_dashboards.json | 2 +- plugins/wazuh-check-updates/package.json | 2 +- plugins/wazuh-core/opensearch_dashboards.json | 2 +- plugins/wazuh-core/package.json | 2 +- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24fadd3975..8945e1c847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the Wazuh app project will be documented in this file. -## Wazuh v4.8.0 - OpenSearch Dashboards 2.10.0 - Revision 03 +## Wazuh v4.8.0 - OpenSearch Dashboards 2.10.0 - Revision 04 ### Added diff --git a/plugins/main/common/api-info/endpoints.json b/plugins/main/common/api-info/endpoints.json index ac58e3d7d8..11c29300f4 100644 --- a/plugins/main/common/api-info/endpoints.json +++ b/plugins/main/common/api-info/endpoints.json @@ -1181,6 +1181,7 @@ "socket", "syscheck", "syslog_output", + "vulnerability-detection", "indexer", "aws-s3", "azure-logs", @@ -4845,6 +4846,7 @@ "socket", "syscheck", "syslog_output", + "vulnerability-detection", "indexer", "aws-s3", "azure-logs", diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index 222deca5a9..46bcb4532b 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.8.0-03", + "version": "4.8.0-04", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": [ "wazuh" @@ -30,4 +30,4 @@ ], "server": true, "ui": true -} +} \ No newline at end of file diff --git a/plugins/main/package.json b/plugins/main/package.json index b7bffe5a78..356da8ea6e 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", "version": "4.8.0", - "revision": "03", + "revision": "04", "pluginPlatform": { "version": "2.10.0" }, @@ -83,4 +83,4 @@ "redux-mock-store": "^1.5.4", "swagger-client": "^3.19.11" } -} +} \ No newline at end of file diff --git a/plugins/wazuh-check-updates/opensearch_dashboards.json b/plugins/wazuh-check-updates/opensearch_dashboards.json index 813fb902f3..017cbfa097 100644 --- a/plugins/wazuh-check-updates/opensearch_dashboards.json +++ b/plugins/wazuh-check-updates/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCheckUpdates", - "version": "4.8.0-03", + "version": "4.8.0-04", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-check-updates/package.json b/plugins/wazuh-check-updates/package.json index 9d4c6bd8de..542d76edcc 100644 --- a/plugins/wazuh-check-updates/package.json +++ b/plugins/wazuh-check-updates/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-check-updates", "version": "4.8.0", - "revision": "03", + "revision": "04", "pluginPlatform": { "version": "2.10.0" }, diff --git a/plugins/wazuh-core/opensearch_dashboards.json b/plugins/wazuh-core/opensearch_dashboards.json index 17a130bcec..964f9f3af6 100644 --- a/plugins/wazuh-core/opensearch_dashboards.json +++ b/plugins/wazuh-core/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCore", - "version": "4.8.0-03", + "version": "4.8.0-04", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-core/package.json b/plugins/wazuh-core/package.json index 0c9b8cb8c7..ab19882343 100644 --- a/plugins/wazuh-core/package.json +++ b/plugins/wazuh-core/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-core", "version": "4.8.0", - "revision": "03", + "revision": "04", "pluginPlatform": { "version": "2.10.0" }, From f6caa12ed4a81c6003effd8c07285ecee64ae413 Mon Sep 17 00:00:00 2001 From: Ian Yenien Serrano <63758389+yenienserrano@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:07:55 +0100 Subject: [PATCH 55/64] Support new Opensearch dashboard version 2.12.0 (#6440) * Update dev.sh * Update OSD version in plugins and changelog * Update optimazer warnings * Change breadcrumb in register agent for "Endpoint" * Fix snapshot * Fix snapshot * Remove dependency wazuh-endpoint * Fix test --- CHANGELOG.md | 2 +- docker/osd-dev/dev.sh | 6 +- plugins/main/opensearch_dashboards.json | 3 +- plugins/main/package.json | 2 +- .../__snapshots__/agent-status.test.tsx.snap | 12 +- .../__snapshots__/agent-synced.test.tsx.snap | 6 +- .../column-with-status-icon.test.tsx.snap | 6 +- .../stats/__snapshots__/table.test.tsx.snap | 20 ++- .../__snapshots__/inventory.test.tsx.snap | 114 +++++++++++++++--- .../error-boundary.test.tsx.snap | 10 +- .../form/__snapshots__/index.test.tsx.snap | 24 +++- .../with-error-boundary.test.tsx.snap | 10 +- .../__snapshots__/table-default.test.tsx.snap | 10 +- .../table-with-search-bar.test.tsx.snap | 10 +- .../__snapshots__/table-wz-api.test.tsx.snap | 10 +- .../export-table-csv.test.tsx.snap | 10 +- .../register-agent/register-agent.tsx | 5 +- .../__snapshots__/agents-table.test.tsx.snap | 36 +++++- .../__snapshots__/check-result.test.tsx.snap | 10 +- .../__snapshots__/intelligence.test.tsx.snap | 24 +++- .../__snapshots__/aql.test.tsx.snap | 6 +- .../__snapshots__/generalInfo.test.tsx.snap | 12 +- .../__snapshots__/update-detail.test.tsx.snap | 18 ++- .../SubscriptionTab.test.tsx.snap | 10 +- .../__snapshots__/api-auth-tab.test.tsx.snap | 10 +- .../__snapshots__/general-tab.test.tsx.snap | 10 +- .../angular/doc_table/_doc_table.scss | 2 +- .../utils/fontawesome/scss/_fixed-width.scss | 2 +- .../utils/fontawesome/scss/_larger.scss | 20 ++- .../public/utils/fontawesome/scss/_list.scss | 8 +- .../utils/fontawesome/scss/_variables.scss | 2 +- .../server/routes/wazuh-reporting.test.ts | 11 +- plugins/wazuh-check-updates/package.json | 2 +- .../dismiss-notification-check.test.tsx.snap | 6 +- plugins/wazuh-core/package.json | 2 +- plugins/wazuh-endpoints/package.json | 2 +- 36 files changed, 345 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d68424a6da..324f3316ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the Wazuh app project will be documented in this file. -## Wazuh v4.9.0 - OpenSearch Dashboards 2.11.0 - Revision 00 +## Wazuh v4.9.0 - OpenSearch Dashboards 2.12.0 - Revision 00 ### Added diff --git a/docker/osd-dev/dev.sh b/docker/osd-dev/dev.sh index 33ae08a32f..9a03af5bee 100755 --- a/docker/osd-dev/dev.sh +++ b/docker/osd-dev/dev.sh @@ -13,6 +13,8 @@ os_versions=( '2.9.0' '2.10.0' '2.11.0' + '2.11.1' + '2.12.0' ) osd_versions=( @@ -28,8 +30,8 @@ osd_versions=( '2.9.0' '2.10.0' '2.11.0' - '4.6.0' - '4.7.0' + '2.11.1' + '2.12.0' ) wzs_version=( diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index d2beb8d5a5..7af70c4235 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -18,8 +18,7 @@ "opensearchDashboardsUtils", "opensearchDashboardsLegacy", "wazuhCheckUpdates", - "wazuhCore", - "wazuhEndpoints" + "wazuhCore" ], "optionalPlugins": [ "security", diff --git a/plugins/main/package.json b/plugins/main/package.json index 9f1cc623d6..1a003dc499 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -3,7 +3,7 @@ "version": "4.9.0", "revision": "00", "pluginPlatform": { - "version": "2.11.0" + "version": "2.12.0" }, "description": "Wazuh dashboard", "keywords": [ diff --git a/plugins/main/public/components/agents/__snapshots__/agent-status.test.tsx.snap b/plugins/main/public/components/agents/__snapshots__/agent-status.test.tsx.snap index 6253e66ffd..e4b3c3708c 100644 --- a/plugins/main/public/components/agents/__snapshots__/agent-status.test.tsx.snap +++ b/plugins/main/public/components/agents/__snapshots__/agent-status.test.tsx.snap @@ -26,7 +26,11 @@ exports[`AgentStatus component Renders status indicator with the its color and t viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
+ > + +
`; diff --git a/plugins/main/public/components/agents/__snapshots__/agent-synced.test.tsx.snap b/plugins/main/public/components/agents/__snapshots__/agent-synced.test.tsx.snap index de773fa3b7..21088099b7 100644 --- a/plugins/main/public/components/agents/__snapshots__/agent-synced.test.tsx.snap +++ b/plugins/main/public/components/agents/__snapshots__/agent-synced.test.tsx.snap @@ -23,7 +23,11 @@ Array [ viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
+ > + +
- - + > + + + Start: @@ -459,7 +463,7 @@ exports[`AgentStatTable component Renders correctly to match the snapshot 1`] = size="m" type="importAction" > - - + > + + + + > + + @@ -2245,7 +2249,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2354,7 +2362,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2408,7 +2420,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2582,7 +2598,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2611,7 +2631,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2720,7 +2744,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2934,7 +2962,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -2963,7 +2995,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3072,7 +3108,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3126,7 +3166,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3303,7 +3347,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3332,7 +3380,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3441,7 +3493,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3495,7 +3551,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3675,7 +3735,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3704,7 +3768,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3813,7 +3881,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -3868,7 +3940,11 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/main/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/plugins/main/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap index 9a0cb7b29a..b50866b573 100644 --- a/plugins/main/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap +++ b/plugins/main/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap @@ -57,7 +57,7 @@ exports[`ErrorBoundary component renders correctly to match the snapshot 1`] = ` size="xxl" type="faceSad" > - - + > + + + + > + +
@@ -357,7 +361,11 @@ exports[`[component] InputForm Renders correctly to match the snapshot: Input: s viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
@@ -396,7 +404,11 @@ exports[`[component] InputForm Renders correctly to match the snapshot: Input: s viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + + > + + diff --git a/plugins/main/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/plugins/main/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap index 1a84b4ea0f..509fa987ee 100644 --- a/plugins/main/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap +++ b/plugins/main/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap @@ -62,7 +62,7 @@ exports[`withErrorBoundary hoc implementation renders correctly to match the sna size="xxl" type="faceSad" > - - + > + + +
- - + > + + +
- - + > + + +
- - + > + + +
- - + > + + + + > + + @@ -80,7 +84,11 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -109,7 +117,11 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -143,7 +155,11 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -249,7 +265,11 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -303,7 +323,11 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap b/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap index 436f919ef7..73cd80d050 100644 --- a/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap +++ b/plugins/main/public/components/health-check/components/__snapshots__/check-result.test.tsx.snap @@ -54,7 +54,7 @@ exports[`Check result component should render a Check result screen 1`] = ` onFocus={[Function]} type="clock" > - - + > + + + diff --git a/plugins/main/public/components/overview/mitre_attack_intelligence/__snapshots__/intelligence.test.tsx.snap b/plugins/main/public/components/overview/mitre_attack_intelligence/__snapshots__/intelligence.test.tsx.snap index adf70d0cc4..2fe8a49688 100644 --- a/plugins/main/public/components/overview/mitre_attack_intelligence/__snapshots__/intelligence.test.tsx.snap +++ b/plugins/main/public/components/overview/mitre_attack_intelligence/__snapshots__/intelligence.test.tsx.snap @@ -13,7 +13,11 @@ exports[`Module Mitre Att&ck intelligence container should render permissions pr viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
@@ -104,7 +108,11 @@ exports[`Module Mitre Att&ck intelligence container should render the component viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
@@ -260,7 +268,11 @@ exports[`Module Mitre Att&ck intelligence container should render the component viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + @@ -332,7 +344,11 @@ exports[`Module Mitre Att&ck intelligence container should render the component viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/main/public/components/search-bar/query-language/__snapshots__/aql.test.tsx.snap b/plugins/main/public/components/search-bar/query-language/__snapshots__/aql.test.tsx.snap index 0ef68d2e9e..3f9bd54fc2 100644 --- a/plugins/main/public/components/search-bar/query-language/__snapshots__/aql.test.tsx.snap +++ b/plugins/main/public/components/search-bar/query-language/__snapshots__/aql.test.tsx.snap @@ -39,7 +39,11 @@ exports[`SearchBar component Renders correctly to match the snapshot of query la viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/main/public/components/settings/about/__snapshots__/generalInfo.test.tsx.snap b/plugins/main/public/components/settings/about/__snapshots__/generalInfo.test.tsx.snap index 50897d09a9..c47b5eefec 100644 --- a/plugins/main/public/components/settings/about/__snapshots__/generalInfo.test.tsx.snap +++ b/plugins/main/public/components/settings/about/__snapshots__/generalInfo.test.tsx.snap @@ -76,7 +76,11 @@ exports[`SettingsAboutGeneralInfo component should render a component 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + +
+ > + +
diff --git a/plugins/main/public/components/settings/api/available-updates-flyout/__snapshots__/update-detail.test.tsx.snap b/plugins/main/public/components/settings/api/available-updates-flyout/__snapshots__/update-detail.test.tsx.snap index 08a8b8e821..79276268d1 100644 --- a/plugins/main/public/components/settings/api/available-updates-flyout/__snapshots__/update-detail.test.tsx.snap +++ b/plugins/main/public/components/settings/api/available-updates-flyout/__snapshots__/update-detail.test.tsx.snap @@ -27,7 +27,11 @@ exports[`UpdateDetail component should return the UpdateDetail component 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + + > + + @@ -147,7 +155,11 @@ exports[`UpdateDetail component should return the UpdateDetail component 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/main/public/controllers/management/components/management/configuration/office365/components/SubscriptionTab/__snapshots__/SubscriptionTab.test.tsx.snap b/plugins/main/public/controllers/management/components/management/configuration/office365/components/SubscriptionTab/__snapshots__/SubscriptionTab.test.tsx.snap index e0d47aa5f6..6af540478d 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/office365/components/SubscriptionTab/__snapshots__/SubscriptionTab.test.tsx.snap +++ b/plugins/main/public/controllers/management/components/management/configuration/office365/components/SubscriptionTab/__snapshots__/SubscriptionTab.test.tsx.snap @@ -152,7 +152,7 @@ exports[`SubscriptionTab component renders correctly to match the snapshot 1`] = size="m" type="questionInCircle" > - - + > + + + - - + > + + + - - + > + + + li { position: relative; } + > li { + position: relative; + } } .#{$fa-css-prefix}-li { position: absolute; left: -$fa-li-width; width: $fa-li-width; - top: (2em / 14); + top: calc(2em / 14); text-align: center; &.#{$fa-css-prefix}-lg { - left: -$fa-li-width + (4em / 14); + left: -$fa-li-width + calc(4em / 14); } } diff --git a/plugins/main/public/utils/fontawesome/scss/_variables.scss b/plugins/main/public/utils/fontawesome/scss/_variables.scss index a5a89ef97b..a5a4420d1b 100644 --- a/plugins/main/public/utils/fontawesome/scss/_variables.scss +++ b/plugins/main/public/utils/fontawesome/scss/_variables.scss @@ -9,7 +9,7 @@ $fa-css-prefix: fa !default; $fa-version: "4.6.3" !default; $fa-border-color: #eee !default; $fa-inverse: #fff !default; -$fa-li-width: (30em / 14) !default; +$fa-li-width: calc(30em / 14) !default; $fa-var-500px: "\f26e"; $fa-var-adjust: "\f042"; diff --git a/plugins/main/server/routes/wazuh-reporting.test.ts b/plugins/main/server/routes/wazuh-reporting.test.ts index 075f411d7b..231eaf0382 100644 --- a/plugins/main/server/routes/wazuh-reporting.test.ts +++ b/plugins/main/server/routes/wazuh-reporting.test.ts @@ -214,11 +214,11 @@ describe('[endpoint] PUT /utils/configuration', () => { // If any of the parameters is changed this variable should be updated with the new md5 it.each` footer | header | responseStatusCode | expectedMD5 | tab - ${null} | ${null} | ${200} | ${'301281824427c6ea8546fd14ee1aa5d8'} | ${'pm'} - ${'Custom\nFooter'} | ${'info@company.com\nFake Avenue 123'} | ${200} | ${'c2adfd7ab05ae3ed1548abd3c8be8f7e'} | ${'general'} - ${''} | ${''} | ${200} | ${'06726f42a4129dd47262ea7228939006'} | ${'fim'} - ${'Custom Footer'} | ${null} | ${200} | ${'1ea187181c307a4be5e90a38f614c42d'} | ${'aws'} - ${null} | ${'Custom Header'} | ${200} | ${'f2fc0804eb52ebca21291eb5a40dec35'} | ${'gcp'} + ${null} | ${null} | ${200} | ${'7f497384a622d116b260e14c7bd9d0dc'} | ${'pm'} + ${'Custom\nFooter'} | ${'info@company.com\nFake Avenue 123'} | ${200} | ${'db832dc7cb2eb918d5e2df1f6cecb8b1'} | ${'general'} + ${''} | ${''} | ${200} | ${'cb39c81684c5a9b19cbf5a38dc19061c'} | ${'fim'} + ${'Custom Footer'} | ${null} | ${200} | ${'11603a29c2b90979161c6e1b09cfe345'} | ${'aws'} + ${null} | ${'Custom Header'} | ${200} | ${'67d868e5655a1a7068f457348a8a35c8'} | ${'gcp'} `( `Set custom report header and footer - Verify PDF output`, async ({ footer, header, responseStatusCode, expectedMD5, tab }) => { @@ -257,7 +257,6 @@ describe('[endpoint] PUT /utils/configuration', () => { .put('/utils/configuration') .send(configurationBody) .expect(responseStatusCode); - return; if (typeof footer == 'string') { expect( responseConfig.body?.data?.updatedConfiguration?.[ diff --git a/plugins/wazuh-check-updates/package.json b/plugins/wazuh-check-updates/package.json index 4804025d53..0c24d9e311 100644 --- a/plugins/wazuh-check-updates/package.json +++ b/plugins/wazuh-check-updates/package.json @@ -3,7 +3,7 @@ "version": "4.9.0", "revision": "00", "pluginPlatform": { - "version": "2.11.0" + "version": "2.12.0" }, "description": "Wazuh Check Updates", "private": true, diff --git a/plugins/wazuh-check-updates/public/components/__snapshots__/dismiss-notification-check.test.tsx.snap b/plugins/wazuh-check-updates/public/components/__snapshots__/dismiss-notification-check.test.tsx.snap index 03d28de0a9..6d22dc8887 100644 --- a/plugins/wazuh-check-updates/public/components/__snapshots__/dismiss-notification-check.test.tsx.snap +++ b/plugins/wazuh-check-updates/public/components/__snapshots__/dismiss-notification-check.test.tsx.snap @@ -32,7 +32,11 @@ exports[`DismissNotificationCheck component should render the check 1`] = ` viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" - /> + > + + diff --git a/plugins/wazuh-core/package.json b/plugins/wazuh-core/package.json index 1317a3b47c..5ed3e6c72f 100644 --- a/plugins/wazuh-core/package.json +++ b/plugins/wazuh-core/package.json @@ -3,7 +3,7 @@ "version": "4.9.0", "revision": "00", "pluginPlatform": { - "version": "2.11.0" + "version": "2.12.0" }, "description": "Wazuh Core", "private": true, diff --git a/plugins/wazuh-endpoints/package.json b/plugins/wazuh-endpoints/package.json index e79948329b..6fb24b72b5 100644 --- a/plugins/wazuh-endpoints/package.json +++ b/plugins/wazuh-endpoints/package.json @@ -3,7 +3,7 @@ "version": "4.9.0", "revision": "00", "pluginPlatform": { - "version": "2.11.0" + "version": "2.12.0" }, "description": "Wazuh Endpoints", "private": true, From 1bc5bb64c33022abe389132093e70d48ce9838c2 Mon Sep 17 00:00:00 2001 From: Luciano Gorza <103193307+lucianogorza@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:08:51 -0300 Subject: [PATCH 56/64] Select agents and add/remove groups (#6274) * Add global action to agents table * Add global action remove groups from agents * Add warning to remove groups from agents * Add results to modal * Improve global actions to agent table * Improve modal result * Manage API response * Improve result modal * Fix table layout * Clear table selection on refresh * Fix filters and clear selection on sort and pagination * Fix filters when user type * Improve parameters in service funtions * Paginate getAgents and getGroups * Paginate add and remove agents to groups * Update CHANGELOG * Update test snapshots * Fix pageSize on add-remove agents * Fix snapshot * Fix snapshot checkbox id and label * Fix snapshot checkbox id and label in Mobile * Add unit test for services * Add unit test for hooks * Add unit test for React components * Update snapshots * Remove comments --- CHANGELOG.md | 2 + .../__snapshots__/inventory.test.tsx.snap | 9950 +++++++++-------- .../__snapshots__/table-wz-api.test.tsx.snap | 1153 +- .../common/tables/table-with-search-bar.tsx | 6 + .../components/common/tables/table-wz-api.tsx | 112 +- .../endpoints-summary/hooks/agents.test.ts | 38 + .../endpoints-summary/hooks/agents.ts | 11 +- .../endpoints-summary/hooks/groups.test.ts | 44 + .../endpoints-summary/hooks/groups.ts | 2 +- .../endpoints-summary/hooks/index.ts | 1 + .../components/endpoints-summary/index.tsx | 2 +- .../services/add-agent-to-group.tsx | 13 +- .../services/add-agents-to-group.tsx | 9 + .../services/get-agents.test.tsx | 85 + .../endpoints-summary/services/get-agents.tsx | 54 + .../services/get-groups.test.tsx | 78 + .../endpoints-summary/services/get-groups.tsx | 56 +- .../services/get-total-agents.tsx | 12 - .../endpoints-summary/services/index.tsx | 5 +- .../services/paginated-agents-group.test.tsx | 205 + .../services/paginated-agents-group.tsx | 109 + .../services/remove-agent-from-group.tsx | 6 - .../services/remove-agent-from-groups.tsx | 14 +- .../services/remove-agents-from-group.tsx | 9 + .../__snapshots__/agents-table.test.tsx.snap | 2676 +++-- .../edit-groups-modal.test.tsx.snap | 15 + .../table/{ => actions}/actions.tsx | 16 +- .../table/actions/edit-groups-modal.test.tsx | 118 + .../table/{ => actions}/edit-groups-modal.tsx | 52 +- .../table/agents-table.test.tsx | 39 +- .../endpoints-summary/table/agents-table.tsx | 357 +- .../endpoints-summary/table/columns.tsx | 178 + .../global-actions.test.tsx.snap | 43 + .../edit-groups-modal.test.tsx.snap | 8 + .../edit-groups/edit-groups-modal.test.tsx | 100 + .../edit-groups/edit-groups-modal.tsx | 314 + .../global-actions/edit-groups/result.tsx | 264 + .../global-actions/global-actions.test.tsx | 56 + .../table/global-actions/global-actions.tsx | 131 + .../components/endpoints-summary/types.ts | 32 + .../__snapshots__/intelligence.test.tsx.snap | 402 +- .../main/public/react-services/wz-request.ts | 25 +- 42 files changed, 9735 insertions(+), 7067 deletions(-) create mode 100644 plugins/main/public/components/endpoints-summary/hooks/agents.test.ts create mode 100644 plugins/main/public/components/endpoints-summary/hooks/groups.test.ts create mode 100644 plugins/main/public/components/endpoints-summary/services/add-agents-to-group.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/get-agents.test.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/get-agents.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/get-groups.test.tsx delete mode 100644 plugins/main/public/components/endpoints-summary/services/get-total-agents.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/paginated-agents-group.test.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/paginated-agents-group.tsx delete mode 100644 plugins/main/public/components/endpoints-summary/services/remove-agent-from-group.tsx create mode 100644 plugins/main/public/components/endpoints-summary/services/remove-agents-from-group.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/actions/__snapshots__/edit-groups-modal.test.tsx.snap rename plugins/main/public/components/endpoints-summary/table/{ => actions}/actions.tsx (82%) create mode 100644 plugins/main/public/components/endpoints-summary/table/actions/edit-groups-modal.test.tsx rename plugins/main/public/components/endpoints-summary/table/{ => actions}/edit-groups-modal.tsx (73%) create mode 100644 plugins/main/public/components/endpoints-summary/table/columns.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/__snapshots__/global-actions.test.tsx.snap create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/edit-groups/__snapshots__/edit-groups-modal.test.tsx.snap create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/edit-groups/edit-groups-modal.test.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/edit-groups/edit-groups-modal.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/edit-groups/result.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/global-actions.test.tsx create mode 100644 plugins/main/public/components/endpoints-summary/table/global-actions/global-actions.tsx create mode 100644 plugins/main/public/components/endpoints-summary/types.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 324f3316ba..d17237185e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to the Wazuh app project will be documented in this file. - Support for Wazuh 4.9.0 - Added AngularJS dependencies [#6145](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6145) +- Added edit groups action to Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) +- Added global actions add agents to groups and remove agents from groups to Endpoints Summary [#6274](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6274) ### Changed diff --git a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap index 37bcbeb939..665925c7d8 100644 --- a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap +++ b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap @@ -129,185 +129,262 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network interfaces - - (0) - -

-
- + Network interfaces + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
- -
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + - - - - + + + + + + +
+
+ + No items found + +
+
- + + + +
+
+
+
+
-
- - - - - - - - - - + + + + + + + +
-
+
+
+

+ Network ports + + (0) + +

+
+
+ +
+
+
-
- - +
-
+ + + + +
+
+
+
+
- -
+ +
+
+ +
+
+ + + + + + +
+
+
+
+
- -
- + + - -
-
- +
- No items found - - - -
+ + + Local port + + + + + + + Local IP address + + + + + + + + + + + + + + +
+ + No items found + +
+ + + + +
+
+
+
-
-

- Network ports - - (0) - -

-
- + Network settings + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + +
+
+ + - - - - - - - - - - - - - + - - - - - - -
-
- - - Local port - - - - - - Local IP address - - - - - - State - - - - - + - - Protocol - - - -
-
- + + Protocol + + + + +
- No items found - - - -
+ +
+
+ + No items found + +
+
+
+
@@ -838,192 +1285,268 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = ` class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--directionRow euiFlexGroup--responsive" >
-

- Network settings - - (0) - -

-
-
-
- + Packages + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - - + - + - + + + + + - - - - - - -
-
- - - - - Address - - - - - + - - Netmask - - - - - + - - Protocol - - - - - +
+
- Broadcast - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -1231,244 +1699,53 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Packages - - (0) - -

-
- + Processes + + (0) + + +
+
- -
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - -
-
- - - - - - +
-
- -
-
- - No items found - -
-
-
-
-
-
-
-
-
-
-
-
-

- Processes - - (0) - -

-
-
-
-
- -
-
- +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - + - - + - + - + - + + + + + - - - - - - -
-
- - - Name - - - - - - + - - Effective user - - - - - - - + - - Parent PID - - - - - + - - VM size - - - - - + - - Priority - - - - - +
+
- State - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -2177,185 +2277,261 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network interfaces - - (0) - -

-
- + Network interfaces + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - + - - + - + + + + + - - - - - - -
-
- - - Name - - - - - - + - - MAC - - - - - - - + - - MTU - - - - - +
+
- Type - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -2559,607 +2679,437 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network ports - - (0) - -

-
- + Network ports + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
-
+
+
- + + + + Sorting + + + +
+
-
-
- - - - - - + + - + - + - - - - - - - -
-
- - - Local port - - - - - - Local IP address - - - - - +
+
- Process - - - - - + + Local port + + + - PID - - - - - State + + Process + - - - - - Protocol + + PID + - - -
-
- +
- No items found - - - -
-
-
-
-
-
-
-
-
-
-
-

- Network settings - - (0) - -

-
-
-
-
- -
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
+ + + State + + + + + -
-
-
-
+ + + + + + +
+ + No items found + +
+ + + +
+
+
+
+
+
+
-
-
+
-
-
-
- -
-
+ Network settings + + (0) + +
-
- - - - - - - - - - - - - - - -
-
+
+
-
- - - - +
-
- -
-
- - No items found - -
-
-
-
-
-
-
-
-
-
-
-
-

- Packages - - (0) - -

-
-
-
-
- -
-
- +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + +
+
- - - - - - - - - - - + - + - + - + + + + + - - - - - - -
-
- - - Name - - - - - - + - - Architecture - - - - - + - - Version - - - - - + - - Vendor - - - - - +
+
- Description - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -3696,185 +3468,261 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Processes - - (0) - -

-
- + Packages + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
-
+
+
+
+
+ +
+
+
+
+
+
+ + + + + - - - - - + + + + + + + +
+
+ + - - - - - - - - - - - + - + - + + + + + + + +
-
- - - Name - - - - - - + - - Effective user - - - - - + - - Effective group - - - - + + Description + + + +
+
+ + No items found + +
+
+ + + + + + + +
+
+
+
+
+
+
+
+
- -
+ + + +
+
+
-
+
-
+ + + + +
+
+
+
+
- -
+ +
+
+ +
+
+ + + + + + +
+
+
+
+
- -
- + + + + + + + + + + - + - + - + + + + + + + + - - - - - - -
+
- - Size - - - - - + - - Session - - - - - + - - Priority - - - - - + + + + + + + + + + + + + + + - - State - - - -
-
- + + Priority + + + + +
- No items found - - - -
+ +
+
+ + No items found + +
+
+
+
@@ -4375,185 +4575,262 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network interfaces - - (0) - -

-
- + Network interfaces + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + +
+
+ + - - - - - - - - - - - - - + - + - - - - - - - -
-
- - - - - - - State - - - - - + - - MTU - - - - - + - - Type - - - -
-
- - No items found - -
-
+ + + Type + + + +
+
+ + No items found + +
+
+
+
@@ -4758,347 +4978,367 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network ports - - (0) - -

-
- + Network ports + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
- + + + + Sorting + + + +
+
-
-
- - - - - - + + - - - - - - - - -
-
- - - Local port - - - - - - Local IP address - - - -
+
- Process + + Local port + - - - - - State + + Local IP address + - - - - - - Protocol - - - -
-
- + + Process + + + + +
- No items found - - - -
+ + + + + + + + + + +
+ + No items found + +
+ + + + +
+
@@ -5115,185 +5355,262 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Network settings - - (0) - -

-
- + Network settings + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - - + - + - + + + + + - - - - - - -
-
- - - - - Address - - - - - + - - Netmask - - - - - + - - Protocol - - - - - +
+
- Broadcast - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -5498,185 +5758,262 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Windows updates - - (0) - -

-
- + Windows updates + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
-
-
+ class="euiSpacer euiSpacer--s" + /> +
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + +
+
- - - - +
+
+ + No items found + +
+
- - - - - - - - - - - -
-
- -
-
- - No items found - -
-
@@ -5788,185 +6068,262 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Packages - - (0) - -

-
- + Packages + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - - + - + + + + + - - - - - - -
-
- - - - - Architecture - - - - - + - - Version - - - - - +
+
- Vendor - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
@@ -6152,185 +6452,263 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = ` class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPanel--hasShadow wz-agent-inventory-panel" >
-
-

- Processes - - (0) - -

-
- + Processes + + (0) + + +
+
- +
+
+ + + + + Export formatted + + + +
+
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
+
-
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+ + - - - - - - - - - - - - + - + - + - + - + + + + + - - - - - - -
-
- - - - - PID - - - - - + - - Parent PID - - - - - + - - VM size - - - - - + - - Priority - - - - - + - - NLWP - - - - - +
+
- Command - - - - -
-
- - No items found - -
-
+ + No items found + + + +
+
+
diff --git a/plugins/main/public/components/common/tables/__snapshots__/table-wz-api.test.tsx.snap b/plugins/main/public/components/common/tables/__snapshots__/table-wz-api.test.tsx.snap index 968ff7dfc8..2655f8c2ba 100644 --- a/plugins/main/public/components/common/tables/__snapshots__/table-wz-api.test.tsx.snap +++ b/plugins/main/public/components/common/tables/__snapshots__/table-wz-api.test.tsx.snap @@ -36,620 +36,661 @@ exports[`Table WZ API component renders correctly to match the snapshot 1`] = ` title="Table" >
- -
- -

- Table - - - - -

-
-
-
- -
- -
- - - -
-
- -
- +
+ +
+ +
+ +

+ Table + + + + +

+
+
+
+
+
+
+ +
-
- - + +
+
+
+
+
+ + +
+ + +
+
+
-
- - - - } - closePopover={[Function]} - display="inlineBlock" - hasArrow={true} - isOpen={false} - ownFocus={true} - panelPaddingSize="none" +
+ + +
-
- - - -
+ + + + + + + + + + + Sorting + + + + + + +
+
+
+
+
- +
- +
- -
- -
- - - - - - - - - - + +
- -
- + + + + + - - + - - - - + + - - + - - - - + + - - + - - - - + + - - + + + + + + + + + + + + - - - - - - - - - - - - - -
-
- - +
- + - + - +
- - Name - - - - - - - - -
-
- - No items found - -
-
-
+ + No items found + +
+ + + + + + + + +
+
+ +
-
- - + +
+ `; diff --git a/plugins/main/public/components/common/tables/table-with-search-bar.tsx b/plugins/main/public/components/common/tables/table-with-search-bar.tsx index 1f60167d3a..2c551192aa 100644 --- a/plugins/main/public/components/common/tables/table-with-search-bar.tsx +++ b/plugins/main/public/components/common/tables/table-with-search-bar.tsx @@ -124,6 +124,7 @@ export function TableWithSearchBar({ const [refresh, setRefresh] = useState(Date.now()); const isMounted = useRef(false); + const tableRef = useRef(); const searchBarWQLOptions = useMemo( () => ({ @@ -177,6 +178,10 @@ export function TableWithSearchBar({ (async () => { try { setLoading(true); + + //Reset the table selection in case is enabled + tableRef.current.setSelection([]); + const { items, totalItems } = await onSearch( endpoint, filters, @@ -254,6 +259,7 @@ export function TableWithSearchBar({ /> ({ ...rest }), )} diff --git a/plugins/main/public/components/common/tables/table-wz-api.tsx b/plugins/main/public/components/common/tables/table-wz-api.tsx index fc11c05c42..43b83e72de 100644 --- a/plugins/main/public/components/common/tables/table-wz-api.tsx +++ b/plugins/main/public/components/common/tables/table-wz-api.tsx @@ -18,7 +18,6 @@ import { EuiFlexItem, EuiText, EuiButtonEmpty, - EuiSpacer, EuiToolTip, EuiIcon, EuiCheckboxGroup, @@ -27,9 +26,6 @@ import { TableWithSearchBar } from './table-with-search-bar'; import { TableDefault } from './table-default'; import { WzRequest } from '../../../react-services/wz-request'; import { ExportTableCsv } from './components/export-table-csv'; -import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; -import { UI_LOGGER_LEVELS } from '../../../../common/constants'; -import { getErrorOrchestrator } from '../../../react-services/common-services'; import { useStateStorage } from '../hooks'; /** @@ -50,8 +46,12 @@ export function TableWzAPI({ actionButtons, ...rest }: { - actionButtons?: ReactNode | ReactNode[]; + actionButtons?: + | ReactNode + | ReactNode[] + | (({ filters }: { filters }) => ReactNode); title?: string; + addOnTitle?: ReactNode; description?: string; downloadCsv?: boolean | string; searchTable?: boolean; @@ -61,15 +61,20 @@ export function TableWzAPI({ showReload?: boolean; searchBarProps?: any; reload?: boolean; + onDataChange?: Function; }) { const [totalItems, setTotalItems] = useState(0); const [filters, setFilters] = useState({}); const [isLoading, setIsLoading] = useState(false); + const onFiltersChange = filters => typeof rest.onFiltersChange === 'function' ? rest.onFiltersChange(filters) : null; + const onDataChange = data => + typeof rest.onDataChange === 'function' ? rest.onDataChange(data) : null; + /** * Changing the reloadFootprint timestamp will trigger reloading the table */ @@ -112,10 +117,15 @@ export function TableWzAPI({ ).data; setIsLoading(false); setTotalItems(totalItems); - return { + + const result = { items: rest.mapResponseItem ? items.map(rest.mapResponseItem) : items, totalItems, }; + + onDataChange(result); + + return result; } catch (error) { setIsLoading(false); setTotalItems(0); @@ -132,19 +142,23 @@ export function TableWzAPI({ }, []); - const renderActionButtons = ( - <> - {Array.isArray(actionButtons) - ? actionButtons.map((button, key) => ( - - {button} - - )) - : typeof actionButtons === 'object' && ( - {actionButtons} - )} - - ); + const renderActionButtons = filters => { + if (Array.isArray(actionButtons)) { + return actionButtons.map((button, key) => ( + + {button} + + )); + } + + if (typeof actionButtons === 'object') { + return {actionButtons}; + } + + if (typeof actionButtons === 'function') { + return actionButtons({ filters: getFilters(filters) }); + } + }; /** * Generate a new reload footprint @@ -167,28 +181,34 @@ export function TableWzAPI({ const header = ( <> - - - {rest.title && ( - -

- {rest.title}{' '} - {isLoading ? ( - - ) : ( - ({totalItems}) - )} -

-
- )} - {rest.description && ( - {rest.description} - )} -
+ - + + + {rest.title && ( + +

+ {rest.title}{' '} + {isLoading ? ( + + ) : ( + ({totalItems}) + )} +

+
+ )} +
+ {rest.addOnTitle ? ( + + {rest.addOnTitle} + + ) : null} +
+
+ + {/* Render optional custom action button */} - {renderActionButtons} + {renderActionButtons(filters)} {/* Render optional reload button */} {rest.showReload && ReloadButton} {/* Render optional export to CSV button */} @@ -266,11 +286,15 @@ export function TableWzAPI({ ); return ( - <> - {header} - {rest.description && } - {table} - + + {header} + {rest.description && ( + + {rest.description} + + )} + {table} + ); } diff --git a/plugins/main/public/components/endpoints-summary/hooks/agents.test.ts b/plugins/main/public/components/endpoints-summary/hooks/agents.test.ts new file mode 100644 index 0000000000..32afd959e7 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/hooks/agents.test.ts @@ -0,0 +1,38 @@ +import { renderHook, act } from '@testing-library/react-hooks'; +import { useGetTotalAgents } from './agents'; +import { getAgentsService } from '../services'; + +jest.mock('../services', () => ({ + getAgentsService: jest.fn(), +})); + +describe('useGetTotalAgents hook', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should fetch initial data without any error', async () => { + (getAgentsService as jest.Mock).mockReturnValue({ + total_affected_items: 3, + }); + + const { result, waitForNextUpdate } = renderHook(() => useGetTotalAgents()); + + expect(result.current.isLoading).toBeTruthy(); + await waitForNextUpdate(); + expect(result.current.totalAgents).toEqual(3); + expect(result.current.isLoading).toBeFalsy(); + }); + + it('should handle error while fetching data', async () => { + const mockErrorMessage = 'Some error occurred'; + (getAgentsService as jest.Mock).mockRejectedValue(mockErrorMessage); + + const { result, waitForNextUpdate } = renderHook(() => useGetTotalAgents()); + + expect(result.current.isLoading).toBeTruthy(); + await waitForNextUpdate(); + expect(result.current.error).toBe(mockErrorMessage); + expect(result.current.isLoading).toBeFalsy(); + }); +}); diff --git a/plugins/main/public/components/endpoints-summary/hooks/agents.ts b/plugins/main/public/components/endpoints-summary/hooks/agents.ts index facb9df07b..3c383516fa 100644 --- a/plugins/main/public/components/endpoints-summary/hooks/agents.ts +++ b/plugins/main/public/components/endpoints-summary/hooks/agents.ts @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react'; -import { getTotalAgentsService } from '../services'; +import { getAgentsService } from '../services'; -export const useGetTotalAgents = () => { +export const useGetTotalAgents = (filters?: any) => { const [totalAgents, setTotalAgents] = useState(); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(); @@ -9,8 +9,11 @@ export const useGetTotalAgents = () => { const getTotalAgents = async () => { try { setIsLoading(true); - const totalAgents = await getTotalAgentsService(); - setTotalAgents(totalAgents); + const { total_affected_items } = await getAgentsService({ + filters, + limit: 1, + }); + setTotalAgents(total_affected_items); setError(undefined); } catch (error: any) { setError(error); diff --git a/plugins/main/public/components/endpoints-summary/hooks/groups.test.ts b/plugins/main/public/components/endpoints-summary/hooks/groups.test.ts new file mode 100644 index 0000000000..3dad828a43 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/hooks/groups.test.ts @@ -0,0 +1,44 @@ +import { renderHook, act } from '@testing-library/react-hooks'; +import { useGetGroups } from './groups'; +import { getGroupsService } from '../services'; + +jest.mock('../services', () => ({ + getGroupsService: jest.fn(), +})); + +describe('useGetGroups hook', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should fetch initial data without any error', async () => { + (getGroupsService as jest.Mock).mockReturnValue({ + affected_items: [ + { name: 'group1' }, + { name: 'group2' }, + { name: 'group3' }, + ], + total_affected_items: 3, + }); + + const mockGroups = ['group1', 'group2', 'group3']; + const { result, waitForNextUpdate } = renderHook(() => useGetGroups()); + + expect(result.current.isLoading).toBeTruthy(); + await waitForNextUpdate(); + expect(result.current.groups).toEqual(mockGroups); + expect(result.current.isLoading).toBeFalsy(); + }); + + it('should handle error while fetching data', async () => { + const mockErrorMessage = 'Some error occurred'; + (getGroupsService as jest.Mock).mockRejectedValue(mockErrorMessage); + + const { result, waitForNextUpdate } = renderHook(() => useGetGroups()); + + expect(result.current.isLoading).toBeTruthy(); + await waitForNextUpdate(); + expect(result.current.error).toBe(mockErrorMessage); + expect(result.current.isLoading).toBeFalsy(); + }); +}); diff --git a/plugins/main/public/components/endpoints-summary/hooks/groups.ts b/plugins/main/public/components/endpoints-summary/hooks/groups.ts index 8c83e9dec3..4910e87ed8 100644 --- a/plugins/main/public/components/endpoints-summary/hooks/groups.ts +++ b/plugins/main/public/components/endpoints-summary/hooks/groups.ts @@ -9,7 +9,7 @@ export const useGetGroups = () => { const getGroups = async () => { try { setIsLoading(true); - const { affected_items } = await getGroupsService(); + const { affected_items } = await getGroupsService({}); const groups = affected_items.map(item => item.name); setGroups(groups); setError(undefined); diff --git a/plugins/main/public/components/endpoints-summary/hooks/index.ts b/plugins/main/public/components/endpoints-summary/hooks/index.ts index e1fdae97a1..063e5cc418 100644 --- a/plugins/main/public/components/endpoints-summary/hooks/index.ts +++ b/plugins/main/public/components/endpoints-summary/hooks/index.ts @@ -1 +1,2 @@ export { useGetTotalAgents } from './agents'; +export { useGetGroups } from './groups'; diff --git a/plugins/main/public/components/endpoints-summary/index.tsx b/plugins/main/public/components/endpoints-summary/index.tsx index 2d37a9c9d8..7b52d47946 100644 --- a/plugins/main/public/components/endpoints-summary/index.tsx +++ b/plugins/main/public/components/endpoints-summary/index.tsx @@ -25,7 +25,7 @@ export const MainEndpointsSummary = compose( withReduxProvider, withGlobalBreadcrumb([{ text: endpointSummary.breadcrumbLabel }]), )(() => { - const { isLoading, totalAgents, error } = useGetTotalAgents(); + const { isLoading, totalAgents, error } = useGetTotalAgents('id!=000'); if (error) { const options = { diff --git a/plugins/main/public/components/endpoints-summary/services/add-agent-to-group.tsx b/plugins/main/public/components/endpoints-summary/services/add-agent-to-group.tsx index d32a186f14..eee4e590bb 100644 --- a/plugins/main/public/components/endpoints-summary/services/add-agent-to-group.tsx +++ b/plugins/main/public/components/endpoints-summary/services/add-agent-to-group.tsx @@ -1,4 +1,13 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; import { WzRequest } from '../../../react-services/wz-request'; -export const addAgentToGroupService = async (agentId: string, group: string) => - await WzRequest.apiReq('PUT', `/agents/${agentId}/group/${group}`, {}); +export const addAgentToGroupService = async ({ + agentId, + groupId, +}: { + agentId: string; + groupId: string; +}) => + (await WzRequest.apiReq('PUT', `/agents/${agentId}/group/${groupId}`, { + wait_for_complete: true, + })) as IApiResponse; diff --git a/plugins/main/public/components/endpoints-summary/services/add-agents-to-group.tsx b/plugins/main/public/components/endpoints-summary/services/add-agents-to-group.tsx new file mode 100644 index 0000000000..5c563167f1 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/add-agents-to-group.tsx @@ -0,0 +1,9 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; +import { paginatedAgentsGroupService } from './paginated-agents-group'; + +export const addAgentsToGroupService = async (parameters: { + agentIds: string[]; + groupId: string; + pageSize?: number; +}): Promise> => + await paginatedAgentsGroupService({ addOrRemove: 'add', ...parameters }); diff --git a/plugins/main/public/components/endpoints-summary/services/get-agents.test.tsx b/plugins/main/public/components/endpoints-summary/services/get-agents.test.tsx new file mode 100644 index 0000000000..2293b3373b --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/get-agents.test.tsx @@ -0,0 +1,85 @@ +import { getAgentsService } from './get-agents'; +import { WzRequest } from '../../../react-services/wz-request'; + +jest.mock('../../../react-services/wz-request', () => ({ + WzRequest: { + apiReq: jest.fn(), + }, +})); + +describe('getAgentsService', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should paginate agents and handle API responses correctly', async () => { + (WzRequest.apiReq as jest.Mock).mockImplementation( + async (method, endpoint, options) => { + if (options.params.offset === 0) { + return { + data: { + data: { + affected_items: [ + { id: '001', name: 'agent1' }, + { id: '002', name: 'agent2' }, + ], + total_affected_items: 3, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } else { + return { + data: { + data: { + affected_items: [{ id: '003', name: 'agent3' }], + total_affected_items: 3, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } + }, + ); + + const params = { + filters: {}, + pageSize: 2, + }; + + const result = await getAgentsService(params); + + expect(WzRequest.apiReq).toHaveBeenCalledWith('GET', '/agents', { + params: { + q: {}, + limit: 2, + offset: 0, + wait_for_complete: true, + }, + }); + + expect(WzRequest.apiReq).toHaveBeenCalledWith('GET', '/agents', { + params: { + q: {}, + limit: 2, + offset: 2, + wait_for_complete: true, + }, + }); + + expect(result).toEqual({ + affected_items: [ + { id: '001', name: 'agent1' }, + { id: '002', name: 'agent2' }, + { id: '003', name: 'agent3' }, + ], + total_affected_items: 3, + }); + }); +}); diff --git a/plugins/main/public/components/endpoints-summary/services/get-agents.tsx b/plugins/main/public/components/endpoints-summary/services/get-agents.tsx new file mode 100644 index 0000000000..ebe67f445e --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/get-agents.tsx @@ -0,0 +1,54 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; +import { WzRequest } from '../../../react-services/wz-request'; +import { Agent } from '../types'; + +export const getAgentsService = async ({ + filters, + limit, + offset, + pageSize = 1000, +}: { + filters: any; + limit?: number; + offset?: number; + pageSize?: number; +}) => { + let queryOffset = offset ?? 0; + let queryLimit = limit && limit <= pageSize ? limit : pageSize; + let allAffectedItems: Agent[] = []; + let totalAffectedItems; + + do { + const { + data: { + data: { affected_items, total_affected_items }, + }, + } = (await WzRequest.apiReq('GET', '/agents', { + params: { + limit: queryLimit, + offset: queryOffset, + q: filters, + wait_for_complete: true, + }, + })) as IApiResponse; + + if (totalAffectedItems === undefined) { + totalAffectedItems = total_affected_items; + } + + allAffectedItems = allAffectedItems.concat(affected_items); + + queryOffset += queryLimit; + + const restItems = limit ? limit - allAffectedItems.length : pageSize; + queryLimit = restItems > pageSize ? pageSize : restItems; + } while ( + queryOffset < totalAffectedItems && + (!limit || allAffectedItems.length < limit) + ); + + return { + affected_items: allAffectedItems, + total_affected_items: totalAffectedItems, + }; +}; diff --git a/plugins/main/public/components/endpoints-summary/services/get-groups.test.tsx b/plugins/main/public/components/endpoints-summary/services/get-groups.test.tsx new file mode 100644 index 0000000000..f9f78d2a6f --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/get-groups.test.tsx @@ -0,0 +1,78 @@ +import { getGroupsService } from './get-groups'; +import { WzRequest } from '../../../react-services/wz-request'; + +jest.mock('../../../react-services/wz-request', () => ({ + WzRequest: { + apiReq: jest.fn(), + }, +})); + +describe('getGroupsService', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should paginate groups and handle API responses correctly', async () => { + (WzRequest.apiReq as jest.Mock).mockImplementation( + async (method, endpoint, options) => { + if (options.params.offset === 0) { + return { + data: { + data: { + affected_items: ['group1', 'group2'], + total_affected_items: 3, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } else { + return { + data: { + data: { + affected_items: ['group3'], + total_affected_items: 3, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } + }, + ); + + const params = { + filters: {}, + pageSize: 2, + }; + + const result = await getGroupsService(params); + + expect(WzRequest.apiReq).toHaveBeenCalledWith('GET', '/groups', { + params: { + q: {}, + limit: 2, + offset: 0, + wait_for_complete: true, + }, + }); + + expect(WzRequest.apiReq).toHaveBeenCalledWith('GET', '/groups', { + params: { + q: {}, + limit: 2, + offset: 2, + wait_for_complete: true, + }, + }); + + expect(result).toEqual({ + affected_items: ['group1', 'group2', 'group3'], + total_affected_items: 3, + }); + }); +}); diff --git a/plugins/main/public/components/endpoints-summary/services/get-groups.tsx b/plugins/main/public/components/endpoints-summary/services/get-groups.tsx index 1b463c163d..a565e1f3cb 100644 --- a/plugins/main/public/components/endpoints-summary/services/get-groups.tsx +++ b/plugins/main/public/components/endpoints-summary/services/get-groups.tsx @@ -1,8 +1,54 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; import { WzRequest } from '../../../react-services/wz-request'; +import { Group } from '../types'; -export const getGroupsService = async () => { - const { - data: { data }, - } = await WzRequest.apiReq('GET', '/groups', {}); - return data; +export const getGroupsService = async ({ + filters, + limit, + offset, + pageSize = 1000, +}: { + filters: any; + limit?: number; + offset?: number; + pageSize?: number; +}) => { + let queryOffset = offset ?? 0; + let queryLimit = limit && limit <= pageSize ? limit : pageSize; + let allAffectedItems: Group[] = []; + let totalAffectedItems; + + do { + const { + data: { + data: { affected_items, total_affected_items }, + }, + } = (await WzRequest.apiReq('GET', '/groups', { + params: { + limit: queryLimit, + offset: queryOffset, + q: filters, + wait_for_complete: true, + }, + })) as IApiResponse; + + if (totalAffectedItems === undefined) { + totalAffectedItems = total_affected_items; + } + + allAffectedItems = allAffectedItems.concat(affected_items); + + queryOffset += queryLimit; + + const restItems = limit ? limit - allAffectedItems.length : pageSize; + queryLimit = restItems > pageSize ? pageSize : restItems; + } while ( + queryOffset < totalAffectedItems && + (!limit || allAffectedItems.length < limit) + ); + + return { + affected_items: allAffectedItems, + total_affected_items: totalAffectedItems, + }; }; diff --git a/plugins/main/public/components/endpoints-summary/services/get-total-agents.tsx b/plugins/main/public/components/endpoints-summary/services/get-total-agents.tsx deleted file mode 100644 index b75c59725e..0000000000 --- a/plugins/main/public/components/endpoints-summary/services/get-total-agents.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { WzRequest } from '../../../react-services/wz-request'; - -export const getTotalAgentsService = async () => { - const { - data: { - data: { total_affected_items }, - }, - } = await WzRequest.apiReq('GET', '/agents', { - params: { limit: 1, q: 'id!=000' }, - }); - return total_affected_items; -}; diff --git a/plugins/main/public/components/endpoints-summary/services/index.tsx b/plugins/main/public/components/endpoints-summary/services/index.tsx index 6615483443..a8d7711ff8 100644 --- a/plugins/main/public/components/endpoints-summary/services/index.tsx +++ b/plugins/main/public/components/endpoints-summary/services/index.tsx @@ -1,5 +1,6 @@ -export { getTotalAgentsService } from './get-total-agents'; -export { removeAgentFromGroupService } from './remove-agent-from-group'; +export { getAgentsService } from './get-agents'; export { removeAgentFromGroupsService } from './remove-agent-from-groups'; +export { removeAgentsFromGroupService } from './remove-agents-from-group'; export { addAgentToGroupService } from './add-agent-to-group'; +export { addAgentsToGroupService } from './add-agents-to-group'; export { getGroupsService } from './get-groups'; diff --git a/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.test.tsx b/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.test.tsx new file mode 100644 index 0000000000..e6f506dfe0 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.test.tsx @@ -0,0 +1,205 @@ +import { paginatedAgentsGroupService } from './paginated-agents-group'; +import { WzRequest } from '../../../react-services/wz-request'; + +jest.mock('../../../react-services/wz-request', () => ({ + WzRequest: { + apiReq: jest.fn(), + }, +})); + +describe('paginatedAgentsGroupService', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should paginate agents and handle API responses correctly', async () => { + (WzRequest.apiReq as jest.Mock).mockImplementation( + async (method, endpoint, options) => { + if (options.params.agents_list === 'agent1,agent2') { + return { + data: { + data: { + affected_items: ['agent1', 'agent2'], + total_affected_items: 2, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } else { + return { + data: { + data: { + affected_items: ['agent3'], + total_affected_items: 1, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }; + } + }, + ); + + const params = { + addOrRemove: 'add' as any, + agentIds: ['agent1', 'agent2', 'agent3'], + groupId: 'group1', + pageSize: 2, + }; + + const result = await paginatedAgentsGroupService(params); + + expect(WzRequest.apiReq).toHaveBeenCalledWith( + 'PUT', + '/agents/group', + { + params: { + group_id: 'group1', + agents_list: 'agent1,agent2', + wait_for_complete: true, + }, + }, + { returnOriginalResponse: true }, + ); + + expect(WzRequest.apiReq).toHaveBeenCalledWith( + 'PUT', + '/agents/group', + { + params: { + group_id: 'group1', + agents_list: 'agent3', + wait_for_complete: true, + }, + }, + { returnOriginalResponse: true }, + ); + + expect(result).toEqual({ + data: { + data: { + affected_items: ['agent1', 'agent2', 'agent3'], + total_affected_items: 3, + failed_items: [], + total_failed_items: 0, + }, + error: 0, + message: 'Success', + }, + }); + }); + + it('should paginate agents and handle API responses with failed items', async () => { + (WzRequest.apiReq as jest.Mock).mockImplementation( + async (method, endpoint, options) => { + if (options.params.agents_list === 'agent1,agent2') { + return { + data: { + data: { + affected_items: ['agent1'], + total_affected_items: 1, + failed_items: [ + { + error: { + code: '001', + message: 'agent error', + remediation: 'example remediation', + }, + id: ['agent2'], + }, + ], + total_failed_items: 1, + }, + error: 1, + message: 'agent2 error', + }, + }; + } else { + return { + data: { + data: { + affected_items: [], + total_affected_items: 0, + failed_items: [ + { + error: { + code: '001', + message: 'agent error', + remediation: 'example remediation', + }, + id: ['agent3'], + }, + ], + total_failed_items: 1, + }, + error: 1, + message: 'agent3 error', + }, + }; + } + }, + ); + + const params = { + addOrRemove: 'add' as any, + agentIds: ['agent1', 'agent2', 'agent3'], + groupId: 'group1', + pageSize: 2, + }; + + const result = await paginatedAgentsGroupService(params); + + expect(WzRequest.apiReq).toHaveBeenCalledWith( + 'PUT', + '/agents/group', + { + params: { + group_id: 'group1', + agents_list: 'agent1,agent2', + wait_for_complete: true, + }, + }, + { returnOriginalResponse: true }, + ); + + expect(WzRequest.apiReq).toHaveBeenCalledWith( + 'PUT', + '/agents/group', + { + params: { + group_id: 'group1', + agents_list: 'agent3', + wait_for_complete: true, + }, + }, + { returnOriginalResponse: true }, + ); + + expect(result).toEqual({ + data: { + data: { + affected_items: ['agent1'], + total_affected_items: 1, + failed_items: [ + { + error: { + code: '001', + message: 'agent error', + remediation: 'example remediation', + }, + id: ['agent2', 'agent3'], + }, + ], + total_failed_items: 2, + }, + error: 2, + message: 'agent2 error, agent3 error', + }, + }); + }); +}); diff --git a/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.tsx b/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.tsx new file mode 100644 index 0000000000..512098817c --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/paginated-agents-group.tsx @@ -0,0 +1,109 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; +import { WzRequest } from '../../../react-services/wz-request'; + +export type ErrorAgent = { + error: { + code?: number; + message: string; + remediation?: string; + }; + id: string[]; +}; + +export const paginatedAgentsGroupService = async ({ + addOrRemove, + agentIds, + groupId, + pageSize = 1000, +}: { + addOrRemove: 'add' | 'remove'; + agentIds: string[]; + groupId: string; + pageSize?: number; +}): Promise> => { + let offset = 0; + let requestAgentIds: string[] = []; + let allAffectedItems: string[] = []; + let allFailedItems: ErrorAgent[] = []; + let totalAffectedItems = 0; + let totalFailedItems = 0; + let error = 0; + let message = ''; + + do { + requestAgentIds = agentIds.slice(offset, offset + pageSize); + + const { + data: { + data: { + affected_items: responseAffectedItems, + total_affected_items: responseTotalAffectedItems, + failed_items: responseFailedItems, + total_failed_items: responseTotalFailedItems, + }, + error: responseError, + message: responseMessage, + }, + } = (await WzRequest.apiReq( + addOrRemove === 'add' ? 'PUT' : 'DELETE', + `/agents/group`, + { + params: { + group_id: groupId, + agents_list: requestAgentIds.join(','), + wait_for_complete: true, + }, + }, + { returnOriginalResponse: true }, + )) as IApiResponse; + + error += responseError; + message = + offset === 0 + ? responseMessage + : message.includes(responseMessage) + ? message + : message + ', ' + responseMessage; + totalAffectedItems += responseTotalAffectedItems; + totalFailedItems += responseTotalFailedItems; + allAffectedItems = [...allAffectedItems, ...responseAffectedItems]; + + const notExistFailedItems = responseFailedItems.filter( + responseFailedItem => + !allFailedItems.find( + failedItem => failedItem.error.code === responseFailedItem.error.code, + ), + ); + + const mergeFailedItems = allFailedItems.map(failedItem => { + const responseFailedItemWithSameError = responseFailedItems.find( + responseFailedItem => + responseFailedItem.error.code === failedItem.error.code, + ); + + return { + ...failedItem, + id: responseFailedItemWithSameError + ? [...failedItem.id, ...responseFailedItemWithSameError.id] + : failedItem.id, + }; + }); + + allFailedItems = [...mergeFailedItems, ...notExistFailedItems]; + + offset += pageSize; + } while (offset < agentIds.length); + + return { + data: { + data: { + affected_items: allAffectedItems, + total_affected_items: totalAffectedItems, + failed_items: allFailedItems, + total_failed_items: totalFailedItems, + }, + error, + message, + }, + }; +}; diff --git a/plugins/main/public/components/endpoints-summary/services/remove-agent-from-group.tsx b/plugins/main/public/components/endpoints-summary/services/remove-agent-from-group.tsx deleted file mode 100644 index 633d49fe41..0000000000 --- a/plugins/main/public/components/endpoints-summary/services/remove-agent-from-group.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { WzRequest } from '../../../react-services/wz-request'; - -export const removeAgentFromGroupService = async ( - agentId: string, - group: string, -) => await WzRequest.apiReq('DELETE', `/agents/${agentId}/group/${group}`, {}); diff --git a/plugins/main/public/components/endpoints-summary/services/remove-agent-from-groups.tsx b/plugins/main/public/components/endpoints-summary/services/remove-agent-from-groups.tsx index 2784d026aa..2825670e82 100644 --- a/plugins/main/public/components/endpoints-summary/services/remove-agent-from-groups.tsx +++ b/plugins/main/public/components/endpoints-summary/services/remove-agent-from-groups.tsx @@ -1,11 +1,15 @@ import { WzRequest } from '../../../react-services/wz-request'; -export const removeAgentFromGroupsService = async ( - agentId: string, - groups: string[], -) => +export const removeAgentFromGroupsService = async ({ + agentId, + groupIds, +}: { + agentId: string; + groupIds: string[]; +}) => await WzRequest.apiReq('DELETE', `/agents/${agentId}/group`, { params: { - groups_list: groups.join(','), + groups_list: groupIds.join(','), + wait_for_complete: true, }, }); diff --git a/plugins/main/public/components/endpoints-summary/services/remove-agents-from-group.tsx b/plugins/main/public/components/endpoints-summary/services/remove-agents-from-group.tsx new file mode 100644 index 0000000000..a2000e9ba4 --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/services/remove-agents-from-group.tsx @@ -0,0 +1,9 @@ +import IApiResponse from '../../../react-services/interfaces/api-response.interface'; +import { paginatedAgentsGroupService } from './paginated-agents-group'; + +export const removeAgentsFromGroupService = async (parameters: { + agentIds: string[]; + groupId: string; + pageSize?: number; +}): Promise> => + await paginatedAgentsGroupService({ addOrRemove: 'remove', ...parameters }); diff --git a/plugins/main/public/components/endpoints-summary/table/__snapshots__/agents-table.test.tsx.snap b/plugins/main/public/components/endpoints-summary/table/__snapshots__/agents-table.test.tsx.snap index ca93426bbd..5a0be00f9f 100644 --- a/plugins/main/public/components/endpoints-summary/table/__snapshots__/agents-table.test.tsx.snap +++ b/plugins/main/public/components/endpoints-summary/table/__snapshots__/agents-table.test.tsx.snap @@ -12,143 +12,54 @@ exports[`AgentsTable component Renders correctly to match the snapshot 1`] = ` class="euiFlexItem" >
-
-

- Agents - - (0) - -

-
-
- -
-
- + Agents + + (0) + + +
+
- - - -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
+ Deploy new agent + + +
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - + + + + + + + + + + + + + + +
-
- - - +
-
+
- -
+ + + + + + +
+
+
+
+
- -
+ +
+
+ +
+
+ + + + + + +
+
+
+
+
- -
- - - + + + + + + + + + + - + - - - - - - -
+
- - Synced - - - - - - + +
+
+ +
- Actions - - -
-
- + + + ID + + + + + +
- No items found - - - -
+ +
+ + + + + + + + + + + + + + + Actions + + +
+
+ + No items found + +
+
+
+
@@ -558,250 +664,86 @@ exports[`AgentsTable component Renders correctly to match the snapshot with cust class="euiFlexItem" >
-
-

- Agents - - (0) - -

-
-
- -
-
- + Agents + + (0) + + +
+
- - - -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
+ Deploy new agent + + +
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - + + +
+
+ +
+
+ + + + + + +
+
+
+
-
- - -
-
- - - +
-
- - +
- -
- - + + + + + + +
+
+
+
+
- - +
- Actions - - -
- - No items found - + +
+ +
-
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + Actions + + +
+
+ + No items found + +
+
+
+
@@ -1062,250 +1275,86 @@ exports[`AgentsTable component Renders correctly to match the snapshot with no p class="euiFlexItem" >
-
-

- Agents - - (0) - -

-
-
- + Agents + + (0) + + +
+
- -
-
- - - -
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
-
+ Deploy new agent + + +
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - + +
-
- - - +
-
+
- -
+ + + + + + +
+
+
+
+
- -
+ +
+
+ +
+
+ + + + + + +
+
+
+
+
- -
- - - + + + + + + + + + + + + + + + + + + + - + + + - - Actions - - - - - - - - - - -
+
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + - Status + + Actions + - - - - +
-
- - No items found - -
-
+
+ + No items found + +
+ +
+
+
diff --git a/plugins/main/public/components/endpoints-summary/table/actions/__snapshots__/edit-groups-modal.test.tsx.snap b/plugins/main/public/components/endpoints-summary/table/actions/__snapshots__/edit-groups-modal.test.tsx.snap new file mode 100644 index 0000000000..29c18c734e --- /dev/null +++ b/plugins/main/public/components/endpoints-summary/table/actions/__snapshots__/edit-groups-modal.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EditAgentGroupsModal component should return the component 1`] = ` +