diff --git a/CHANGELOG.md b/CHANGELOG.md index 3713e6c1c..ba16711a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,16 @@ # UTMStack 10.7.1 Release Notes ### Bug Fixes -- Fixed responsive text alignment for action buttons in Log Explorer to enhance visual consistency. +-- Fixed responsive text alignment for action buttons in Log Explorer to enhance visual consistency. +-- Fixed issues with loading data from saved queries in Log Explorer, ensuring the correct filter values are applied. +-- Fixed issue where tabs remained open when navigating outside the Log Explorer scope to improve user experience. +-- Fixed time filter issue where the date range was not applied correctly. +-- Fixed incorrect query behavior when filtering incidents by ID. + ## New Features and Improvements -- Added organization name in app settings to distinguish alert and notification emails for better clarity. -- Enhanced the email notification system by including the organization name to improve recipient identification. -- Introduced new compliance reports aligned with the PCI DSS standard to expand auditing capabilities. -- Resolves issues with malformed queries when filtering incidents by id. +-- Added organization name in app settings to distinguish alert and notification emails for better clarity. +-- Enhanced the email notification system by including the organization name to improve recipient identification. +-- Introduced new compliance reports aligned with the PCI DSS standard to expand auditing capabilities. +-- Added new menu item **New Dashboard**. +-- Added new menu item **New Visualization**. \ No newline at end of file diff --git a/backend/src/main/java/com/park/utmstack/service/mail_config/MailConfigService.java b/backend/src/main/java/com/park/utmstack/service/mail_config/MailConfigService.java index 465bb03f0..fffeb4b34 100644 --- a/backend/src/main/java/com/park/utmstack/service/mail_config/MailConfigService.java +++ b/backend/src/main/java/com/park/utmstack/service/mail_config/MailConfigService.java @@ -18,7 +18,7 @@ public MailConfig getMailConfigFromParameters(List pa mailConfig.setUsername(getParamValue(parameters, Constants.PROP_MAIL_USERNAME)); mailConfig.setPassword(getParamValue(parameters, Constants.PROP_MAIL_PASSWORD)); mailConfig.setAuthType(getParamValue(parameters, Constants.PROP_MAIL_SMTP_AUTH)); - mailConfig.setFrom(String.valueOf(new InternetAddress(Constants.CFG.get(Constants.PROP_MAIL_FROM), getParamValue(parameters, Constants.PROP_MAIL_ORGNAME)))); + mailConfig.setFrom(String.valueOf(new InternetAddress(getParamValue(parameters, Constants.PROP_MAIL_FROM), getParamValue(parameters, Constants.PROP_MAIL_ORGNAME)))); mailConfig.setPort(Integer.parseInt(getParamValue(parameters, Constants.PROP_MAIL_PORT))); return mailConfig; diff --git a/backend/src/main/resources/config/liquibase/changelog/20250319001_add_organization_field_config_params.xml b/backend/src/main/resources/config/liquibase/changelog/20250319002_add_organization_field_config_params.xml similarity index 96% rename from backend/src/main/resources/config/liquibase/changelog/20250319001_add_organization_field_config_params.xml rename to backend/src/main/resources/config/liquibase/changelog/20250319002_add_organization_field_config_params.xml index 43b2aa8fb..6c5bdae26 100644 --- a/backend/src/main/resources/config/liquibase/changelog/20250319001_add_organization_field_config_params.xml +++ b/backend/src/main/resources/config/liquibase/changelog/20250319002_add_organization_field_config_params.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> - + + + + + + + + + + diff --git a/backend/src/main/resources/config/liquibase/master.xml b/backend/src/main/resources/config/liquibase/master.xml index 232d2c85a..2f4b6aae0 100644 --- a/backend/src/main/resources/config/liquibase/master.xml +++ b/backend/src/main/resources/config/liquibase/master.xml @@ -77,8 +77,10 @@ - + + + diff --git a/frontend/src/app/log-analyzer/explorer/log-analyzer-tabs/log-analyzer-tabs.component.ts b/frontend/src/app/log-analyzer/explorer/log-analyzer-tabs/log-analyzer-tabs.component.ts index 5aa270601..d49a228af 100644 --- a/frontend/src/app/log-analyzer/explorer/log-analyzer-tabs/log-analyzer-tabs.component.ts +++ b/frontend/src/app/log-analyzer/explorer/log-analyzer-tabs/log-analyzer-tabs.component.ts @@ -10,6 +10,9 @@ import {TabService} from '../../shared/services/tab.service'; import {LogAnalyzerQueryType} from '../../shared/type/log-analyzer-query.type'; import {TabType} from '../../shared/type/tab.type'; import {LogAnalyzerViewComponent} from '../log-analyzer-view/log-analyzer-view.component'; +import { + ElasticFilterDefaultTime +} from "../../../shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component"; @Component({ selector: 'app-log-analyzer-tabs', @@ -32,23 +35,6 @@ export class LogAnalyzerTabsComponent implements OnInit, OnDestroy { private indexPatternBehavior: IndexPatternBehavior ) {} - /*ngOnInit() { - this.activatedRoute.queryParams.subscribe(params => { - this.queryId = params.queryId; - const tabName = params.active || null; - if (this.queryId) { - this.logAnalyzerQueryService.find(this.queryId).subscribe(vis => { - this.query = vis.body; - this.addNewTab(this.query.name, this.query, params); - }); - } else { - if (tabName) { - this.tabService.deleteActiveTab(); - } - this.addNewTab(); - } - });*/ - ngOnInit(): void { this.activatedRoute.queryParams .pipe(takeUntil(this.destroy$)) @@ -103,8 +89,14 @@ export class LogAnalyzerTabsComponent implements OnInit, OnDestroy { new UtmIndexPattern(1, 'log-*', true); this.tabService.addTab( - new TabType(LogAnalyzerViewComponent, (tabName ? tabName : 'New query ' + this.tabNumber), - query ? query : {pattern}, true, null, uuid) + new TabType( + LogAnalyzerViewComponent, + (tabName ? tabName : 'New query ' + this.tabNumber), + query ? query : {pattern}, + true, + null, + uuid, + this.getDefaultTime(query)) ); if (tabName && pattern) { @@ -112,6 +104,16 @@ export class LogAnalyzerTabsComponent implements OnInit, OnDestroy { } } + getDefaultTime(query: LogAnalyzerQueryType): ElasticFilterDefaultTime { + if (query) { + const timestampFilter = query.filtersType.find(f => f.field === '@timestamp'); + return timestampFilter ? new ElasticFilterDefaultTime(timestampFilter.value[0], timestampFilter.value[1]) : + new ElasticFilterDefaultTime('now-24h', 'now'); + } else { + return new ElasticFilterDefaultTime('now-24h', 'now'); + } + } + removeTab(index: number): void { this.tabService.removeTab(index); } diff --git a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.html b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.html index 947d2b615..3a08c50a0 100644 --- a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.html +++ b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.html @@ -45,7 +45,7 @@ (onSaveQuery)="saveQuery()" [filters]="filters" [template]="'log-explorer'" - *ngIf="defaultTime && pattern;else loadingPattern" + *ngIf="defaultTime && pattern; else loadingPattern" [pattern]="pattern.pattern" [defaultTime]="defaultTime" class="flex-grow-1"> diff --git a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.scss b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.scss index b4dd51c37..5934f99fd 100644 --- a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.scss +++ b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.scss @@ -12,7 +12,19 @@ app-log-analyzer-field { } .search-container { - flex-basis: 65%; + flex-basis: 50%; +} + +@media screen and (min-width: 1550px) and (max-width: 1599px) { + .search-container { + flex-basis: 55%; + } +} + +@media screen and (min-width: 1600px) { + .search-container { + flex-basis: 65%; + } } .btn-refresh { diff --git a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.ts b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.ts index 7dfba0f46..1ac53bc84 100644 --- a/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.ts +++ b/frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.ts @@ -49,6 +49,7 @@ import {LogAnalyzerQueryType} from '../../shared/type/log-analyzer-query.type'; export class LogAnalyzerViewComponent implements OnInit, OnDestroy { @Input() data: LogAnalyzerQueryType; @Input() uuid: string; + @Input() defaultTime: ElasticFilterDefaultTime = new ElasticFilterDefaultTime('now-24h', 'now'); fields: UtmFieldType[] = []; rows: any[] = []; page = 1; @@ -79,7 +80,6 @@ export class LogAnalyzerViewComponent implements OnInit, OnDestroy { private sortBy = NatureDataPrefixEnum.TIMESTAMP + ',' + 'desc'; patterns: UtmIndexPattern[]; paramLoaded = false; - defaultTime: ElasticFilterDefaultTime = new ElasticFilterDefaultTime('now-24h', 'now'); dateFormat$: Observable; destroy$ = new Subject(); filterWidth: number; @@ -96,8 +96,7 @@ export class LogAnalyzerViewComponent implements OnInit, OnDestroy { private elasticDataExportService: ElasticDataExportService, private timezoneFormatService: TimezoneFormatService, private logFilterBehavior: LogFilterBehavior, - private router: Router, - private tabService: TabService) { + private router: Router) { this.detailWidth = (this.pageWidth - 310); } diff --git a/frontend/src/app/log-analyzer/queries/log-analyzer-query-list/log-analyzer-query-list.component.ts b/frontend/src/app/log-analyzer/queries/log-analyzer-query-list/log-analyzer-query-list.component.ts index 3dbc911b1..cc011e6bf 100644 --- a/frontend/src/app/log-analyzer/queries/log-analyzer-query-list/log-analyzer-query-list.component.ts +++ b/frontend/src/app/log-analyzer/queries/log-analyzer-query-list/log-analyzer-query-list.component.ts @@ -1,20 +1,25 @@ import {HttpResponse} from '@angular/common/http'; -import {Component, OnInit} from '@angular/core'; -import {Router} from '@angular/router'; +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {NavigationStart, Router} from '@angular/router'; import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {Subject} from 'rxjs'; +import {filter, takeUntil, tap} from 'rxjs/operators'; import {ITEMS_PER_PAGE} from '../../../shared/constants/pagination.constants'; import {SortEvent} from '../../../shared/directives/sortable/type/sort-event'; import {SortByType} from '../../../shared/types/sort-by.type'; import {LogAnalyzerQueryService} from '../../shared/services/log-analyzer-query.service'; +import {TabService} from '../../shared/services/tab.service'; import {LogAnalyzerQueryType} from '../../shared/type/log-analyzer-query.type'; import {LogAnalyzerQueryDeleteComponent} from '../log-analyzer-query-delete/log-analyzer-query-delete.component'; +import {query} from "@angular/animations"; +import {data} from "../../../active-directory/offline.data"; @Component({ selector: 'app-log-analyzer-query-list', templateUrl: './log-analyzer-query-list.component.html', styleUrls: ['./log-analyzer-query-list.component.scss'] }) -export class LogAnalyzerQueryListComponent implements OnInit { +export class LogAnalyzerQueryListComponent implements OnInit, OnDestroy { fields: SortByType[] = [ { fieldName: 'Name', @@ -34,10 +39,12 @@ export class LogAnalyzerQueryListComponent implements OnInit { query: LogAnalyzerQueryType; private requestParams: any; private sortBy: SortEvent; + destroy$ = new Subject(); constructor(private logAnalyzerQueryService: LogAnalyzerQueryService, private router: Router, - private modalService: NgbModal) { + private modalService: NgbModal, + private tabService: TabService) { } ngOnInit() { @@ -47,6 +54,16 @@ export class LogAnalyzerQueryListComponent implements OnInit { sort: this.sortBy, }; this.getQueryList(); + + this.router.events.pipe( + filter(event => event instanceof NavigationStart), + tap((event: NavigationStart) => { + if (event.url !== '/discover/log-analyzer-queries' && !event.url.includes('/discover/log-analyzer')) { + this.tabService.closeAllTabs(); + } + }), + takeUntil(this.destroy$) + ).subscribe(); } onSearchQuery($event: string) { @@ -65,7 +82,7 @@ export class LogAnalyzerQueryListComponent implements OnInit { queryId: query.id, queryName: query.name.toLowerCase().replace(' ', '_'), patternId: query.pattern.id, - indexPattern: query.pattern.pattern + indexPattern: query.pattern.pattern, } }); } @@ -98,4 +115,9 @@ export class LogAnalyzerQueryListComponent implements OnInit { private onError(body: any) { } + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } } diff --git a/frontend/src/app/log-analyzer/shared/components/tab-content/tab-content.component.ts b/frontend/src/app/log-analyzer/shared/components/tab-content/tab-content.component.ts index 43411aaed..c81e46678 100644 --- a/frontend/src/app/log-analyzer/shared/components/tab-content/tab-content.component.ts +++ b/frontend/src/app/log-analyzer/shared/components/tab-content/tab-content.component.ts @@ -24,5 +24,6 @@ export class TabContentComponent implements OnInit { const componentRef = this.contentContainer.viewContainerRef.createComponent(componentFactory); (componentRef.instance as SkeletonInterface).data = tab.tabData; (componentRef.instance as SkeletonInterface).uuid = tab.uuid; + (componentRef.instance as SkeletonInterface).defaultTime = tab.defaultTime; } } diff --git a/frontend/src/app/log-analyzer/shared/type/skeleton.interface.ts b/frontend/src/app/log-analyzer/shared/type/skeleton.interface.ts index 95a3a0a08..ed06e51b9 100644 --- a/frontend/src/app/log-analyzer/shared/type/skeleton.interface.ts +++ b/frontend/src/app/log-analyzer/shared/type/skeleton.interface.ts @@ -1,4 +1,9 @@ +import { + ElasticFilterDefaultTime +} from '../../../shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component'; + export interface SkeletonInterface { data: any; uuid: string; + defaultTime: ElasticFilterDefaultTime; } diff --git a/frontend/src/app/log-analyzer/shared/type/tab.type.ts b/frontend/src/app/log-analyzer/shared/type/tab.type.ts index af4fde94d..7bcd36cf6 100644 --- a/frontend/src/app/log-analyzer/shared/type/tab.type.ts +++ b/frontend/src/app/log-analyzer/shared/type/tab.type.ts @@ -1,5 +1,8 @@ import {Type} from '@angular/core'; import {LogAnalyzerQueryType} from './log-analyzer-query.type'; +import { + ElasticFilterDefaultTime +} from "../../../shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component"; export class TabType { public id?: number; @@ -8,14 +11,16 @@ export class TabType { public active: boolean; public component: Type; public uuid?: string; + public defaultTime?: ElasticFilterDefaultTime; constructor(component: Type, title: string, tabData: any, active: boolean, id?: number, - uuid?: string) { + uuid?: string, defaultTime?: ElasticFilterDefaultTime) { this.id = id; this.tabData = tabData; this.component = component; this.title = title; this.active = active; this.uuid = uuid; + this.defaultTime = defaultTime; } } diff --git a/frontend/src/app/shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component.html b/frontend/src/app/shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component.html index 89e5134a8..dfbdb75a5 100644 --- a/frontend/src/app/shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component.html +++ b/frontend/src/app/shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component.html @@ -97,7 +97,7 @@
Info! - Offline agent, data based on the last sync. + The agent is offline. Data shown is from the last successful sync.