From a4bd268c10a796531d3478c072d66b3698e2b18e Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Thu, 21 Dec 2023 13:23:05 +0100 Subject: [PATCH 01/49] Increased search delay as you type from 300ms to 800ms (less requests to DB as you type, before each letter = one useless search request by "slower" typing) --- src/gui/src/components/analyze/ToolbarFilterAnalyze.vue | 2 +- src/gui/src/components/assess/ToolbarFilterAssess.vue | 2 +- src/gui/src/components/assets/ToolbarFilterAssets.vue | 2 +- src/gui/src/components/common/ToolbarFilter.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue b/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue index 51c433c50..b384e1027 100644 --- a/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue +++ b/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue @@ -157,7 +157,7 @@ export default { if (this.publish_selector === false) { this.$refs.toolbarGroupAnalyze.disableMultiSelect() } - }, 300); + }, 800); }, changeTheme() { diff --git a/src/gui/src/components/assess/ToolbarFilterAssess.vue b/src/gui/src/components/assess/ToolbarFilterAssess.vue index 4b5e6a8b3..e307001ee 100644 --- a/src/gui/src/components/assess/ToolbarFilterAssess.vue +++ b/src/gui/src/components/assess/ToolbarFilterAssess.vue @@ -199,7 +199,7 @@ if (self.analyze_selector === false) { self.$refs.toolbarGroupAssess.disableMultiSelect() } - }, 300); + }, 800); }, changeTheme() { diff --git a/src/gui/src/components/assets/ToolbarFilterAssets.vue b/src/gui/src/components/assets/ToolbarFilterAssets.vue index 0678f3c1b..76e619e7b 100644 --- a/src/gui/src/components/assets/ToolbarFilterAssets.vue +++ b/src/gui/src/components/assets/ToolbarFilterAssets.vue @@ -84,7 +84,7 @@ this.timeout = setTimeout(function () { this.$root.$emit('update-assets-filter', this.filter); - }, 300); + }, 800); }, changeTheme() { this.$vuetify.theme.themes.light.primary = "#f0f"; diff --git a/src/gui/src/components/common/ToolbarFilter.vue b/src/gui/src/components/common/ToolbarFilter.vue index fca036701..8514e01a8 100644 --- a/src/gui/src/components/common/ToolbarFilter.vue +++ b/src/gui/src/components/common/ToolbarFilter.vue @@ -53,7 +53,7 @@ let self = this; this.timeout = setTimeout(function(){ self.$root.$emit('update-items-filter', self.filter) - },800); + }, 800); }, changeTheme() { this.$vuetify.theme.themes.light.primary = "#f0f"; From 7e0c5b0b478c80710b887d8af49318c70e465048 Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Thu, 28 Dec 2023 15:59:53 +0100 Subject: [PATCH 02/49] Revert "Increased search delay as you type from 300ms to 800ms (less requests to DB as you type, before each letter = one useless search request by "slower" typing)" This reverts commit a4bd268c10a796531d3478c072d66b3698e2b18e. --- src/gui/src/components/analyze/ToolbarFilterAnalyze.vue | 2 +- src/gui/src/components/assess/ToolbarFilterAssess.vue | 2 +- src/gui/src/components/assets/ToolbarFilterAssets.vue | 2 +- src/gui/src/components/common/ToolbarFilter.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue b/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue index b384e1027..51c433c50 100644 --- a/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue +++ b/src/gui/src/components/analyze/ToolbarFilterAnalyze.vue @@ -157,7 +157,7 @@ export default { if (this.publish_selector === false) { this.$refs.toolbarGroupAnalyze.disableMultiSelect() } - }, 800); + }, 300); }, changeTheme() { diff --git a/src/gui/src/components/assess/ToolbarFilterAssess.vue b/src/gui/src/components/assess/ToolbarFilterAssess.vue index e307001ee..4b5e6a8b3 100644 --- a/src/gui/src/components/assess/ToolbarFilterAssess.vue +++ b/src/gui/src/components/assess/ToolbarFilterAssess.vue @@ -199,7 +199,7 @@ if (self.analyze_selector === false) { self.$refs.toolbarGroupAssess.disableMultiSelect() } - }, 800); + }, 300); }, changeTheme() { diff --git a/src/gui/src/components/assets/ToolbarFilterAssets.vue b/src/gui/src/components/assets/ToolbarFilterAssets.vue index 76e619e7b..0678f3c1b 100644 --- a/src/gui/src/components/assets/ToolbarFilterAssets.vue +++ b/src/gui/src/components/assets/ToolbarFilterAssets.vue @@ -84,7 +84,7 @@ this.timeout = setTimeout(function () { this.$root.$emit('update-assets-filter', this.filter); - }, 800); + }, 300); }, changeTheme() { this.$vuetify.theme.themes.light.primary = "#f0f"; diff --git a/src/gui/src/components/common/ToolbarFilter.vue b/src/gui/src/components/common/ToolbarFilter.vue index 8514e01a8..fca036701 100644 --- a/src/gui/src/components/common/ToolbarFilter.vue +++ b/src/gui/src/components/common/ToolbarFilter.vue @@ -53,7 +53,7 @@ let self = this; this.timeout = setTimeout(function(){ self.$root.$emit('update-items-filter', self.filter) - }, 800); + },800); }, changeTheme() { this.$vuetify.theme.themes.light.primary = "#f0f"; From 6ac8c72f6f300c30cdc6631fb3ea7233f780f6ba Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Wed, 3 Jan 2024 16:16:23 +0100 Subject: [PATCH 03/49] Cancel the same GET request (not yed processed) on some main screens. This prevent blinking, dalayed loading old data. Need solve cancel backend actions too (database selects..) --- src/gui/src/api/analyze.js | 2 +- src/gui/src/api/assess.js | 2 +- src/gui/src/api/dashboard.js | 2 +- src/gui/src/api/publish.js | 2 +- src/gui/src/services/api_service.js | 25 +++++++++++++++++++++++++ src/gui/src/store/analyze.js | 3 ++- src/gui/src/store/assess.js | 3 ++- src/gui/src/store/dashboard.js | 3 ++- src/gui/src/store/publish.js | 3 ++- 9 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/gui/src/api/analyze.js b/src/gui/src/api/analyze.js index 78768ee37..7c4c5e4cb 100644 --- a/src/gui/src/api/analyze.js +++ b/src/gui/src/api/analyze.js @@ -16,7 +16,7 @@ export function getAllReportItems(filter_data) { filter += "&offset=" + encodeURIComponent(filter_data.offset) filter += "&limit=" + encodeURIComponent(filter_data.limit) - return ApiService.get('/analyze/report-items' + filter) + return ApiService.getWithCancel('screenData', '/analyze/report-items' + filter) } export function getReportItem(report_item_id) { diff --git a/src/gui/src/api/assess.js b/src/gui/src/api/assess.js index 17d2424e6..6b4aef356 100644 --- a/src/gui/src/api/assess.js +++ b/src/gui/src/api/assess.js @@ -19,7 +19,7 @@ export function getNewsItemsByGroup(group_id, filter_data) { filter += "&offset=" + encodeURIComponent(filter_data.offset) filter += "&limit=" + encodeURIComponent(filter_data.limit) - return ApiService.get('/assess/news-item-aggregates-by-group/' + group_id + filter) + return ApiService.getWithCancel('screenData', '/assess/news-item-aggregates-by-group/' + group_id + filter) } export function addNewsItem(data) { diff --git a/src/gui/src/api/dashboard.js b/src/gui/src/api/dashboard.js index 8d1cdcffb..772c7e28e 100644 --- a/src/gui/src/api/dashboard.js +++ b/src/gui/src/api/dashboard.js @@ -1,5 +1,5 @@ import ApiService from "@/services/api_service"; export function getDashboardData() { - return ApiService.get('/dashboard-data') + return ApiService.getWithCancel('screenData', '/dashboard-data') } \ No newline at end of file diff --git a/src/gui/src/api/publish.js b/src/gui/src/api/publish.js index 660cbb3d8..56eaf716f 100644 --- a/src/gui/src/api/publish.js +++ b/src/gui/src/api/publish.js @@ -7,7 +7,7 @@ export function getAllProducts(filter_data) { filter += "&offset=" + encodeURIComponent(filter_data.offset) filter += "&limit=" + encodeURIComponent(filter_data.limit) - return ApiService.get('/publish/products' + filter) + return ApiService.getWithCancel('screenData', '/publish/products' + filter) } export function createProduct(data) { diff --git a/src/gui/src/services/api_service.js b/src/gui/src/services/api_service.js index 34fb5ba9a..5c9b983f6 100644 --- a/src/gui/src/services/api_service.js +++ b/src/gui/src/services/api_service.js @@ -1,5 +1,8 @@ import axios from 'axios' +var abortControllers = {}; +//let cancRequest = null; + const ApiService = { init(baseURL) { @@ -16,9 +19,31 @@ const ApiService = { }, get(resource, data = {}) { + //window.console.debug("GET:", resource); return axios.get(resource, data) }, + getWithCancel(resType, resource) { + // resType: cancel key that abort request (support for multiple cancels) + if (resType in abortControllers) { + // window.console.debug("CANCEL", resType); + abortControllers[resType].abort(); + } + + abortControllers[resType] = new AbortController(); + let promise = axios.get(resource, { + signal: abortControllers[resType].signal + }).catch(function (e) { + if (axios.isCancel(e)) { + window.console.debug("request canceled:", resource); + } else { + throw e; + } + }); + // window.console.debug("GET CANCEL:", resource, promise); + return promise; + }, + post(resource, data) { return axios.post(resource, data) }, diff --git a/src/gui/src/store/analyze.js b/src/gui/src/store/analyze.js index 6d21e45d1..1c33492a9 100644 --- a/src/gui/src/store/analyze.js +++ b/src/gui/src/store/analyze.js @@ -25,7 +25,8 @@ const actions = { return getAllReportItems(data) .then(response => { - context.commit('setReportItems', response.data); + if (response) + context.commit('setReportItems', response.data); }) }, diff --git a/src/gui/src/store/assess.js b/src/gui/src/store/assess.js index 1ea1710fb..f3345128b 100644 --- a/src/gui/src/store/assess.js +++ b/src/gui/src/store/assess.js @@ -15,7 +15,8 @@ const actions = { return getNewsItemsByGroup(data.group_id, data.data) .then(response => { - context.commit('setNewsItems', response.data); + if (response) + context.commit('setNewsItems', response.data); }) }, diff --git a/src/gui/src/store/dashboard.js b/src/gui/src/store/dashboard.js index 2d2098d2b..b86f82a2f 100644 --- a/src/gui/src/store/dashboard.js +++ b/src/gui/src/store/dashboard.js @@ -18,7 +18,8 @@ const actions = { return getDashboardData() .then(response => { - context.commit('setDashboardData', response.data); + if (response) + context.commit('setDashboardData', response.data); }) } }; diff --git a/src/gui/src/store/publish.js b/src/gui/src/store/publish.js index ee5d61332..cf16c764a 100644 --- a/src/gui/src/store/publish.js +++ b/src/gui/src/store/publish.js @@ -12,7 +12,8 @@ const actions = { return getAllProducts(data) .then(response => { - context.commit('setProducts', response.data); + if (response) + context.commit('setProducts', response.data); }) }, From 010b8de9fca5e049b6bab9ed4f0b9c6157b0e35b Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Thu, 4 Jan 2024 14:29:22 +0100 Subject: [PATCH 04/49] Add/correct translation for some tooltips (removes warnings in console) Added translation settings for navigation bar (avoid false warnings, translate system and not user created strings) --- .../components/assets/ToolbarFilterAssets.vue | 10 +++--- src/gui/src/components/common/Navigation.vue | 5 ++- src/gui/src/i18n/en/messages.js | 18 ++++++++-- src/gui/src/views/nav/ConfigNav.vue | 36 +++++++++---------- src/gui/src/views/nav/DashboardNav.vue | 3 +- src/gui/src/views/nav/ExternalConfigNav.vue | 6 ++-- src/gui/src/views/nav/PublishNav.vue | 3 +- 7 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/gui/src/components/assets/ToolbarFilterAssets.vue b/src/gui/src/components/assets/ToolbarFilterAssets.vue index 0678f3c1b..eb7855970 100644 --- a/src/gui/src/components/assets/ToolbarFilterAssets.vue +++ b/src/gui/src/components/assets/ToolbarFilterAssets.vue @@ -19,19 +19,19 @@ - {{ UI.ICON.VULNERABLE }} + {{ UI.ICON.VULNERABLE }} - + {{ UI.ICON.ALPHABETICAL }} - {{ UI.ICON.DESC }} + {{ UI.ICON.ASC }} - + {{ UI.ICON.VULNERABLE }} - {{ UI.ICON.ASC }} + {{ UI.ICON.DESC }} diff --git a/src/gui/src/components/common/Navigation.vue b/src/gui/src/components/common/Navigation.vue index 3f7a65361..a0994abca 100644 --- a/src/gui/src/components/common/Navigation.vue +++ b/src/gui/src/components/common/Navigation.vue @@ -12,7 +12,10 @@ {{ link.icon }} - {{ $t(link.title) }} + + {{ $t(link.title) }} + {{ link.title }} + diff --git a/src/gui/src/i18n/en/messages.js b/src/gui/src/i18n/en/messages.js index e4ebf10e0..43992892c 100644 --- a/src/gui/src/i18n/en/messages.js +++ b/src/gui/src/i18n/en/messages.js @@ -796,7 +796,7 @@ const messages_en = { MONTH: 'Show news items for the last month' }, sort: { - time: { + date: { ascending: 'Sort news items by collected date ascending', descending: 'Sort news items by collected date descending' }, @@ -832,6 +832,20 @@ const messages_en = { }, }, + assets: { + tooltip: { + filter_vulnerable: "Show/hide vulnerable assets", + sort: { + vulnerability: { + descending: 'Sort assets by vulnerability in descending order', + }, + alphabetical: { + ascending: 'Sort assets alphabetically in ascending order', + }, + }, + } + }, + publish: { tooltip: { range: { @@ -841,7 +855,7 @@ const messages_en = { MONTH: 'Show products for the last month' }, sort: { - time: { + date: { ascending: 'Sort products by creation date ascending', descending: 'Sort products by creation date descending' } diff --git a/src/gui/src/views/nav/ConfigNav.vue b/src/gui/src/views/nav/ConfigNav.vue index 6e615bfd2..1353ad702 100644 --- a/src/gui/src/views/nav/ConfigNav.vue +++ b/src/gui/src/views/nav/ConfigNav.vue @@ -16,31 +16,31 @@ }, data: () => ({ links: [ - { id: 1, icon: 'mdi-account-group', title: 'nav_menu.users', route: '/config/users', permission: 'CONFIG_USER_ACCESS' }, - { id: 2, icon: 'mdi-office-building', title: 'nav_menu.organizations', route: '/config/organizations', permission: 'CONFIG_ORGANIZATION_ACCESS' }, - { id: 3, icon: 'mdi-account-arrow-right', title: 'nav_menu.roles', route: '/config/roles', permission: 'CONFIG_ROLE_ACCESS' }, - { id: 4, icon: 'mdi-lock-check', title: 'nav_menu.acls', route: '/config/acls', permission: 'CONFIG_ACL_ACCESS' }, + { id: 1, icon: 'mdi-account-group', title: 'nav_menu.users', route: '/config/users', permission: 'CONFIG_USER_ACCESS', translate: '1' }, + { id: 2, icon: 'mdi-office-building', title: 'nav_menu.organizations', route: '/config/organizations', permission: 'CONFIG_ORGANIZATION_ACCESS', translate: '1' }, + { id: 3, icon: 'mdi-account-arrow-right', title: 'nav_menu.roles', route: '/config/roles', permission: 'CONFIG_ROLE_ACCESS', translate: '1' }, + { id: 4, icon: 'mdi-lock-check', title: 'nav_menu.acls', route: '/config/acls', permission: 'CONFIG_ACL_ACCESS', translate: '1' }, { id: 5, separator: '1' }, - { id: 6, icon: 'mdi-server-network', title: 'nav_menu.collectors_nodes', route: '/config/collectors/nodes', permission: 'CONFIG_COLLECTORS_NODE_ACCESS' }, - { id: 7, icon: 'mdi-animation-outline', title: 'nav_menu.osint_sources', route: '/config/collectors/sources', permission: 'CONFIG_OSINT_SOURCE_ACCESS'}, - { id: 8, icon: 'mdi-folder-multiple', title: 'nav_menu.osint_source_groups', route: '/config/collectors/groups', permission: 'CONFIG_OSINT_SOURCE_GROUP_ACCESS'}, + { id: 6, icon: 'mdi-server-network', title: 'nav_menu.collectors_nodes', route: '/config/collectors/nodes', permission: 'CONFIG_COLLECTORS_NODE_ACCESS', translate: '1' }, + { id: 7, icon: 'mdi-animation-outline', title: 'nav_menu.osint_sources', route: '/config/collectors/sources', permission: 'CONFIG_OSINT_SOURCE_ACCESS', translate: '1' }, + { id: 8, icon: 'mdi-folder-multiple', title: 'nav_menu.osint_source_groups', route: '/config/collectors/groups', permission: 'CONFIG_OSINT_SOURCE_GROUP_ACCESS', translate: '1' }, { id: 9, separator: '1' }, - { id: 10, icon: 'mdi-server-network', title: 'nav_menu.presenters_nodes', route: '/config/presenters/nodes', permission: 'CONFIG_PRESENTERS_NODE_ACCESS' }, - { id: 12, icon: 'mdi-file-document-outline', title: 'nav_menu.product_types', route: '/config/product/types', permission: 'CONFIG_PRODUCT_TYPE_ACCESS' }, + { id: 10, icon: 'mdi-server-network', title: 'nav_menu.presenters_nodes', route: '/config/presenters/nodes', permission: 'CONFIG_PRESENTERS_NODE_ACCESS', translate: '1' }, + { id: 12, icon: 'mdi-file-document-outline', title: 'nav_menu.product_types', route: '/config/product/types', permission: 'CONFIG_PRODUCT_TYPE_ACCESS', translate: '1' }, { id: 13, separator: '1' }, - { id: 14, icon: 'mdi-server-network', title: 'nav_menu.publishers_nodes', route: '/config/publishers/nodes', permission: 'CONFIG_PUBLISHERS_NODE_ACCESS' }, - { id: 15, icon: 'mdi-file-star-outline', title: 'nav_menu.publisher_presets', route: '/config/publishers/presets', permission: 'CONFIG_PUBLISHER_PRESET_ACCESS' }, + { id: 14, icon: 'mdi-server-network', title: 'nav_menu.publishers_nodes', route: '/config/publishers/nodes', permission: 'CONFIG_PUBLISHERS_NODE_ACCESS', translate: '1' }, + { id: 15, icon: 'mdi-file-star-outline', title: 'nav_menu.publisher_presets', route: '/config/publishers/presets', permission: 'CONFIG_PUBLISHER_PRESET_ACCESS', translate: '1' }, { id: 16, separator: '1' }, - { id: 17, icon: 'mdi-application-variable-outline', title: 'nav_menu.attributes', route: '/config/reportitems/attributes', permission: 'CONFIG_ATTRIBUTE_ACCESS' }, - {id: 18, icon: 'mdi-file-table-outline', title: 'nav_menu.report_types', route: '/config/reportitems/types', permission: 'CONFIG_REPORT_TYPE_ACCESS' }, + { id: 17, icon: 'mdi-application-variable-outline', title: 'nav_menu.attributes', route: '/config/reportitems/attributes', permission: 'CONFIG_ATTRIBUTE_ACCESS', translate: '1' }, + { id: 18, icon: 'mdi-file-table-outline', title: 'nav_menu.report_types', route: '/config/reportitems/types', permission: 'CONFIG_REPORT_TYPE_ACCESS', translate: '1' }, { id: 19, separator: '1' }, - {id: 20, icon: 'mdi-format-list-text', title: 'nav_menu.word_lists', route: '/config/wordlists', permission: 'CONFIG_WORD_LIST_ACCESS' }, + { id: 20, icon: 'mdi-format-list-text', title: 'nav_menu.word_lists', route: '/config/wordlists', permission: 'CONFIG_WORD_LIST_ACCESS', translate: '1' }, { id: 21, separator: '1'}, - { id: 22, icon: 'mdi-remote-desktop', title: 'nav_menu.remote_access', route: '/config/remote/access', permission: 'CONFIG_REMOTE_ACCESS_ACCESS' }, - { id: 23, icon: 'mdi-share-variant', title: 'nav_menu.remote_nodes', route: '/config/remote/nodes', permission: 'CONFIG_REMOTE_NODE_ACCESS' }, + { id: 22, icon: 'mdi-remote-desktop', title: 'nav_menu.remote_access', route: '/config/remote/access', permission: 'CONFIG_REMOTE_ACCESS_ACCESS', translate: '1' }, + { id: 23, icon: 'mdi-share-variant', title: 'nav_menu.remote_nodes', route: '/config/remote/nodes', permission: 'CONFIG_REMOTE_NODE_ACCESS', translate: '1' }, { id: 24, separator: '1'}, - { id: 25, icon: 'mdi-server-network', title: 'nav_menu.bots_nodes', route: '/config/bots/nodes', permission: 'CONFIG_BOTS_NODE_ACCESS' }, - { id: 26, icon: 'mdi-robot', title: 'nav_menu.bot_presets', route: '/config/bots/presets', permission: 'CONFIG_BOT_PRESET_ACCESS' }, + { id: 25, icon: 'mdi-server-network', title: 'nav_menu.bots_nodes', route: '/config/bots/nodes', permission: 'CONFIG_BOTS_NODE_ACCESS', translate: '1' }, + { id: 26, icon: 'mdi-robot', title: 'nav_menu.bot_presets', route: '/config/bots/presets', permission: 'CONFIG_BOT_PRESET_ACCESS', translate: '1' }, ] }) } diff --git a/src/gui/src/views/nav/DashboardNav.vue b/src/gui/src/views/nav/DashboardNav.vue index 9e9404127..6a03277d5 100644 --- a/src/gui/src/views/nav/DashboardNav.vue +++ b/src/gui/src/views/nav/DashboardNav.vue @@ -10,8 +10,7 @@ }, data: () => ({ - links: [ - ] + links: [] }) } \ No newline at end of file diff --git a/src/gui/src/views/nav/ExternalConfigNav.vue b/src/gui/src/views/nav/ExternalConfigNav.vue index c3f1a9815..6036cef72 100644 --- a/src/gui/src/views/nav/ExternalConfigNav.vue +++ b/src/gui/src/views/nav/ExternalConfigNav.vue @@ -15,9 +15,9 @@ }, data: () => ({ links: [ - { id: 1, icon: 'mdi-account-group', title: 'nav_menu.users', route: '/config/external/users' }, - { id: 2, icon: 'mdi-folder-multiple', title: 'nav_menu.asset_groups', route: '/config/external/groups'}, - { id: 3, icon: 'mdi-email-multiple-outline', title: 'nav_menu.notification_templates', route: '/config/external/templates'}, + { id: 1, icon: 'mdi-account-group', title: 'nav_menu.users', route: '/config/external/users', translate: '1' }, + { id: 2, icon: 'mdi-folder-multiple', title: 'nav_menu.asset_groups', route: '/config/external/groups', translate: '1' }, + { id: 3, icon: 'mdi-email-multiple-outline', title: 'nav_menu.notification_templates', route: '/config/external/templates', translate: '1' }, ] }) } diff --git a/src/gui/src/views/nav/PublishNav.vue b/src/gui/src/views/nav/PublishNav.vue index 01ac58177..7f164d845 100644 --- a/src/gui/src/views/nav/PublishNav.vue +++ b/src/gui/src/views/nav/PublishNav.vue @@ -14,8 +14,7 @@ Navigation }, data: () => ({ - links: [ - ] + links: [] }) } \ No newline at end of file From edabe0c4f1554fe91c14b8bb350d8ef252cc66ad Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Mon, 8 Jan 2024 13:10:52 +0100 Subject: [PATCH 05/49] unused comment --- src/gui/src/services/api_service.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/src/services/api_service.js b/src/gui/src/services/api_service.js index 5c9b983f6..8fe160a91 100644 --- a/src/gui/src/services/api_service.js +++ b/src/gui/src/services/api_service.js @@ -1,7 +1,6 @@ import axios from 'axios' var abortControllers = {}; -//let cancRequest = null; const ApiService = { From 61138143dc5e2c499e708a4b24d5c337ab2dfd4c Mon Sep 17 00:00:00 2001 From: multiflexi Date: Tue, 9 Jan 2024 13:03:36 +0100 Subject: [PATCH 06/49] addition of Czech language vatiables and files to code --- src/gui/src/i18n/messages.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/src/i18n/messages.js b/src/gui/src/i18n/messages.js index 525a7e200..3048e932c 100644 --- a/src/gui/src/i18n/messages.js +++ b/src/gui/src/i18n/messages.js @@ -1,9 +1,11 @@ +import messages_cs from "@/i18n/cs/messages"; import messages_en from "@/i18n/en/messages"; import messages_sk from "@/i18n/sk/messages"; const messages = { + cs: messages_cs, en: messages_en, sk: messages_sk }; -export default messages \ No newline at end of file +export default messages From 2bf81e99801e4e8b19b61d2cfae0c7e872dc4550 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Tue, 9 Jan 2024 13:05:49 +0100 Subject: [PATCH 07/49] fix inconsistency for English --- src/gui/src/i18n/en/messages.js | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/gui/src/i18n/en/messages.js b/src/gui/src/i18n/en/messages.js index e4ebf10e0..dc1b77334 100644 --- a/src/gui/src/i18n/en/messages.js +++ b/src/gui/src/i18n/en/messages.js @@ -143,7 +143,7 @@ const messages_en = { country: "Country", successful: "New organization was successfully added", successful_edit: "Organization was successfully updated", - removed: "Organization was successfully removed", + removed: "Organization was successfully deleted", removed_error: "Organization is in use and could not be deleted", total_count: "Organizations count: " }, @@ -161,7 +161,7 @@ const messages_en = { name: "Name", successful: "New user was successfully added", successful_edit: "User was successfully updated", - removed: "User was successfully removed", + removed: "User was successfully deleted", removed_error: "User is in use and could not be deleted", organizations: "Organizations", roles: "Roles", @@ -185,7 +185,7 @@ const messages_en = { key: "Key", successful: "New collectors node was successfully added", successful_edit: "Collectors node was successfully updated", - removed: "Collectors node was successfully removed", + removed: "Collectors node was successfully deleted", removed_error: "Collectors node is in use and could not be deleted", total_count: "Collectors nodes count: " }, @@ -204,7 +204,7 @@ const messages_en = { description: "Description", successful: "New OSINT source was successfully added", successful_edit: "OSINT source was successfully updated", - removed: "OSINT source was successfully removed", + removed: "OSINT source was successfully deleted", removed_error: "OSINT source is in use and could not be deleted", word_lists: "Word Lists", type: "Type", @@ -242,7 +242,7 @@ const messages_en = { description: "Description", successful: "New OSINT source group was successfully added", successful_edit: "OSINT source group was successfully updated", - removed: "OSINT source group was successfully removed", + removed: "OSINT source group was successfully deleted", removed_error: "OSINT source group is in use and could not be deleted", title: "Title", osint_sources: "OSINT Sources", @@ -264,7 +264,7 @@ const messages_en = { description: "Description", successful: "New role was successfully added", successful_edit: "Role was successfully updated", - removed: "Role was successfully removed", + removed: "Role was successfully deleted", removed_error: "Role is in use and could not be deleted", title: "Title", permissions: "Permissions", @@ -291,7 +291,7 @@ const messages_en = { modify: "Modify", successful: "New ACL was successfully added", successful_edit: "ACL was successfully updated", - removed: "ACL was successfully removed", + removed: "ACL was successfully deleted", removed_error: "ACL is in use and could not be deleted", roles: "Roles", users: "Users", @@ -314,7 +314,7 @@ const messages_en = { use_for_notifications: "Use for all global notifications", successful: "New publisher preset was successfully added", successful_edit: "Publisher preset was successfully updated", - removed: "Publisher preset was successfully removed", + removed: "Publisher preset was successfully deleted", removed_error: "Publisher preset is in use and could not be deleted", total_count: "Publisher presets count: " }, @@ -334,7 +334,7 @@ const messages_en = { description: "Description", successful: "New product type was successfully added", successful_edit: "Product type was successfully updated", - removed: "Product type was successfully removed", + removed: "Product type was successfully deleted", removed_error: "Product type is in use and could not be deleted", total_count: "Product types count: ", help: "Template parameters description", @@ -374,7 +374,7 @@ const messages_en = { key: "Key", successful: "New presenters node was successfully added", successful_edit: "Presenters node was successfully updated", - removed: "Presenters node was successfully removed", + removed: "Presenters node was successfully deleted", removed_error: "Presenters node is in use and could not be deleted", total_count: "Presenters nodes count: " }, @@ -394,7 +394,7 @@ const messages_en = { key: "Key", successful: "New publishers node was successfully added", successful_edit: "Publishers node was successfully updated", - removed: "Publishers node was successfully removed", + removed: "Publishers node was successfully deleted", removed_error: "Publishers node is in use and could not be deleted", total_count: "Publishers nodes count: " }, @@ -414,7 +414,7 @@ const messages_en = { key: "Key", successful: "New bots node was successfully added", successful_edit: "Bots node was successfully updated", - removed: "Bots node was successfully removed", + removed: "Bots node was successfully deleted", removed_error: "Bots node is in use and could not be deleted", total_count: "Bots nodes count: " }, @@ -434,7 +434,7 @@ const messages_en = { description: "Description", successful: "New bot preset was successfully added", successful_edit: "Bot preset was successfully updated", - removed: "Bot preset was successfully removed", + removed: "Bot preset was successfully deleted", removed_error: "Bot preset is in use and could not be deleted", total_count: "Bot presets count: " }, @@ -460,7 +460,7 @@ const messages_en = { default_value: "Default Value", successful: "New attribute was successfully added", successful_edit: "Attribute was successfully updated", - removed: "Attribute was successfully removed", + removed: "Attribute was successfully deleted", removed_error: "Attribute is in use and could not be deleted", value: "Value", value_text: "Value text", @@ -679,7 +679,7 @@ const messages_en = { successful: "New report item type was successfully added", successful_edit: "Report item type was successfully updated", removed_error: "Report item type is in use and could not be deleted", - removed: "Report item type was successfully removed", + removed: "Report item type was successfully deleted", total_count: "Report types count: " }, @@ -696,7 +696,7 @@ const messages_en = { report_type: "Report Item Type", successful: "New report item was successfully added", successful_edit: "Report item was successfully saved", - removed: "Report item was successfully removed", + removed: "Report item was successfully deleted", removed_error: "Report item is in use and could not be deleted", select: "Select Report Items", select_remote: "Select Report Items from Remote Nodes", @@ -729,7 +729,7 @@ const messages_en = { report_type: "Product Type", successful: "New product was successfully added", successful_edit: "Product was successfully saved", - removed: "Product was successfully removed", + removed: "Product was successfully deleted", removed_error: "Product is in use and could not be deleted", preview: "Show product preview", publish: "Publish product", @@ -900,7 +900,7 @@ const messages_en = { use_for_stop_words: "Use as stop word list", successful: "New word list was successfully added", successful_edit: "Word list was successfully updated", - remove: "Word list was successfully removed", + remove: "Word list was successfully deleted", removed_error: "Word list is in use and could not be deleted", value: "Value", new_word: "New Word", @@ -929,7 +929,7 @@ const messages_en = { allowed_users: "Allowed users (If none is selected than all users are allowed)", successful: "New asset group was successfully added", successful_edit: "Asset group was successfully updated", - removed: "Asset group was successfully removed", + removed: "Asset group was successfully deleted", removed_error: "Asset group is in use and could not be deleted", total_count: "Asset groups count: " }, @@ -951,7 +951,7 @@ const messages_en = { recipients: "Recipients", successful: "New notification template was successfully added", successful_edit: "Notification template was successfully updated", - removed: "Notification template was successfully removed", + removed: "Notification template was successfully deleted", removed_error: "Notification template is in use and could not be deleted", total_count: "Notification templates count: " }, @@ -974,7 +974,7 @@ const messages_en = { value: "Value", successful: "New asset was successfully added", successful_edit: "Asset was successfully updated", - removed: "Asset was successfully removed", + removed: "Asset was successfully deleted", removed_error: "Asset is in use and could not be deleted", total_count: "Assets count: ", vulnerabilities: "Vulnerabilities", @@ -1002,7 +1002,7 @@ const messages_en = { enabled: "Enabled", successful: "New remote access was successfully added", successful_edit: "Remote access was successfully updated", - removed: "Remote access was successfully removed", + removed: "Remote access was successfully deleted", removed_error: "Remote access is in use and could not be deleted", osint_sources: "OSINT Sources to share", report_item_types: "Report Item Types to share", @@ -1031,7 +1031,7 @@ const messages_en = { osint_source_group: "Synchronize to OSINT source group", successful: "New remote node was successfully added", successful_edit: "Remote node was successfully updated", - removed: "Remote node was successfully removed", + removed: "Remote node was successfully deleted", removed_error: "Remote node is in use and could not be deleted", total_count: "Remote nodes count: " }, @@ -1054,4 +1054,4 @@ const messages_en = { } }; -export default messages_en \ No newline at end of file +export default messages_en From 92ee614f6c556733a927bf2a45a058258ac166b1 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Tue, 9 Jan 2024 13:15:09 +0100 Subject: [PATCH 08/49] use newer version of vue-i18n --- src/gui/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/package.json b/src/gui/package.json index 272750546..0c60e41d0 100644 --- a/src/gui/package.json +++ b/src/gui/package.json @@ -44,7 +44,7 @@ "vue-cookies": "^1.7.4", "vue-csv-import": "^3.3.10", "vue-cvss": "^1.1.2", - "vue-i18n": "^8.26.7", + "vue-i18n": "^8.28.2", "vue-keypress": "^1.4.0", "vue-quick-chat": "^1.2.8", "vue-quill-editor": "^3.0.6", From b48e35f824d05095c1a85ffc7f9a59c8dc0a354c Mon Sep 17 00:00:00 2001 From: multiflexi Date: Tue, 9 Jan 2024 19:45:19 +0100 Subject: [PATCH 09/49] improve language settings and selection --- docker/.env | 3 +++ docker/docker-compose.yml | 2 +- src/gui/src/main.js | 29 ++++++++++++++++++++--------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/docker/.env b/docker/.env index f71c53f63..000a566f0 100644 --- a/docker/.env +++ b/docker/.env @@ -12,6 +12,9 @@ TARANIS_NG_TAG=v23.09.1 # Timezone for all containers TZ=Europe/Bratislava +# Force language +VUE_APP_TARANIS_NG_LOCALE="" + # Default passwords. CHANGE THESE FOR PRODUCTION! POSTGRES_PASSWORD=supersecret POSTGRES_KEYCLOAK_PASSWORD=supersecret diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 2f4be5755..d9fa83369 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -222,7 +222,7 @@ services: VUE_APP_TARANIS_NG_URL: "${TARANIS_NG_HTTPS_URI}" VUE_APP_TARANIS_NG_CORE_API: "${TARANIS_NG_HTTPS_URI}/api/v1" VUE_APP_TARANIS_NG_CORE_SSE: "${TARANIS_NG_HTTPS_URI}/sse" - VUE_APP_TARANIS_NG_LOCALE: en + VUE_APP_TARANIS_NG_LOCALE: "${VUE_APP_TARANIS_NG_LOCALE}" TZ: "${TZ}" labels: traefik.enable: "true" diff --git a/src/gui/src/main.js b/src/gui/src/main.js index 855933616..b86c4a8f6 100644 --- a/src/gui/src/main.js +++ b/src/gui/src/main.js @@ -4,14 +4,14 @@ import Vue from 'vue'; import Vuetify from 'vuetify/lib'; //import colors from 'vuetify/lib/util/colors' import App from './App.vue' -import {router} from './router' -import {store} from '@/store/store' +import { router } from './router' +import { store } from '@/store/store' import ApiService from "@/services/api_service"; import VueI18n from 'vue-i18n' import messages from "@/i18n/messages"; import VeeValidate from 'vee-validate'; import Themes from './assets/themes'; -import {Scroll} from 'vuetify/lib/directives'; +import { Scroll } from 'vuetify/lib/directives'; import CKEditor from '@ckeditor/ckeditor5-vue' import VueCookies from 'vue-cookies' import VueSSE from 'vue-sse'; @@ -24,7 +24,7 @@ import layout_config from "./assets/layout_config"; const CSL = { install(Vue) { Vue.prototype.UI = layout_config - this.UI = () => {} + this.UI = () => { } } } Vue.use(CSL); @@ -44,11 +44,11 @@ Vue.use(Vuetify, { }); Vue.use(Vuetify, { - iconfont: 'md' + iconfont: 'md' }); Vue.use(Vuetify, { - iconfont: 'mdi' + iconfont: 'mdi' }); Vue.use(CKEditor); @@ -62,8 +62,19 @@ const vuetify = new Vuetify({ Vue.use(VueI18n); +let bash_locale = "$VUE_APP_TARANIS_NG_LOCALE"; +let locale; + +if (bash_locale) { + locale = bash_locale; +} else if (typeof (process.env.VUE_APP_TARANIS_NG_LOCALE) !== "undefined") { + locale = process.env.VUE_APP_TARANIS_NG_LOCALE; +} else { + locale = navigator.language.split('-')[0]; +} + const i18n = new VueI18n({ - locale: ((typeof(process.env.VUE_APP_TARANIS_NG_LOCALE) == "undefined") ? "$VUE_APP_TARANIS_NG_LOCALE" : process.env.VUE_APP_TARANIS_NG_LOCALE), + locale: locale, fallbackLocale: 'en', messages }); @@ -73,7 +84,7 @@ Vue.use(VeeValidate, { i18n, }); -ApiService.init(((typeof(process.env.VUE_APP_TARANIS_NG_CORE_API) == "undefined") ? "$VUE_APP_TARANIS_NG_CORE_API" : process.env.VUE_APP_TARANIS_NG_CORE_API)); +ApiService.init(((typeof (process.env.VUE_APP_TARANIS_NG_CORE_API) == "undefined") ? "$VUE_APP_TARANIS_NG_CORE_API" : process.env.VUE_APP_TARANIS_NG_CORE_API)); if (localStorage.ACCESS_TOKEN) { store.dispatch('setToken', (localStorage.ACCESS_TOKEN)).then() @@ -92,4 +103,4 @@ export const vm = new Vue({ this.$store.commit('setVerticalView', val); } -}).$mount('#app'); \ No newline at end of file +}).$mount('#app'); From 75fca320a97e9ad7660ca418631db9eef79d5095 Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Tue, 16 Jan 2024 16:00:05 +0100 Subject: [PATCH 10/49] Add support for language setting per user --- .../versions/e87b34c74db0_language.py | 22 ++++++++++++++++ src/core/model/user.py | 7 +++--- src/gui/src/App.vue | 12 ++++++--- src/gui/src/components/UserSettings.vue | 25 +++++++++++++++++-- src/gui/src/store/settings.js | 15 +++++++++++ src/shared/shared/schema/user.py | 1 + 6 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 src/core/migrations/versions/e87b34c74db0_language.py diff --git a/src/core/migrations/versions/e87b34c74db0_language.py b/src/core/migrations/versions/e87b34c74db0_language.py new file mode 100644 index 000000000..2d5c8fc35 --- /dev/null +++ b/src/core/migrations/versions/e87b34c74db0_language.py @@ -0,0 +1,22 @@ +"""add language setting to user profile + +Revision ID: e87b34c74db0 +Revises: d776f47ce040 +Create Date: 2024-01-10 12:58:52.257692 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = 'e87b34c74db0' +down_revision = 'd776f47ce040' +branch_labels = None +depends_on = None + +def upgrade(): + op.add_column('user_profile', sa.Column('language', sa.VARCHAR(length=2))) + +def downgrade(): + op.drop_column('user_profile', 'language') diff --git a/src/core/model/user.py b/src/core/model/user.py index c73308c83..9273bd6f6 100644 --- a/src/core/model/user.py +++ b/src/core/model/user.py @@ -222,7 +222,7 @@ def update_profile(cls, user, data): user.profile.spellcheck = updated_profile.spellcheck user.profile.dark_theme = updated_profile.dark_theme - + user.profile.language = updated_profile.language user.profile.word_lists = [] from model.word_list import WordList for word_list in updated_profile.word_lists: @@ -272,14 +272,15 @@ class UserProfile(db.Model): spellcheck = db.Column(db.Boolean, default=True) dark_theme = db.Column(db.Boolean, default=False) - + language = db.Column(db.String(2)) hotkeys = db.relationship("Hotkey", cascade="all, delete-orphan") word_lists = db.relationship('WordList', secondary='user_profile_word_list') - def __init__(self, spellcheck, dark_theme, hotkeys, word_lists): + def __init__(self, spellcheck, dark_theme, language, hotkeys, word_lists): self.id = None self.spellcheck = spellcheck self.dark_theme = dark_theme + self.language = language self.hotkeys = hotkeys self.word_lists = [] diff --git a/src/gui/src/App.vue b/src/gui/src/App.vue index 94dd03378..c0cf4ac9d 100644 --- a/src/gui/src/App.vue +++ b/src/gui/src/App.vue @@ -59,6 +59,13 @@ export default { this.sseConnection = null } this.connectSSE() + }, + + initUserSettings() { + this.$store.dispatch('getUserProfile').then(() => { + this.$vuetify.theme.dark = this.$store.getters.getProfileDarkTheme + this.$i18n.locale = this.$store.getters.getProfileLanguage + }); } }, updated() { @@ -77,9 +84,7 @@ export default { if (localStorage.ACCESS_TOKEN) { if (this.isAuthenticated()) { - this.$store.dispatch('getUserProfile').then(() => { - this.$vuetify.theme.dark = this.$store.getters.getProfileDarkTheme - }); + this.initUserSettings(); this.connectSSE() } else { if (this.$store.getters.getJWT) { @@ -107,6 +112,7 @@ export default { }); this.$root.$on('logged-in', () => { + this.initUserSettings(); this.connectSSE() }); diff --git a/src/gui/src/components/UserSettings.vue b/src/gui/src/components/UserSettings.vue index 89e073ec4..7a0fa4b46 100644 --- a/src/gui/src/components/UserSettings.vue +++ b/src/gui/src/components/UserSettings.vue @@ -43,6 +43,14 @@ :label="$t('settings.dark_theme')" > + + + @@ -137,6 +145,7 @@ data: () => ({ visible: false, dark_theme: false, + language: 'en', spellcheck: null, pressKeyVisible: false, shortcuts: [], @@ -150,18 +159,25 @@ {text: 'Description', value: 'description'}, ], word_lists: [], - selected_word_lists: [] + selected_word_lists: [], + languages: [ + { id: 'en', value: 'English' }, + { id: 'sk', value: 'Slovak' }, + ], }), methods: { close() { this.visible = false; - this.$vuetify.theme.dark = this.$store.getters.getDarkTheme + // set original settings values if no SAVE is selected + this.$vuetify.theme.dark = this.$store.getters.getProfileDarkTheme + this.$i18n.locale = this.$store.getters.getProfileLanguage }, save() { this.$store.dispatch('saveUserProfile', { spellcheck: this.spellcheck, dark_theme: this.dark_theme, + language: this.language, hotkeys: this.shortcuts, word_lists: this.selected_word_lists, }).then(() => { @@ -173,6 +189,10 @@ this.$vuetify.theme.dark = this.dark_theme }, + languageChage() { + this.$i18n.locale = this.language + }, + pressKeyDialog(event) { window.addEventListener("keydown", this.pressKey, false); @@ -208,6 +228,7 @@ this.visible = true; this.spellcheck = this.$store.getters.getProfileSpellcheck this.dark_theme = this.$store.getters.getProfileDarkTheme + this.language = this.$store.getters.getProfileLanguage this.selected_word_lists = this.$store.getters.getProfileWordLists this.shortcuts = this.$store.getters.getProfileHotkeys }); diff --git a/src/gui/src/store/settings.js b/src/gui/src/store/settings.js index 0d4e6df6b..919d5e91d 100644 --- a/src/gui/src/store/settings.js +++ b/src/gui/src/store/settings.js @@ -47,6 +47,7 @@ const state = { ], spellcheck: true, dark_theme: false, + language: "", word_lists: [] }; @@ -74,6 +75,7 @@ const mutations = { setUserProfile(state, profile) { state.spellcheck = profile.spellcheck state.dark_theme = profile.dark_theme + state.language = profile.language state.word_lists = profile.word_lists for (let i = 0; i < state.hotkeys.length; i++) { for (let j = 0; j < profile.hotkeys.length; j++) { @@ -102,6 +104,19 @@ const getters = { getProfileWordLists(state) { return state.word_lists; + }, + + getProfileLanguage(state) { + let lng = state.language; + if (!lng) { + if (typeof (process.env.VUE_APP_TARANIS_NG_LOCALE) !== "undefined") { + lng = process.env.VUE_APP_TARANIS_NG_LOCALE; + } + if (!lng) { + lng = "en"; + } + } + return lng; } }; diff --git a/src/shared/shared/schema/user.py b/src/shared/shared/schema/user.py index 022bdc179..f18fa2441 100644 --- a/src/shared/shared/schema/user.py +++ b/src/shared/shared/schema/user.py @@ -66,5 +66,6 @@ class Meta: class UserProfileSchema(Schema): spellcheck = fields.Bool() dark_theme = fields.Bool() + language = fields.Str() word_lists = fields.List(fields.Nested(WordListSchema)) hotkeys = fields.Nested(HotkeySchema, many=True) From 298a5418f0f8c0d4a40c1b50b3a844bf529207b3 Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Tue, 23 Jan 2024 10:22:58 +0100 Subject: [PATCH 11/49] Allow store CVSS as number (quick need for reporting) Same as #163 CVSS might be inserted as a number (small improvements, fixed default value, 1 decimal point, some code enhacements) --- .../common/attribute/AttributeCVSS.vue | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gui/src/components/common/attribute/AttributeCVSS.vue b/src/gui/src/components/common/attribute/AttributeCVSS.vue index d989fb46c..e095f0e52 100644 --- a/src/gui/src/components/common/attribute/AttributeCVSS.vue +++ b/src/gui/src/components/common/attribute/AttributeCVSS.vue @@ -117,7 +117,7 @@ status: "", rules: { vector: value => { - const pattern = /^CVSS:3\.1\/((AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])\/)*(AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$/ + const pattern = /(^CVSS:3\.1\/((AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])\/)*(AV:[NALP]|AC:[LH]|PR:[UNLH]|UI:[NR]|S:[UC]|[CIA]:[NLH]|E:[XUPFH]|RL:[XOTWU]|RC:[XURC]|[CIA]R:[XLMH]|MAV:[XNALP]|MAC:[XLH]|MPR:[XUNLH]|MUI:[XNR]|MS:[XUC]|M[CIA]:[XNLH])$)|(^(10(\.0)?|[0-9](\.[0-9])?)$)/ return value == '' || pattern.test(value) || 'Invalid or Incomplete Vector String' } } @@ -136,29 +136,40 @@ methods: { updateValue(e) { this.calcValue = e; - this.score = this.clc.calculateCVSSFromVector(this.calcValue); - setTimeout(()=>{ + const value = parseFloat(e); + if (value >= 0 && value <= 10) { + // OK + } else { + this.score = this.clc.calculateCVSSFromVector(this.calcValue); + } + setTimeout(() => { this.values[0].value = e; this.onEdit(0); - },200); + }, 200); }, report(e) { this.status = e; }, directValueChange() { - let vsReport = this.clc.calculateCVSSFromVector(this.calcValue); - - if(vsReport.success) { - this.score = vsReport; - + const value = parseFloat(this.calcValue); + if (value >= 0 && value <= 10) { this.values[0].value = this.calcValue; this.onKeyUp(0); + } else { + let vsReport = this.clc.calculateCVSSFromVector(this.calcValue); + if (vsReport.success) { + this.score = vsReport; + this.values[0].value = this.calcValue; + this.onKeyUp(0); + } } } - }, - mounted(){ - if( this.values[0].value !== "" ) { + mounted() { + const value = parseFloat(this.values[0].value); + if (value >= 0 && value <= 10) { + this.calcValue = this.values[0].value; + } else if (this.values[0].value !== "") { this.calcValue = this.values[0].value; this.score = this.clc.calculateCVSSFromVector(this.calcValue); } else { From bcb1ca04092da245498e83d559c7f3d44ac62f83 Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Wed, 31 Jan 2024 17:06:45 +0100 Subject: [PATCH 12/49] PDF report update: - fix broken AFFECTED SYSTEMS field (affected by later update) - add suport for multiline in DESCRIPTION, AFFECTED SYSTEMS & RECOMMENDATIONS fields --- .../versions/dfc12c30395b_Affected_systems.py | 69 +++++++++++++++++++ src/presenters/templates/css/custom.css | 3 + src/presenters/templates/pdf_template.html | 16 +---- 3 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 src/core/migrations/versions/dfc12c30395b_Affected_systems.py diff --git a/src/core/migrations/versions/dfc12c30395b_Affected_systems.py b/src/core/migrations/versions/dfc12c30395b_Affected_systems.py new file mode 100644 index 000000000..23d6c698c --- /dev/null +++ b/src/core/migrations/versions/dfc12c30395b_Affected_systems.py @@ -0,0 +1,69 @@ +"""Affected systems to text area + +Revision ID: dfc12c30395b +Revises: e87b34c74db0 +Create Date: 2024-01-31 13:35:10.639848 + +""" +from alembic import op +from datetime import datetime +from sqlalchemy import orm, Column, ForeignKey, String, Integer, DateTime, Boolean, Enum, text +from sqlalchemy.ext.declarative import declarative_base +import sqlalchemy as sa + +Base = declarative_base() + +# revision identifiers, used by Alembic. +revision = 'dfc12c30395b' +down_revision = 'e87b34c74db0' +branch_labels = None +depends_on = None + +class ReportItemType_dfc12c30395b(Base): + __tablename__ = 'report_item_type' + id = Column(Integer, primary_key=True, server_default=text("nextval('report_item_type_id_seq'::regclass)")) + title = Column(String) + +class AttributeGroup_dfc12c30395b(Base): + __tablename__ = 'attribute_group' + id = Column(Integer, primary_key=True, server_default=text("nextval('attribute_group_id_seq'::regclass)")) + title = Column(String) + report_item_type_id = Column(ForeignKey('report_item_type.id')) + +class AttributeGroupItem_dfc12c30395b(Base): + __tablename__ = 'attribute_group_item' + id = Column(Integer, primary_key=True, server_default=text("nextval('attribute_group_item_id_seq'::regclass)")) + title = Column(String) + attribute_group_id = Column(ForeignKey('attribute_group.id')) + attribute_id = Column(ForeignKey('attribute.id')) + +class Attribute_dfc12c30395b(Base): + __tablename__ = 'attribute' + id = Column(Integer, primary_key=True, server_default=text("nextval('attribute_id_seq'::regclass)")) + name = Column(String, nullable=False) + +def upgrade(): + bind = op.get_bind() + session = orm.Session(bind=bind) + + # ======= Update existing old report ======= + rit = session.query(ReportItemType_dfc12c30395b).filter_by(title = 'Vulnerability Report').first() + if rit: + ag = session.query(AttributeGroup_dfc12c30395b).filter_by(title = 'Identify and Act', report_item_type_id = rit.id).first() + if ag: + atr_text_id = session.query(Attribute_dfc12c30395b).filter_by(name = 'Text').first().id + agi = session.query(AttributeGroupItem_dfc12c30395b).filter_by(title = 'Affected systems', attribute_group_id = ag.id, attribute_id = atr_text_id).first() + if agi: + atr_text_area_id = session.query(Attribute_dfc12c30395b).filter_by(name = 'Text Area').first().id + agi.attribute_id = atr_text_area_id + session.add(agi) + session.commit() + else: + print("Nothing to upgrade...", flush=True) + else: + print("No report attribute group to upgrade...", flush=True) + else: + print("No report to upgrade...", flush=True) + +def downgrade(): + pass \ No newline at end of file diff --git a/src/presenters/templates/css/custom.css b/src/presenters/templates/css/custom.css index 21a1768ee..7da1967a5 100644 --- a/src/presenters/templates/css/custom.css +++ b/src/presenters/templates/css/custom.css @@ -71,6 +71,9 @@ input { .checkbox-button__control { transform: scale(0.75) } +.crlf { + white-space: pre-line; +} /*FOOTER*/ .footer_text { diff --git a/src/presenters/templates/pdf_template.html b/src/presenters/templates/pdf_template.html index 45d55fd2e..4406a6b33 100644 --- a/src/presenters/templates/pdf_template.html +++ b/src/presenters/templates/pdf_template.html @@ -124,9 +124,7 @@ DESCRIPTION - - {{ report_item.attrs.description|e }} - + {{ report_item.attrs.description|e }} @@ -202,13 +200,7 @@ AFFECTED SYSTEMS - - {% if report_item.attrs.affected_systems %} - {% for i in report_item.attrs.affected_systems %} -
{{ i|e }}
- {% endfor %} - {% endif %} - + {{ report_item.attrs.affected_systems }} @@ -217,9 +209,7 @@ RECOMMENDATIONS - - {{ report_item.attrs.recommendations }} - + {{ report_item.attrs.recommendations }} From 4c6f56d03ffd4d4873230a9caf77458953576588 Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Fri, 2 Feb 2024 14:40:59 +0100 Subject: [PATCH 13/49] Fix: disable shorcuts on text/textarea fields (prevents typing text) Example: Assess, create report from item and you type N in description field -> all is canceled and it creates new report again --- src/gui/src/assets/keyboard_mixin.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/src/assets/keyboard_mixin.js b/src/gui/src/assets/keyboard_mixin.js index 7744461e9..e43c84ea4 100644 --- a/src/gui/src/assets/keyboard_mixin.js +++ b/src/gui/src/assets/keyboard_mixin.js @@ -151,8 +151,12 @@ const keyboardMixin = targetId => ({ } } // window.console.debug("keyAlias:", keyAlias, "activeElement:", document.activeElement); - if ((document.activeElement == search_field || document.activeElement.className == "ql-editor") && (keyAlias !== 'close_item' || press.keyCode !== 27)) { - // when search field or editor is active, ignore all keypresses except Escape + if ((document.activeElement == search_field || + document.activeElement.className == "ql-editor" || + document.activeElement.type == "text" || + document.activeElement.type == "textarea") && (keyAlias !== 'close_item' || press.keyCode !== 27)) { + // when search field, editor, text or textarea is active, ignore all keypresses except Escape + // example problem: Assess, create report from item and you type N in description field -> all is canceled and it creates new report again return; } From ba710c9f35b21bcb4f6f48a99dd2dd34b93c12cb Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Mon, 5 Feb 2024 14:03:41 +0100 Subject: [PATCH 14/49] Fix crash on new user creating --- src/core/model/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/model/user.py b/src/core/model/user.py index 9273bd6f6..10fdeb7d2 100644 --- a/src/core/model/user.py +++ b/src/core/model/user.py @@ -63,7 +63,7 @@ def __init__(self, id, username, name, password, organizations, roles, permissio for permission in permissions: self.permissions.append(Permission.find(permission.id)) - self.profile = UserProfile(True, False, [], []) + self.profile = UserProfile(True, False, None, [], []) self.title = "" self.subtitle = "" self.tag = "" From c1d42af6656eac6de1a6921175feb2ce273b8ac7 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Mon, 5 Feb 2024 14:29:10 +0100 Subject: [PATCH 15/49] English inconsistencies --- src/gui/src/i18n/en/messages.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/src/i18n/en/messages.js b/src/gui/src/i18n/en/messages.js index dc1b77334..4bfdb81ea 100644 --- a/src/gui/src/i18n/en/messages.js +++ b/src/gui/src/i18n/en/messages.js @@ -321,7 +321,7 @@ const messages_en = { product_type: { add_new: "Add new product type", - edit: "Edit new product type", + edit: "Edit product type", node: "Presenters Node", presenter: "Presenter", add: "Add", @@ -361,7 +361,7 @@ const messages_en = { presenters_node: { add_new: "Add new presenters node", - edit: "Edit new presenters node", + edit: "Edit presenters node", add: "Add", save: "Save", add_btn: "Add New", @@ -381,7 +381,7 @@ const messages_en = { publishers_node: { add_new: "Add new publishers node", - edit: "Add new publishers node", + edit: "Edit publishers node", add: "Add", save: "Save", add_btn: "Add New", @@ -401,7 +401,7 @@ const messages_en = { bots_node: { add_new: "Add new bots node", - edit: "Add new bots node", + edit: "Edit bots node", add: "Add", save: "Save", add_btn: "Add New", From 003c9a453614736901772a9f3efb327c6a46e688 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Mon, 5 Feb 2024 16:58:55 +0100 Subject: [PATCH 16/49] Czech translation --- src/gui/src/i18n/cs/messages.js | 1057 +++++++++++++++++++++++++++++++ 1 file changed, 1057 insertions(+) create mode 100644 src/gui/src/i18n/cs/messages.js diff --git a/src/gui/src/i18n/cs/messages.js b/src/gui/src/i18n/cs/messages.js new file mode 100644 index 000000000..a78ce7ecf --- /dev/null +++ b/src/gui/src/i18n/cs/messages.js @@ -0,0 +1,1057 @@ +const messages_cs = { + + validations: { + messages: { + _default: "Vyplňte prosím povinné pole" + }, + + custom: { + username: { + required: "Vyplňte prosím své uživatelské jméno" + }, + password: { + required: "Heslo je povinné" + }, + url: { + required: "URL je povinné" + }, + key: { + required: "API klíč je povinný" + }, + name: { + required: "Jméno je povinné" + }, + parameter: { + required: "Povinné pole" + }, + password_check: { + required: "Heslo je povinné", + confirmed: "Hesla se neshodují" + }, + collector_node: { + required: "Vyberte instanci kolektoru" + }, + file: { + required: "Soubor je povinný" + } + }, + }, + + login: { + title: "Prosím přihlaste se", + username: "Uživatelské jméno", + password: "Heslo", + submit: "Přihlásit se", + error: "Uživatelské jméno nebo heslo je nesprávné" + }, + + user_menu: { + settings: "Nastavení uživatele", + logout: "Odhlásit", + dark_theme: "Tmavý motiv", + }, + + main_menu: { + enter: "Vložit", + assess: "Vyhodnotit", + analyze: "Analyzovat", + publish: "Zveřejnit", + config: "Nastavení", + dashboard: "Dashboard", + my_assets: "Aktiva" + }, + + nav_menu: { + enter: "Vytvořit novinku", + newsitems: "Novinky", + products: "Reporty", + publications: "Publikace", + recent: "Recent", + popular: "Popular", + favourites: "Oblíbené", + configuration: "Nastavení", + collectors_nodes: "Instance kolektorů", + presenters_nodes: "Instance prezenterů", + publishers_nodes: "Instance vydavatelů", + bots_nodes: "Instance robotů", + osint_sources: "Zdroje OSINT", + osint_source_groups: "Skupiny zdrojů OSINT", + publisher_presets: "Publikační kanály", + bot_presets: "Roboti", + collectors: "Kolektory", + report_items: "Analýzy", + attributes: "Atributy", + report_types: "Typy analýz", + product_types: "Typy publikací", + roles: "Role", + acls: "ACL", + users: "Uživatelé", + organizations: "Organizace", + word_lists: "Seznamy slov", + asset_groups: "Skupiny aktiv", + notification_templates: "Šablony oznámení", + remote_access: "Vzdálený přístup", + remote_nodes: "Vzdálené instance", + local: "Lokální" + }, + + notification: { + close: "Zavřít" + }, + + enter: { + create: "Vytvořit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Novinku se nepodařilo vytvořit.", + title: "Název", + review: "Souhrn", + source: "Zdroj", + link: "Odkaz", + successful: "Novinka byla vytvořena", + }, + + card_item: { + title: "Název", + created: "Vytvořeno", + collected: "Indexováno", + published: "Publikováno", + source: "Zdroj", + status: "Stav", + node: "Instance", + description: "Popis", + in_analyze: "Probíhá analýza", + url: "URL", + name: "Name", + username: "Uživatelské jméno", + aggregated_items: "Sloučené novinky", + }, + + organization: { + add_new: "Přidat novou organizaci", + edit: "Upravit organizaci", + add: "Přidat", + add_btn: "Přidat", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Organizaci se nepodařilo vytvořit.", + name: "Název", + description: "Popis", + street: "Ulice", + city: "Město", + zip: "PSČ", + country: "Země", + successful: "Nová organizace byla vytvořena", + successful_edit: "Organizace byla upravena", + removed: "Organizace byla smazána", + removed_error: "Organizace je používána a nelze ji smazat", + total_count: "Počet organizací: " + }, + + user: { + add_new: "Přidat nového uživatele", + edit: "Upravit uživatele", + add: "Přidat", + add_btn: "Přidat", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Uživatele se nepodařilo vytvořit.", + username: "Uživatelské jméno", + name: "Jméno", + successful: "Uživatel byl vytvořen", + successful_edit: "Uživatel byl upraven", + removed: "Uživatel byl smazán", + removed_error: "Uživatel je používán a nelze jej smazat", + organizations: "Organizace", + roles: "Role", + permissions: "Práva", + total_count: "Počet uživatelů: ", + password: "Heslo", + password_check: "Zadejte heslo znovu", + }, + + collectors_node: { + add_new: "Přidat novou instanci kolektorů", + edit: "Upravit instanci kolektorů", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "K tomuto uzlu kolektoru se nepodařilo připojit.", + name: "Název", + description: "Popis", + url: "URL", + key: "Klíč", + successful: "Nový kolektor byl přidán", + successful_edit: "Instance kolektoru byl upraven", + removed: "Instance kolektoru byla smazána", + removed_error: "Instance kolektoru je používám a nelze jej smazat", + total_count: "Počet uzlů kolektorů: " + }, + + osint_source: { + add_new: "Přidat nový zdroj OSINT", + edit: "Editovat zdroj OSINT", + node: "Instance kolektoru", + collector: "Kolektor", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Tento zdroj OSINT se nepodařilo uložit", + name: "Název", + description: "Popis", + successful: "Nový zdroj OSINT byl přidán", + successful_edit: "Zdroj OSINT byl upraven", + removed: "Zdroj OSINT byl úspěšně smazán", + removed_error: "Zdroj OSINT je používán a nelze jej smazat", + word_lists: "Seznamy slov", + type: "Typ", + total_count: "Počet zdrojů OSINT: ", + osint_source_groups: "Skupiny zdrojů OSINT", + tooltip: { + group_items: "Seskupit novinky do souhrnu", + ungroup_items: "Oddělit zprávy ze souhrnu", + analyze_items: "Vytvořit analýzu z novinek", + read_items: "Označit novinky jako přečtené", + important_items: "Označit novinky jako důležité", + like_items: "Označit jako To se mi líbí", + dislike_items: "Označit jako To se mi nelíbí", + delete_items: "Smazat novinky", + select_all: "Vybrat vše", + unselect_all: "Odznačit vše" + }, + notification: { + success: "Kolektory byly přidány" + }, + dialog_import: "Importovat zdroje OSINT", + import: "Importovat", + export: "Exportovat" + }, + + osint_source_group: { + add_new: "Přidat novou skupinu zdrojů OSINT", + edit: "Upravit skupinu zdrojů OSINT", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Tuto skupinu zdrojů OSINT se nepodařilo uložit.", + name: "Name", + description: "Popis", + successful: "Nová skupina zdrojů OSINT byla přidána", + successful_edit: "Skupina zdrojů OSINT byla upravena", + removed: "Skupina zdrojů OSINT byla smazána", + removed_error: "Skupina zdrojů OSINT je používána a nelze ji odstranit", + title: "Název", + osint_sources: "Zdroje OSINT", + total_count: "Počet skupin zdrojů OSINT: ", + default_group: "Nezařazeno", + default_group_description: "Skupina pro nezařazené zdroje OSINT" + }, + + role: { + add_new: "Přidat novou roli", + edit: "Upravit roli", + add: "Přidat", + add_btn: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Tuto roli se nepodařilo uložit.", + name: "Název", + description: "Popis", + successful: "Nová role byla přidána", + successful_edit: "Role byla upravena", + removed: "Role byla smazána", + removed_error: "Role je používána a nelze ji smazat", + title: "Název", + permissions: "Práva", + total_count: "Počet rolí: " + }, + + acl: { + full_title: "Seznamy pro řízení přístupu (ACL)", + add_new: "Přidat nový ACL", + edit: "Upravit ACL", + add: "Přidat", + add_btn: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Toto ACL se nepodařilo uložit.", + name: "Název", + description: "Popis", + item_type: "Typ položky", + item_id: "ID položky", + everyone: "Everyone", + see: "Prohlížet", + access: "Access", + modify: "Upravit", + successful: "Nový ACL bylo přidáno", + successful_edit: "ACL bylo přidáno", + removed: "ACL bylo smazán", + removed_error: "ACL je používáno a nelze jej smazat", + roles: "Role", + users: "Uživatelé", + total_count: "Počet ACL: " + }, + + publisher_preset: { + add_new: "Přidat nové přednastavení vydavatele", + edit: "Upravit přednastavení vydavatele", + node: "Instance vydavatelů", + publisher: "Vydavatel", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit přednastavení.", + name: "Název", + description: "Popis", + use_for_notifications: "Použit pro všechna globální upozornění", + successful: "Nové přednastavení bylo přidáno", + successful_edit: "Přednastavení bylo upraveno", + removed: "Přednastavení bylo smazáno", + removed_error: "Přednastavení vydavatele se používá a nelze jej smazat", + total_count: "Počet přednastavení vydavatelů: " + }, + + product_type: { + add_new: "Přidat nový typ publikace", + edit: "Upravit typ publikace", + node: "Instance prezenterů", + presenter: "Prezenter", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit typ publikace.", + name: "Název", + description: "Popis", + successful: "Nový typ publikace byla přidána", + successful_edit: "Typ publikace byl upraven", + removed: "Typ publikace byl smazán", + removed_error: "Typ publikace se používá a nelze jej smazat", + total_count: "Počet typů publikací: ", + help: "Popis parametrů šablony", + close: "Zavřít", + choose_report_type: "Vyberte typ analýzy pro zobrazení popisu parametrů", + report_items: "Analýzy", + report_items_object: { + name: "Název", + name_prefix: "Předpona názvu", + type: "Typ analýzy" + }, + news_items: "Novinky", + news_items_object: { + title: "Název", + review: "Souhrn", + content: "Obsah", + author: "Autor", + source: "Zdroj", + link: "Odkaz", + collected: "Datum indexace", + published: "Datum zveřejnění", + } + }, + + presenters_node: { + add_new: "Přidat novou instanci prezenterů", + edit: "Upravit instanci prezenterů", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se připojit k této instanci prezenterů.", + name: "Název", + description: "Popis", + url: "URL", + key: "Heslo", + successful: "Nová instance prezenterů byla přidána", + successful_edit: "Instance prezenterů byla upravena", + removed: "Instance prezenterů byla smazána", + removed_error: "Instance prezenterů je používána a nelze ji smazat", + total_count: "Počet instancí prezenterů: " + }, + + publishers_node: { + add_new: "Přidat novou instanci vydavatelů", + edit: "Upravit instanci vydavatelů", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se připojit k této instanci vydavatelů.", + name: "Name", + description: "Popis", + url: "URL", + key: "Klíč", + successful: "Nová instance vydavatelů byla přidána", + successful_edit: "Instance vydavatelů byla upravena", + removed: "Instance vydavatelů byla smazána", + removed_error: "Instance vydavatelů je používána a nelze ji smazat", + total_count: "Počet instancí vydavatelů: " + }, + + bots_node: { + add_new: "Přidat instanci robotů", + edit: "Upravit instanci robotů", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se připojit k instanci robotů.", + name: "Název", + description: "Popis", + url: "URL", + key: "Klíč", + successful: "Nová instance robotů byla přidána", + successful_edit: "Instance robotů byla upravena", + removed: "Instance robotů byla smazána", + removed_error: "Instance robotů se používá a nelze ji smazat", + total_count: "Počet instancí robotů: " + }, + + bot_preset: { + add_new: "Přidat nové přednastavení robota", + edit: "Upravit přednastavení robota", + node: "Instance robotů", + bot: "Robot", + add: "Přidat", + save: "Uložit", + add_btn: "Přidat", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit tohoto robota.", + name: "Název", + description: "Popis", + successful: "Nové přednastavení robota bylo přidáno", + successful_edit: "Přednastavení robota bylo upraveno", + removed: "Přednastavení robota bylo smazáno", + removed_error: "Přednastavení robota je používáno a nelze jej odstranit", + total_count: "Počet přednastavení robotů: " + }, + + attribute: { + add: "Přidat", + add_btn: "Přidat", + add_new: "Přidat nový atribut", + edit: "Upravit atribut", + add_attachment: "Přidat přílohu", + add_value: "Přidat hodnotu", + select_attachment: "Vybrat přílohu", + select_file: "Vybrat soubor", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit tento atribut", + name: "Název", + description: "Popis", + type: "Typ", + validator: "Validátor", + validator_parameter: "Parametr validátoru", + default_value: "Původní hodnota", + successful: "Nový atribut byl přidán", + successful_edit: "Atribut byl upraven", + removed: "Atribut byl smazán", + removed_error: "Atribut je používán a nemohl být smazán", + value: "Hodnota", + value_text: "Popis hodnoty", + tlp_clear: "TLP:CLEAR", + tlp_green: "TLP:GREEN", + tlp_amber: "TLP:AMBER", + tlp_amber_strict: "TLP:AMBER+STRICT", + tlp_red: "TLP:RED", + attribute_parameters: "Parametry atributu", + attribute_constants: "Konstanty atributu", + import_from_csv: "Importovat z CSV", + new_constant: "Nová konstanta", + attribute: "atribut", + attributes: "Atributy", + new_attribute: "Nový atribut", + min_occurrence: "Minimální výskyt", + max_occurrence: "Maximální výskyt", + total_count: "Počet atributů: ", + import: "Importovat", + load_csv_file: "Načíst CSV soubor", + file_has_header: "Soubor má hlavičku", + search: "Hledat", + reload_cpe: "Znovu načíst CPE slovník", + reload_cve: "Znovu načíst CVE slovník", + delete_existing: "Smazat všechny existující hodnoty", + select_enum: "Vybrat hodnotu konstanty", + reloading: "Opakované načítání slovníku...", + status: "Stav", + select_date: "Vybrat datum", + select_time: "Vybrat čas", + select_datetime: "Vybrat datum a čas", + done: "Hotovo" + }, + + cvss_calculator: { + title: "CVSS Calculator 3.1", + base_score: "Base Score", + attack_vector: "Attack Vector (AV)", + attack_complexity: "Attack Complexity (AC)", + privileges_required: "Privileges Required (PR)", + user_interaction: "User Interaction (UI)", + scope: "Scope (S)", + confidentiality: "Confidentiality (C)", + integrity: "Integrity (I)", + availability: "Availability (A)", + + temporal_score: "Temporal Score", + exploitability_code_maturity: "Exploitability Code Maturity (E)", + remediation_level: "Remediation Level (RL)", + report_confidence: "Report Confidence (RC)", + + environmental_score: "Environmental Score", + confidentiality_requirement: "Confidentiality Requirement (CR)", + integrity_requirement: "Integrity Requirement (IR)", + availability_requirement: "Availability Requirement (AR)", + modified_attack_vector: "Modified Attack Vector (MAV)", + modified_attack_complexity: "Modified Attack Complexity (MAC)", + modified_privileges_required: "Modified Privileges Required (MPR)", + modified_user_interaction: "Modified User Interaction (MUI)", + modified_scope: "Modified Scope (MS)", + modified_confidentiality: "Modified Confidentiality (MC)", + modified_integrity: "Modified Integrity (MI)", + modified_availability: "Modified Availability (MA)", + + network: "Network", + adjacent: "Adjacent", + adjacent_network: "Adjacent Network", + local: "Local", + physical: "Physical", + required: "Required", + unchanged: "Unchanged", + changed: "Changed", + + not_defined: "Not Defined", + none: "None", + low: "Low", + medium: "Medium", + high: "High", + critical: "Critical", + + unproven: "Unproven", + proof_of_concept: "Proof-of-Concept", + functional: "Functional", + + official_fix: "Official Fix", + temporary_fix: "Temporary Fix", + workaround: "Workaround", + unavailable: "Unavailable", + + unknown: "Unknown", + reasonable: "Reasonable", + confirmed: "Confirmed", + + validator: "Neplatný nebo nekompletní textový řetězec" + + }, + + cvss_calculator_tooltip: { + baseMetricGroup_Legend: "The Base Metric group represents the intrinsic characteristics of a vulnerability that are constant over time and across user environments. Determine the vulnerable component and score Attack Vector, Attack Complexity, Privileges Required and User Interaction relative to this.", + AV_Heading: "This metric reflects the context by which vulnerability exploitation is possible. The Base Score increases the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable component.", + AV_N_Label: "The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed, up to and including the entire Internet. Such a vulnerability is often termed 'remotely exploitable' and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers).", + AV_A_Label: "The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared physical (e.g., Bluetooth or IEEE 802.11) or logical (e.g., local IP subnet) network, or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN to an administrative network zone).", + AV_L_Label: "The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Either: the attacker exploits the vulnerability by accessing the target system locally (e.g., keyboard, console), or remotely (e.g., SSH); or the attacker relies on User Interaction by another person to perform actions required to exploit the vulnerability (e.g., tricking a legitimate user into opening a malicious document).", + AV_P_Label: "The attack requires the attacker to physically touch or manipulate the vulnerable component. Physical interaction may be brief or persistent.", + AC_Heading: "This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Such conditions may require the collection of more information about the target or computational exceptions. The assessment of this metric excludes any requirements for user interaction in order to exploit the vulnerability. If a specific configuration is required for an attack to succeed, the Base metrics should be scored assuming the vulnerable component is in that configuration.", + AC_L_Label: "Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success against the vulnerable component.", + AC_H_Label: "A successful attack depends on conditions beyond the attacker's control. That is, a successful attack cannot be accomplished at will, but requires the attacker to invest in some measurable amount of effort in preparation or execution against the vulnerable component before a successful attack can be expected. For example, a successful attack may require an attacker to: gather knowledge about the environment in which the vulnerable target/component exists; prepare the target environment to improve exploit reliability; or inject themselves into the logical network path between the target and the resource requested by the victim in order to read and/or modify network communications (e.g., a man in the middle attack).", + PR_Heading: "This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.", + PR_N_Label: "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files to carry out an attack.", + PR_L_Label: "The attacker is authorized with (i.e., requires) privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges may have the ability to cause an impact only to non-sensitive resources.", + PR_H_Label: "The attacker is authorized with (i.e., requires) privileges that provide significant (e.g., administrative) control over the vulnerable component that could affect component-wide settings and files.", + UI_Heading: "This metric captures the requirement for a user, other than the attacker, to participate in the successful compromise the vulnerable component. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.", + UI_N_Label: "The vulnerable system can be exploited without any interaction from any user.", + UI_R_Label: "Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited.", + S_Heading: "Does a successful attack impact a component other than the vulnerable component? If so, the Base Score increases and the Confidentiality, Integrity and Authentication metrics should be scored relative to the impacted component.", + S_U_Label: "An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.", + S_C_Label: "An exploited vulnerability can affect resources beyond the security scope managed by the security authority of the vulnerable component. In this case, the vulnerable component and the impacted component are different and managed by different security authorities.", + C_Heading: "This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + C_N_Label: "There is no loss of confidentiality within the impacted component.", + C_L_Label: "There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the impacted component.", + C_H_Label: "There is total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact.", + I_Heading: "This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.", + I_N_Label: "There is no loss of integrity within the impacted component.", + I_L_Label: "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact on the impacted component.", + I_H_Label: "There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.", + A_Heading: "This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. It refers to the loss of availability of the impacted component itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of an impacted component.", + A_N_Label: "There is no impact to availability within the impacted component.", + A_L_Label: "Performance is reduced or there are interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the impacted component are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the impacted component.", + A_H_Label: "There is total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).", + temporalMetricGroup_Legend: "The Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence that one has in the description of a vulnerability.", + E_Heading: "This metric measures the likelihood of the vulnerability being attacked, and is typically based on the current state of exploit techniques, exploit code availability, or active, 'in-the-wild' exploitation.", + E_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning High.", + E_U_Label: "No exploit code is available, or an exploit is theoretical.", + E_P_Label: "Proof-of-concept exploit code is available, or an attack demonstration is not practical for most systems. The code or technique is not functional in all situations and may require substantial modification by a skilled attacker.", + E_F_Label: "Functional exploit code is available. The code works in most situations where the vulnerability exists.", + E_H_Label: "Functional autonomous code exists, or no exploit is required (manual trigger) and details are widely available. Exploit code works in every situation, or is actively being delivered via an autonomous agent (such as a worm or virus). Network-connected systems are likely to encounter scanning or exploitation attempts. Exploit development has reached the level of reliable, widely-available, easy-to-use automated tools.", + RL_Heading: "The Remediation Level of a vulnerability is an important factor for prioritization. The typical vulnerability is unpatched when initially published. Workarounds or hotfixes may offer interim remediation until an official patch or upgrade is issued. Each of these respective stages adjusts the temporal score downwards, reflecting the decreasing urgency as remediation becomes final.", + RL_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning Unavailable.", + RL_O_Label: "A complete vendor solution is available. Either the vendor has issued an official patch, or an upgrade is available.", + RL_T_Label: "There is an official but temporary fix available. This includes instances where the vendor issues a temporary hotfix, tool, or workaround.", + RL_W_Label: "There is an unofficial, non-vendor solution available. In some cases, users of the affected technology will create a patch of their own or provide steps to work around or otherwise mitigate the vulnerability.", + RL_U_Label: "There is either no solution available or it is impossible to apply.", + RC_Heading: "This metric measures the degree of confidence in the existence of the vulnerability and the credibility of the known technical details. Sometimes only the existence of vulnerabilities are publicized, but without specific details. For example, an impact may be recognized as undesirable, but the root cause may not be known. The vulnerability may later be corroborated by research which suggests where the vulnerability may lie, though the research may not be certain. Finally, a vulnerability may be confirmed through acknowledgement by the author or vendor of the affected technology. The urgency of a vulnerability is higher when a vulnerability is known to exist with certainty. This metric also suggests the level of technical knowledge available to would-be attackers.", + RC_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Temporal Score, i.e., it has the same effect on scoring as assigning Confirmed.", + RC_U_Label: "There are reports of impacts that indicate a vulnerability is present. The reports indicate that the cause of the vulnerability is unknown, or reports may differ on the cause or impacts of the vulnerability. Reporters are uncertain of the true nature of the vulnerability, and there is little confidence in the validity of the reports or whether a static Base score can be applied given the differences described. An example is a bug report which notes that an intermittent but non-reproducible crash occurs, with evidence of memory corruption suggesting that denial of service, or possible more serious impacts, may result.", + RC_R_Label: "Significant details are published, but researchers either do not have full confidence in the root cause, or do not have access to source code to fully confirm all of the interactions that may lead to the result. Reasonable confidence exists, however, that the bug is reproducible and at least one impact is able to be verified (Proof-of-concept exploits may provide this). An example is a detailed write-up of research into a vulnerability with an explanation (possibly obfuscated or 'left as an exercise to the reader') that gives assurances on how to reproduce the results.", + RC_C_Label: "Detailed reports exist, or functional reproduction is possible (functional exploits may provide this). Source code is available to independently verify the assertions of the research, or the author or vendor of the affected code has confirmed the presence of the vulnerability.", + environmentalMetricGroup_Legend: "These metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of complementary/alternative security controls in place, Confidentiality, Integrity, and Availability. The metrics are the modified equivalent of base metrics and are assigned metric values based on the component placement in organization infrastructure.", + CR_Heading: "These metrics enable the analyst to customize the CVSS score depending on the importance of the Confidentiality of the affected IT asset to a user’s organization, relative to other impacts. This metric modifies the environmental score by reweighting the Modified Confidentiality impact metric versus the other modified impacts.", + CR_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score, i.e., it has the same effect on scoring as assigning Medium.", + CR_L_Label: "Loss of Confidentiality is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + CR_M_Label: "Assigning this value to the metric will not influence the score.", + CR_H_Label: "Loss of Confidentiality is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + IR_Heading: "These metrics enable the analyst to customize the CVSS score depending on the importance of the Integrity of the affected IT asset to a user’s organization, relative to other impacts. This metric modifies the environmental score by reweighting the Modified Integrity impact metric versus the other modified impacts.", + IR_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score, i.e., it has the same effect on scoring as assigning Medium.", + IR_L_Label: "Loss of Integrity is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + IR_M_Label: "Assigning this value to the metric will not influence the score.", + IR_H_Label: "Loss of Integrity is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + AR_Heading: "These metrics enable the analyst to customize the CVSS score depending on the importance of the Availability of the affected IT asset to a user’s organization, relative to other impacts. This metric modifies the environmental score by reweighting the Modified Availability impact metric versus the other modified impacts.", + AR_X_Label: "Assigning this value indicates there is insufficient information to choose one of the other values, and has no impact on the overall Environmental Score, i.e., it has the same effect on scoring as assigning Medium.", + AR_L_Label: "Loss of Availability is likely to have only a limited adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + AR_M_Label: "Assigning this value to the metric will not influence the score.", + AR_H_Label: "Loss of Availability is likely to have a catastrophic adverse effect on the organization or individuals associated with the organization (e.g., employees, customers).", + MAV_Heading: "This metric reflects the context by which vulnerability exploitation is possible. The Environmental Score increases the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable component.", + MAV_X_Label: "The value assigned to the corresponding Base metric is used.", + MAV_N_Label: "The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed, up to and including the entire Internet. Such a vulnerability is often termed 'remotely exploitable' and can be thought of as an attack being exploitable at the protocol level one or more network hops away.", + MAV_A_Label: "The vulnerable component is bound to the network stack, but the attack is limited at the protocol level to a logically adjacent topology. This can mean an attack must be launched from the same shared physical (e.g., Bluetooth or IEEE 802.11) or logical (e.g., local IP subnet) network, or from within a secure or otherwise limited administrative domain (e.g., MPLS, secure VPN).", + MAV_L_Label: "The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities. Either: the attacker exploits the vulnerability by accessing the target system locally (e.g., keyboard, console), or remotely (e.g., SSH); or the attacker relies on User Interaction by another person to perform actions required to exploit the vulnerability (e.g., tricking a legitimate user into opening a malicious document).", + MAV_P_Label: "The attack requires the attacker to physically touch or manipulate the vulnerable component. Physical interaction may be brief or persistent.", + MAC_Heading: "This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Such conditions may require the collection of more information about the target or computational exceptions. The assessment of this metric excludes any requirements for user interaction in order to exploit the vulnerability. If a specific configuration is required for an attack to succeed, the Base metrics should be scored assuming the vulnerable component is in that configuration.", + MAC_X_Label: "The value assigned to the corresponding Base metric is used.", + MAC_L_Label: "Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success against the vulnerable component.", + MAC_H_Label: "A successful attack depends on conditions beyond the attacker's control. That is, a successful attack cannot be accomplished at will, but requires the attacker to invest in some measurable amount of effort in preparation or execution against the vulnerable component before a successful attack can be expected. For example, a successful attack may require an attacker to: gather knowledge about the environment in which the vulnerable target/component exists; prepare the target environment to improve exploit reliability; or inject themselves into the logical network path between the target and the resource requested by the victim in order to read and/or modify network communications (e.g., a man in the middle attack).", + MPR_Heading: "This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.", + MPR_X_Label: "The value assigned to the corresponding Base metric is used.", + MPR_N_Label: "The attacker is unauthorized prior to attack, and therefore does not require any access to settings or files to carry out an attack.", + MPR_L_Label: "The attacker is authorized with (i.e., requires) privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges may have the ability to cause an impact only to non-sensitive resources.", + MPR_H_Label: "The attacker is authorized with (i.e., requires) privileges that provide significant (e.g., administrative) control over the vulnerable component that could affect component-wide settings and files.", + MUI_Heading: "This metric captures the requirement for a user, other than the attacker, to participate in the successful compromise the vulnerable component. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.", + MUI_X_Label: "The value assigned to the corresponding Base metric is used.", + MUI_N_Label: "The vulnerable system can be exploited without any interaction from any user.", + MUI_R_Label: "Successful exploitation of this vulnerability requires a user to take some action before the vulnerability can be exploited.", + MS_Heading: "Does a successful attack impact a component other than the vulnerable component? If so, the Base Score increases and the Confidentiality, Integrity and Authentication metrics should be scored relative to the impacted component.", + MS_X_Label: "The value assigned to the corresponding Base metric is used.", + MS_U_Label: "An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.", + MS_C_Label: "An exploited vulnerability can affect resources beyond the security scope managed by the security authority of the vulnerable component. In this case, the vulnerable component and the impacted component are different and managed by different security authorities.", + MC_Heading: "This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.", + MC_X_Label: "The value assigned to the corresponding Base metric is used.", + MC_N_Label: "There is no loss of confidentiality within the impacted component.", + MC_L_Label: "There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is limited. The information disclosure does not cause a direct, serious loss to the impacted component.", + MC_H_Label: "There is total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact.", + MI_Heading: "This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.", + MI_X_Label: "The value assigned to the corresponding Base metric is used.", + MI_N_Label: "There is no loss of integrity within the impacted component.", + MI_L_Label: "Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is limited. The data modification does not have a direct, serious impact on the impacted component.", + MI_H_Label: "There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.", + MA_Heading: "This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. It refers to the loss of availability of the impacted component itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of an impacted component.", + MA_X_Label: "The value assigned to the corresponding Base metric is used.", + MA_N_Label: "There is no impact to availability within the impacted component.", + MA_L_Label: "Performance is reduced or there are interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the impacted component are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the impacted component.", + MA_H_Label: "There is total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable)." + }, + + report_type: { + add_new: "Přidat nový typ analýzy", + edit: "Upravit typ analýzy", + add_btn: "Přidat", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit tento typ analýzy", + name: "Název", + description: "Popis", + section_title: "Section", + new_group: "Nová skupina atributů", + successful: "Nový typ analýzy byl přidán", + successful_edit: "Typ analýzy byl upraven", + removed_error: "Typ analýzy je používán a nemohl být smazán", + removed: "Typ analýzy byl smazán", + total_count: "Počet typů analýz: " + }, + + report_item: { + add_new: "Nová analýza", + edit: "Upravit analýzu", + read: "Report item preview", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit tuto analýzu", + title: "Název", + title_prefix: "Předpona názvu", + report_type: "Typ analýzy", + successful: "Analýza byla přidána", + successful_edit: "Analýza byla uložena", + removed: "Analýza byla smazána", + removed_error: "Analýza se používá a nelze ji smazat", + select: "Vybrat analýzy", + select_remote: "Vybrat novinky ze vzdálených instancí", + add: "Přidat", + attributes: "Atributy", + import_csv: "Importovat z CSV", + import_from_csv: "Importovat CVE/CPE z CSV", + delete_existing_codes: "Smazat stávající CVE/CPE kódy", + tooltip: { + sort_time: "Seřadit hodnoty od nejnovější", + sort_user: "Zobrazit vlastní hodnoty před ostatními", + cvss_detail: "Zobrazit definice CVSS kalkulačky", + enum_selector: "Zobrazit okno s hledáním hodnot", + delete_value: "Smazat hodnotu tohoto atributu", + add_value: "Přidat novou hodnotu k tomuto atributu", + } + }, + + product: { + add_new: "Nový typ publikace", + add_btn: "Přidat", + edit: "Upravit typ publikace", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit tento typ publikace", + title: "Nadpis", + name: "Název", + description: "Popis", + report_type: "Typ publikace", + successful: "Nový typ publikace byl úspěšně přidán", + successful_edit: "Typ publikace byl uložen", + removed: "Typ publikace byl úspěšně smazán", + removed_error: "Typ publikace je používán a nelze jej smazat", + preview: "Zobrazit náhled publikace", + publish: "Zveřejnit publikaci", + total_count: "Počet typů publikací: " + }, + + analyze: { + sort: "Seřadit podle", + from: "Od", + to: "Do", + add_new: "Přidat", + total_count: "Počet analýz: ", + tooltip: { + filter_completed: "Zobrazit/Skrýt hotové analýzy", + filter_incomplete: "Zobrazit/Skrýt nedokončené analýzy", + range: { + ALL: "Zobrazit všechny analýzy", + TODAY: "Zobrazit dnešní analýzy", + WEEK: "Zobrazit analýzy za poslední týden", + MONTH: "Zobrazit analýzy za poslední měsíc" + }, + sort: { + time: { + ascending: "Seřadit analýzy podle data vytvoření vzestupně", + descending: "Seřadit analýzy podle data vytvoření sestupně" + } + }, + toggle_selection: "Toggle analýzy selection mode", + delete_items: "Smazat analýzy", + publish_items: "Vytvořit z analýz report", + delete_item: "Smazat analýzu", + publish_item: "Vytvořit report z analýzy", + } + }, + + assess: { + source: "Zdroj", + comments: "Komentáře", + collected: "Indexováno", + published: "Publikováno", + author: "Autor", + add_news_item: "Přidat novinku", + select_news_item: "Vybrat novinku", + add: "Přidat", + aggregate_detail: "Detail sloučené novinky", + aggregate_info: "Info", + aggregate_title: "Název", + aggregate_description: "Popis", + attributes: "Atributy", + title: "Název", + description: "Popis", + download: "Stáhnout", + total_count: "Počet novinek: ", + selected_count: "Počet vybraných novinek: ", + tooltip: { + filter_read: "Zobrazit/Skrýt nepřečtené novinky", + filter_important: "Zobrazit/Skrýt důležité novinky", + filter_relevant: "Zobrazit/Skrýt relevantní novinky", + filter_in_analyze: "Zobrazit/Skrýt analyzované novinky", + range: { + ALL: "Zobrazit všechny novinky", + TODAY: "Zobrazit dnešní novinky", + WEEK: "Zobrazit novinky za minulý týden", + MONTH: "Zobrazit novinky za minulý měsíc" + }, + sort: { + time: { + ascending: "Seřadit novinky podle data indexace vzestupně", + descending: "Seřadit novinky podle data indexace sestupně" + }, + relevance: { + ascending: "Seřadit novinky podle relevance vzestupně", + descending: "Seřadit novinky podle relevance sestupně" + } + }, + highlight_wordlist: "Zvýraznit slova ze seznamů slov", + toggle_selection: "Mód výběru novinek", + group_items: "Sloučit novinky", + ungroup_items: "Rozdělit novinky", + analyze_items: "Vytvořit z novinek analýzu", + read_items: "Označit novinky jako přečtené", + important_items: "Označit novinky jako důležité", + like_items: "To se mi líbí", + dislike_items: "To se mi nelíbí", + delete_items: "Smazat novinky", + open_source: "Otevřít zdroj novinky v nové záložce", + ungroup_item: "Oddělit novinku ze skupiny", + analyze_item: "Vytvořit z novinky analýzu", + read_item: "Označit jako přečtené", + important_item: "Označit jako důležité", + like_item: "To se mi líbí", + dislike_item: "To se mi nelíbí", + delete_item: "Smazat novinku", + }, + shortcuts: { + enter_filter_mode: "Zapnut mód zkratek 'filtr'. Ukončete klávesou Escape.", + enter_view_mode: "Zapnut mód zkratek 'náhled'. Ukončete klávesou Escape.", + default_mode: "Mód zkratek 'původní'.", + aggregate_no_group: "Nelze otevřít neagregovanou novinku, funguje pouze se skupinou novinek.", + }, + }, + + publish: { + tooltip: { + range: { + ALL: "Zobrazit všechny reporty", + TODAY: "Zobrazit dnešní reporty", + WEEK: "Zobrazit reporty za minulý týden", + MONTH: "Zobrazit reporty za minulý měsíc" + }, + sort: { + time: { + ascending: "Seřadit reporty podle data vytvoření vzestupně", + descending: "Seřadit reporty podle data vytvoření sestupně" + } + }, + delete_item: "Smazat report", + } + }, + + toolbar_filter: { + search: "Hledání", + all: "Vše", + today: "Dnes", + this_week: "Tento týden", + this_month: "Tento měsíc", + custom_filter: "Vlastní filtrování" + }, + + settings: { + user_settings: "Nastavení uživatele", + tab_general: "Obecné", + tab_wordlists: "Seznamy slov", + tab_hotkeys: "Zkratky", + save: "Uložit", + close_item: "Zavřít", + collection_up: "Posunout nahoru", + collection_down: "Posunout dolů", + show_item: "Show", + read_item: "Označit jako přečtené", + important_item: "Označit jako důležité", + like_item: "Označit jako To se mi líbí", + unlike_item: "Označit jako To se mi nelíbí", + delete_item: "Smazat", + spellcheck: "Kontrolovat pravopis", + dark_theme: "Tmavý motiv", + press_key: "Stiskněte klávesu pro ", + cancel_press_key: "Zrušit", + selection: "Výběr", + group: "Seskupit", + ungroup: "Zrušit seskupení", + new_product: "Nový produkt", + aggregate_open: "Otevřít sloučenou novinku" + }, + + word_list: { + add_new: "Přidat nový seznam slov", + edit: "Upravit seznam slov", + add: "Přidat", + add_btn: "Přidat", + save: "Uložit", + cancel: "Zrušit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit tento seznam slov", + name: "Název", + description: "Popis", + link: "URL", + use_for_stop_words: "Použít jako seznam stopslov", + successful: "Nový seznam slov byl přidán", + successful_edit: "Seznam slov byl přidán byl upraven", + remove: "Seznam slov byl smazán", + removed_error: "Seznam slov se používá a nelze jej smazat", + value: "Hodnota", + new_word: "Nové slovo", + words: "Slova", + new_category: "Nová kategorie", + total_count: "Počet seznamů slov: ", + file_has_header: "Soubor má hlavičku", + import_from_csv: "Importovat z CSV", + load_csv_file: "Načíst CSV soubor", + download_from_link: "Stáhnout z URL", + import: "Importovat", + close: "Zavřít", + }, + + asset_group: { + add_new: "Přidat novou skupinu aktiv", + edit: "Upravit skupinu aktiv", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se vytvořit skupinu aktiv", + name: "Název", + description: "Popis", + notification_templates: "Šablony upozornění", + allowed_users: "Povolení uživatelé (Pokud není žádný vybrán, získávají povolení všichni)", + successful: "Nová skupina aktiv byla přidána", + successful_edit: "Skupina aktiv byla upravena", + removed: "Skupina aktiv byla smazána", + removed_error: "Skupina aktiv je používána a nelze ji smazat", + total_count: "Počet skupin aktiv: " + }, + + notification_template: { + add_new: "Přidat novou šablonu upozornění", + edit: "Upravit šablonu upozornění", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit šablonu upozornění", + name: "Název", + description: "Popis", + message_title: "Nadpis zprávy", + message_body: "Tělo zprávy", + new_recipient: "Nový příjemce", + email: "E-mailová adresa", + recipients: "Příjemci", + successful: "Nová šablona upozornění byla přidána", + successful_edit: "Šablona upozornění byla upravena", + removed: "Šablona upozornění byla smazána", + removed_error: "Šablona upozornění se používá a nelze ji smazat", + total_count: "Počet šablon upozornění: " + }, + + asset: { + add_new: "Přidat nové aktivum", + add_group_info: "Přidejte prosím skupinu aktiv", + edit: "Upravit aktivum", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit toto aktivum", + name: "Název", + serial: "Sériové číslo", + description: "Popis", + cpe: "CPE kód", + new_cpe: "Přidat CPE kód", + cpes: "CPE kódy", + value: "Hodnota", + successful: "Nové aktivum bylo přidáno", + successful_edit: "Aktivum bylo upraveno", + removed: "Aktivum bylo smazáno", + removed_error: "Aktivum se používá a nelze jej smazat", + total_count: "Počet aktiv: ", + vulnerabilities: "Zranitelnosti", + vulnerabilities_count: "Počet zranitelností: ", + no_vulnerabilities: "Bez zranitelností", + import_csv: "Importovat CSV", + import_from_csv: "Importovat CPE z CSV", + file_has_header: "Soubor má hlavičku", + load_csv_file: "Načíst CSV soubor", + import: "Importovat", + close: "Zavřít" + }, + + remote_access: { + add_new: "Přidat vzdálený přístup", + edit: "Upravit vzdálený přístup", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit vzdálený přístup", + name: "Název", + description: "Popis", + access_key: "Přístupový klíč", + enabled: "Enabled", + successful: "Nový vzdálený přístup byl přidán", + successful_edit: "Vzdálený přístup byl upraven", + removed: "Vzdálený přístup byl smazán", + removed_error: "Vzdálený přístup se používá a nelze jej smazat", + osint_sources: "Sdílené zdroje OSINT", + report_item_types: "Sdílené analýzy", + total_count: "Počet vzdálených přístupů: " + }, + + remote_node: { + add_new: "Přidat vzdálenou instanci", + edit: "Upravit vzdálenou instanci", + add: "Přidat", + cancel: "Zrušit", + save: "Uložit", + validation_error: "Prosím vyplňte všechna povinná pole", + error: "Nepodařilo se uložit tuto vzdálenou instanci", + name: "Name", + description: "Popis", + remote_url: "URL vzdálené instance", + event_url: "URL vzdáleného zdroje událostí", + access_key: "Přístupový klíč", + enabled: "Zapnuto", + connect: "Připojit ke vzdálené instanci", + connect_error: "Připojení ke vzdálené instanci selhalo. Použit nesprávný přístupový klíč nebo instance není v dostupná.", + connect_info: "Připojeno ke vzdálené instanci.", + sync_news_items: "Synchronizovat novinky", + sync_report_items: "Synchronizovat analýzy", + osint_source_group: "Synchronizovat do skupiny OSINT zdrojů", + successful: "Nová vzdálená instance byla přidána", + successful_edit: "Vzdálená instance byla upravena", + removed: "Vzdálená instance byla smazána", + removed_error: "Vzdálená instance se používá a nelze ji odstranit", + total_count: "Počet vzdálených instancí: " + }, + + drop_zone: { + default_message: "Přetáhněte soubory sem nebo kliknutím vyberte", + file_description: "Popis", + last_updated: "Naposledy upraveno", + save: "Uložit", + download: "Stáhnout", + delete: "Smazat", + cancel: "Zrušit", + attachment_load: "Načíst přílohu", + attachment_detail: "Detaily přílohy" + }, + + error: { + aggregate_in_use: "Některé vybrané novinky nebo sloučené novinky jsou již připojeny k analýze", + server_error: "Neznámá chyba serveru..." + } +}; + +export default messages_cs From bb645509c7bed9385e74c1cccd692b11b3be454d Mon Sep 17 00:00:00 2001 From: multiflexi Date: Sat, 10 Feb 2024 20:17:56 +0100 Subject: [PATCH 17/49] link deduplication in product --- src/presenters/presenters/base_presenter.py | 47 +++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/presenters/presenters/base_presenter.py b/src/presenters/presenters/base_presenter.py index bdba59444..6f2cbc90b 100644 --- a/src/presenters/presenters/base_presenter.py +++ b/src/presenters/presenters/base_presenter.py @@ -3,6 +3,7 @@ Returns: _description_ """ + from shared.schema.presenter import PresenterSchema from managers import log_manager import json @@ -169,6 +170,31 @@ def add_link_prefix(self, report, letter): return description, recommendations + def link_renumbering(self, text, report_links, product_links): + """Replace the numbers enclosed in brackets in the given text with the corresponding indices from product_links. + + Arguments: + text (str): The text in which the numbers enclosed in brackets will be replaced. + report_links (list): The list of report links. + product_links (list): The list of product links. + + Returns: + str: The updated text with the numbers enclosed in brackets replaced by the corresponding indices from product_links. + """ + pattern = r"\[(\d+)\]" + + # Create a mapping from old indices to new indices + mapping = {old_index + 1: product_links.index(item) + 1 for old_index, item in enumerate(report_links)} + log_manager.log_info(f"Mapping: {mapping}") + + # Use a regular expression to find all instances of numbers enclosed in brackets + def replace_match(match): + old_index = int(match.group(1)) + new_index = mapping.get(old_index, old_index) # Use the old index as a fallback + return f"[{new_index}]" + + return re.sub(pattern, replace_match, text) + def __init__(self, presenter_input): """Initialize the object. @@ -195,16 +221,29 @@ def __init__(self, presenter_input): for report in presenter_input.reports: self.report_items.append(BasePresenter.ReportItemObject(report, report_types, attribute_map)) + link_deduplication = True letter = "A" vul_report_count = 0 + product_links = [] + # If there are multiple vulnerability reports, we need to renumber the links for report in self.report_items: - if report.type == "Vulnerability Report": - report.attrs.description, report.attrs.recommendations = self.add_link_prefix(report, letter) - report.attrs.link_prefix = letter - letter = chr(ord(letter) + 1) + if report.type.startswith("Vulnerability Report"): + if link_deduplication: + if report.attrs.links: + for link in report.attrs.links: + if link not in product_links: + product_links.append(link) + report.attrs.description = self.link_renumbering(report.attrs.description, report.attrs.links, product_links) + report.attrs.recommendations = self.link_renumbering(report.attrs.recommendations, report.attrs.links, product_links) + else: + report.attrs.description, report.attrs.recommendations = self.add_link_prefix(report, letter) + report.attrs.link_prefix = letter + letter = chr(ord(letter) + 1) vul_report_count += 1 + # If there are vulnerability reports, set the max TLP and product links if vul_report_count > 0: self.product.max_tlp = self.get_max_tlp(self.report_items) + self.product.links = product_links def get_info(self): """Get info about the presenter. From b81c9a7ed8bf07556434f20186d7a1f1950112b2 Mon Sep 17 00:00:00 2001 From: Dominik Dancs Date: Fri, 16 Feb 2024 13:54:58 +0100 Subject: [PATCH 18/49] Docker build readme fix --- docker/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/README.md b/docker/README.md index f03ff8add..e81b2b414 100644 --- a/docker/README.md +++ b/docker/README.md @@ -79,11 +79,13 @@ docker compose -f docker/docker-compose.yml up --no-build or, alternatively, build and run the containers with: ```bash -TARANIS_NG_TAG=build docker-compose -f docker/docker-compose.yml up --build --pull +TARANIS_NG_TAG=build docker-compose -f docker/docker-compose.yml build --pull +TARANIS_NG_TAG=build docker-compose -f docker/docker-compose.yml up ``` or ```bash -TARANIS_NG_TAG=build docker compose -f docker/docker-compose.yml up --build --pull +TARANIS_NG_TAG=build docker compose -f docker/docker-compose.yml build --pull +TARANIS_NG_TAG=build docker compose -f docker/docker-compose.yml up ``` (`--pull` updates the base images) From 1ccd64cb09aa0a76cdfe1bcece085b0a2548dc59 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Wed, 21 Feb 2024 21:54:05 +0100 Subject: [PATCH 19/49] removed unused code, fixed bugs --- src/presenters/presenters/base_presenter.py | 43 +++++---------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/src/presenters/presenters/base_presenter.py b/src/presenters/presenters/base_presenter.py index 6f2cbc90b..f1d39bfec 100644 --- a/src/presenters/presenters/base_presenter.py +++ b/src/presenters/presenters/base_presenter.py @@ -144,32 +144,15 @@ def get_max_tlp(self, reports): """ color_values = {"WHITE": 0, "CLEAR": 1, "GREEN": 2, "AMBER": 3, "AMBER+STRICT": 4, "RED": 5} colors = [] - for report in reports: - if report.type == "Vulnerability Report": + if report.type.startswith("Vulnerability Report"): colors.append(report.attrs.tlp) - - max_tlp = max(colors, key=lambda color: color_values.get(color, 0)) - if not max_tlp: + if colors: + max_tlp = max(colors, key=lambda color: color_values.get(color, 1)) + else: max_tlp = "CLEAR" return max_tlp - def add_link_prefix(self, report, letter): - """Add link prefix to the report description and recommendations. - - Arguments: - report -- report to add link prefix to - letter -- letter to use as a link prefix - - Returns: - description, recommendations: report description and recommendations with link prefix added - """ - pattern = r"\[(\d+)\]" - description = re.sub(pattern, lambda match: f"[{letter}{match.group(1)}]", report.attrs.description) - recommendations = re.sub(pattern, lambda match: f"[{letter}{match.group(1)}]", report.attrs.recommendations) - - return description, recommendations - def link_renumbering(self, text, report_links, product_links): """Replace the numbers enclosed in brackets in the given text with the corresponding indices from product_links. @@ -185,7 +168,6 @@ def link_renumbering(self, text, report_links, product_links): # Create a mapping from old indices to new indices mapping = {old_index + 1: product_links.index(item) + 1 for old_index, item in enumerate(report_links)} - log_manager.log_info(f"Mapping: {mapping}") # Use a regular expression to find all instances of numbers enclosed in brackets def replace_match(match): @@ -221,25 +203,18 @@ def __init__(self, presenter_input): for report in presenter_input.reports: self.report_items.append(BasePresenter.ReportItemObject(report, report_types, attribute_map)) - link_deduplication = True - letter = "A" vul_report_count = 0 product_links = [] # If there are multiple vulnerability reports, we need to renumber the links for report in self.report_items: if report.type.startswith("Vulnerability Report"): - if link_deduplication: - if report.attrs.links: - for link in report.attrs.links: - if link not in product_links: - product_links.append(link) + vul_report_count += 1 + if report.attrs.links: + for link in report.attrs.links: + if link not in product_links: + product_links.append(link) report.attrs.description = self.link_renumbering(report.attrs.description, report.attrs.links, product_links) report.attrs.recommendations = self.link_renumbering(report.attrs.recommendations, report.attrs.links, product_links) - else: - report.attrs.description, report.attrs.recommendations = self.add_link_prefix(report, letter) - report.attrs.link_prefix = letter - letter = chr(ord(letter) + 1) - vul_report_count += 1 # If there are vulnerability reports, set the max TLP and product links if vul_report_count > 0: self.product.max_tlp = self.get_max_tlp(self.report_items) From 13fcc3b80dd65bbe6a2fa830d3aac52f89119d19 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Tue, 27 Feb 2024 14:46:05 +0100 Subject: [PATCH 20/49] Add logging messages --- src/publishers/publishers/email_publisher.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/publishers/publishers/email_publisher.py b/src/publishers/publishers/email_publisher.py index 9b0e03f18..282c449f1 100644 --- a/src/publishers/publishers/email_publisher.py +++ b/src/publishers/publishers/email_publisher.py @@ -114,7 +114,12 @@ def publish(self, publisher_input): envelope.encryption(key=open(encrypt)) try: - envelope.send() + sent = envelope.send() + success = bool(sent) + if success: + log_manager.log_info("Email sent successfully") + else: + log_manager.log_critical("Email sending failed") except Exception as error: BasePublisher.print_exception(self, error) From 049d020f1e1c68ffc5b9aea38f2be6125011da1d Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Wed, 28 Feb 2024 15:07:53 +0100 Subject: [PATCH 21/49] Fixed bug in chrome driver: unrecognized proxy type: MANUAL --- src/collectors/collectors/web_collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collectors/collectors/web_collector.py b/src/collectors/collectors/web_collector.py index d162ae2ab..8e2fa2b0b 100644 --- a/src/collectors/collectors/web_collector.py +++ b/src/collectors/collectors/web_collector.py @@ -378,7 +378,7 @@ def __get_headless_driver_chrome(self): chrome_options.add_argument('--proxy-server={}'.format(socks_proxy)) elif self.proxy: webdriver.DesiredCapabilities.CHROME['proxy'] = { - "proxyType": "MANUAL", + "proxyType": "manual", "httpProxy": self.proxy, "ftpProxy": self.proxy, "sslProxy": self.proxy From 74a61776c505e078e9b204611c38a9b80ee70625 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Thu, 29 Feb 2024 14:44:01 +0100 Subject: [PATCH 22/49] improve SMTP communication --- src/publishers/publishers/email_publisher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/publishers/publishers/email_publisher.py b/src/publishers/publishers/email_publisher.py index 282c449f1..6f1487c38 100644 --- a/src/publishers/publishers/email_publisher.py +++ b/src/publishers/publishers/email_publisher.py @@ -99,7 +99,6 @@ def publish(self, publisher_input): envelope.subject(subject) envelope.from_(sender) envelope.to(recipients) - envelope.smtp(smtp) if sign == "auto": envelope.signature(key=sign) @@ -113,11 +112,13 @@ def publish(self, publisher_input): log_manager.log_info(f"Encrypting email with file {encrypt}") envelope.encryption(key=open(encrypt)) + envelope.smtp(smtp) try: sent = envelope.send() success = bool(sent) if success: log_manager.log_info("Email sent successfully") + Envelope.smtp_quit() else: log_manager.log_critical("Email sending failed") From f28ec6145b513f2379b7a4c58bf707aa3204fe2c Mon Sep 17 00:00:00 2001 From: multiflexi Date: Thu, 29 Feb 2024 17:52:05 +0100 Subject: [PATCH 23/49] publishers Python libraries and Alpine image update --- docker/Dockerfile.publishers | 4 ++-- src/publishers/requirements.txt | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docker/Dockerfile.publishers b/docker/Dockerfile.publishers index c4f50e78c..ac81fd0e3 100644 --- a/docker/Dockerfile.publishers +++ b/docker/Dockerfile.publishers @@ -1,4 +1,4 @@ -FROM python:3.12-alpine3.18 AS build_shared +FROM python:3.12-alpine3.19 AS build_shared WORKDIR /build_shared/ @@ -8,7 +8,7 @@ RUN python -m build -FROM python:3.12-alpine3.18 AS production +FROM python:3.12-alpine3.19 AS production WORKDIR /app/ diff --git a/src/publishers/requirements.txt b/src/publishers/requirements.txt index a2b70805e..ef5db4b1b 100644 --- a/src/publishers/requirements.txt +++ b/src/publishers/requirements.txt @@ -1,15 +1,15 @@ -envelope==2.0.2 -Flask==3.0.0 +envelope==2.0.3 +Flask==3.0.2 Flask-Cors==4.0.0 Flask-RESTful==0.3.10 -gevent==23.9.1 +gevent==24.2.1 gunicorn==21.2.0 -marshmallow==3.20.1 +marshmallow==3.21.0 marshmallow-enum==1.5.1 oauth2client==4.1.3 -paramiko==3.3.1 -python-dotenv==1.0.0 +paramiko==3.4.0 +python-dotenv==1.0.1 requests==2.31.0 tweepy==4.14.0 -urllib3==2.0.6 -pymisp==2.4.128 +urllib3==2.2.1 +pymisp==2.4.186 From 4ede6a8a20bbeb7d1d90f31c3dd8323f742253c5 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Thu, 29 Feb 2024 18:10:55 +0100 Subject: [PATCH 24/49] presenters Python libraries and Alpine image update --- docker/Dockerfile.presenters | 4 ++-- src/presenters/requirements.txt | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker/Dockerfile.presenters b/docker/Dockerfile.presenters index 27737392e..bf6ce8a12 100644 --- a/docker/Dockerfile.presenters +++ b/docker/Dockerfile.presenters @@ -1,4 +1,4 @@ -FROM python:3.12-alpine3.18 AS build_shared +FROM python:3.12-alpine3.19 AS build_shared WORKDIR /build_shared/ @@ -8,7 +8,7 @@ RUN python -m build -FROM python:3.12-alpine3.18 AS production +FROM python:3.12-alpine3.19 AS production WORKDIR /app/ diff --git a/src/presenters/requirements.txt b/src/presenters/requirements.txt index bebd77dd8..dd996d5c9 100644 --- a/src/presenters/requirements.txt +++ b/src/presenters/requirements.txt @@ -1,10 +1,10 @@ -Flask==3.0.0 +Flask==3.0.2 Flask-Cors==4.0.0 Flask-RESTful==0.3.10 -gevent==23.9.1 +gevent==24.2.1 gunicorn==21.2.0 -Jinja2==3.1.2 -marshmallow==3.20.1 +Jinja2==3.1.3 +marshmallow==3.21.0 marshmallow-enum==1.5.1 -python-dotenv==1.0.0 -weasyprint==60.1 +python-dotenv==1.0.1 +weasyprint==61.1 From d92b09ad25d746bbd9a45b23602153b7d87d59dd Mon Sep 17 00:00:00 2001 From: multiflexi Date: Thu, 29 Feb 2024 18:26:59 +0100 Subject: [PATCH 25/49] presenters Python libraries and Alpine image update --- docker/Dockerfile.collectors | 4 ++-- src/collectors/requirements.txt | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docker/Dockerfile.collectors b/docker/Dockerfile.collectors index edc46df14..5b79ca12b 100644 --- a/docker/Dockerfile.collectors +++ b/docker/Dockerfile.collectors @@ -1,4 +1,4 @@ -FROM python:3.12-alpine3.18 AS build_shared +FROM python:3.12-alpine3.19 AS build_shared WORKDIR /build_shared/ @@ -8,7 +8,7 @@ RUN python -m build -FROM python:3.12-alpine3.18 AS production +FROM python:3.12-alpine3.19 AS production WORKDIR /app/ diff --git a/src/collectors/requirements.txt b/src/collectors/requirements.txt index d7b1d1d38..912bba00b 100644 --- a/src/collectors/requirements.txt +++ b/src/collectors/requirements.txt @@ -1,19 +1,19 @@ -beautifulsoup4==4.12.2 +beautifulsoup4==4.12.3 bleach==6.1.0 dateparser==1.2.0 -feedparser==6.0.10 -Flask==3.0.0 +feedparser==6.0.11 +Flask==3.0.2 Flask-Cors==4.0.0 Flask-RESTful==0.3.10 -gevent==23.9.1 +gevent==24.2.1 gunicorn==21.2.0 -marshmallow==3.20.1 +marshmallow==3.21.0 marshmallow-enum==1.5.1 PySocks==1.7.1 python-dateutil==2.8.2 -python-dotenv==1.0.0 +python-dotenv==1.0.1 requests==2.31.0 schedule==1.2.1 -selenium==4.15.2 +selenium==4.18.1 slackclient==1.3.2 tweepy==4.14.0 From 5f5d21c79288559ea2d34265a37bd0b11692b560 Mon Sep 17 00:00:00 2001 From: multiflexi Date: Thu, 29 Feb 2024 18:36:00 +0100 Subject: [PATCH 26/49] bots Python libraries and Alpine image update --- docker/Dockerfile.bots | 4 ++-- src/bots/requirements.txt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docker/Dockerfile.bots b/docker/Dockerfile.bots index a989a105c..010f8f114 100644 --- a/docker/Dockerfile.bots +++ b/docker/Dockerfile.bots @@ -1,4 +1,4 @@ -FROM python:3.12-alpine3.18 AS build_shared +FROM python:3.12-alpine3.19 AS build_shared WORKDIR /build_shared/ @@ -8,7 +8,7 @@ RUN python -m build -FROM python:3.12-alpine3.18 AS production +FROM python:3.12-alpine3.19 AS production WORKDIR /app/ diff --git a/src/bots/requirements.txt b/src/bots/requirements.txt index bc21d0327..ecff522c9 100644 --- a/src/bots/requirements.txt +++ b/src/bots/requirements.txt @@ -1,13 +1,13 @@ -Flask==3.0.0 +Flask==3.0.2 Flask-Cors==4.0.0 Flask-RESTful==0.3.10 -gevent==23.9.1 +gevent==24.2.1 gunicorn==21.2.0 -marshmallow==3.20.1 +marshmallow==3.21.0 marshmallow-enum==1.5.1 oauthlib==3.2.2 PySocks==1.7.1 -python-dotenv==1.0.0 +python-dotenv==1.0.1 requests==2.31.0 schedule==1.2.1 sseclient-py==1.8.0 From 388878127235044359312503a1419425fb89b78d Mon Sep 17 00:00:00 2001 From: Jan Polonsky Date: Sat, 2 Mar 2024 11:52:31 +0100 Subject: [PATCH 27/49] - Dark theme fix: report item attributes were unreadable (bad background hover color) - Dark theme fix: white text on white background + unified richtextbox components - Dark theme fix: initial help text in richtextbox was unreadable (bad color) - Dark theme fix: fixed white color on tollbars - Dark theme fix: keyboard shorcuts - Unified richtextbox toolbars (same order of tools) - Deduplicate styles in centralize.css --- src/gui/src/assets/centralize.css | 545 ++---------------- src/gui/src/assets/common.css | 6 +- src/gui/src/components/UserSettings.vue | 5 +- .../assess/NewsItemAggregateDetail.vue | 27 +- .../assess/NewsItemSingleDetail.vue | 335 ++++++----- src/gui/src/components/assets/CPETable.vue | 2 +- src/gui/src/components/assets/CardAsset.vue | 2 +- src/gui/src/components/assets/NewAsset.vue | 2 +- .../src/components/common/CalculatorCVSS.vue | 2 +- .../src/components/common/EnumSelector.vue | 10 +- .../common/attribute/AttributeCVSS.vue | 2 +- .../config/assets/NewAssetGroup.vue | 4 +- .../config/assets/NewNotificationTemplate.vue | 30 +- .../config/assets/RecipientTable.vue | 2 +- .../config/attributes/NewAttribute.vue | 2 +- .../config/osint_sources/NewOSINTSource.vue | 4 +- .../osint_sources/NewOSINTSourceGroup.vue | 2 +- .../config/remote/NewRemoteAccess.vue | 72 +-- .../config/report_types/AttributeTable.vue | 2 +- src/gui/src/components/config/user/NewACL.vue | 4 +- .../config/user/NewExternalUser.vue | 2 +- .../src/components/config/user/NewRole.vue | 2 +- .../src/components/config/user/NewUser.vue | 6 +- .../config/word_lists/WordTable.vue | 2 +- src/gui/src/main.js | 3 - src/gui/src/views/users/EnterView.vue | 29 +- 26 files changed, 294 insertions(+), 810 deletions(-) diff --git a/src/gui/src/assets/centralize.css b/src/gui/src/assets/centralize.css index df17870ba..56c37ab26 100644 --- a/src/gui/src/assets/centralize.css +++ b/src/gui/src/assets/centralize.css @@ -1,12 +1,5 @@ /* Temporary CSS - WiP - Don't modify */ - -/*div.content-container > div.container { !* add button *! - position: relative; - !*bottom: 40px; - width: 82px; - right: 0;*! - z-index: 100; -}*/ +/* JP: deduplicated */ /* Fullscreen Dialog */ div.v-dialog__content header { @@ -21,24 +14,13 @@ div.v-dialog__content header { z-index: 1; } -/* NEW */ /* App Bar */ .app-header { - /*background-color: #c7c7c7 !important; - border-bottom: 1px solid red !important;*/ box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.02), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12); } -/*.app-header img { - height: 45px; -}*/ - -/*.container { - max-width: calc(100%) !important; -}*/ - #app .user-settings-dialog .v-tabs .v-window.v-tabs-items { background-color: transparent !important; } @@ -80,7 +62,6 @@ div.v-data-table > header { } /* --- Login.vue --- */ -/* Login Screen */ .login-screen { background-color: #eee; } @@ -145,11 +126,13 @@ div.v-data-table > header { } /* --- AnalyzeView.vue --- */ +/* --- MyAssetsView.vue --- */ .np { display: none; } /* --- AssessView.vue --- */ +/* --- EnterView.vue --- */ .nri { display: none; } @@ -175,21 +158,13 @@ div.v-data-table > header { right: 12px; } -/* --- EnterView.vue --- */ -.nri { - display: none; -} - +/* --- DashboardView.vue --- */ +/* --- ToolbarFilterAssets.vue --- */ .v-chip-group .v-chip.filter { height: 20px; margin-top: 5px; } -/* --- MyAssetsView.vue --- */ -.np { - display: none; -} - /* --- MainMenu.vue --- */ .app-header .v-toolbar__content { padding-right: 0; @@ -227,7 +202,6 @@ header.app-header.border.dark { .user-menu-button { margin-right: 0; margin-left: 0; - /*height: 46px !important;*/ } .user-menu .v-badge__badge { @@ -257,13 +231,13 @@ header.app-header.border.dark { right:0; } -/* --- CardAnalyze.vue --- */ - /* --- ContentDataAnalyze.vue --- */ +/* --- ContentDataPublish.vue --- */ html { scroll-behavior: smooth; } +/* --- ContentDataAnalyze.vue --- */ #selector_analyze .card-assess { transition: background-color 1s; } @@ -284,16 +258,27 @@ html { } /* --- NewReportItem.vue --- */ +/* --- RemoteReportItem.vue --- */ +/* --- VulnerabilityDetail.vue --- */ +/* --- NewRole.vue --- */ +/* --- NewOSINTSourceGroup.vue --- */ +/* --- NewRemoteAccess.vue --- */ +/* --- NewRemoteNode.vue --- */ +/* --- NewACL.vue --- */ +/* --- NewExternalUser.vue --- */ +/* --- NewProduct.vue --- */ .div-wrapper .theme--light.v-card { border-left: 5px solid rgb(255, 172, 33); } +/* --- NewUser.vue --- */ +.div-wrapper .theme--light.v-card { + border-left: 5px solid rgb(100, 172, 33); +} .tabs [role='tablist'] { background-color: #f5ebd5 !important; - } - .tabs .v-window-item { } @@ -324,6 +309,18 @@ html { color: white; } +/* --- CPETable.vue --- */ +/* --- NewAttribute.vue --- */ +/* --- WordTable.vue --- */ +.vue-csv-uploader button.load { + margin: 10px; + margin-left: 0; + padding: 4px 10px 4px 10px; + background-color: #4092dd; + border-radius: 4px; + color: white; +} + .vue-csv-uploader-part-two table { width: 400px; } @@ -345,15 +342,6 @@ html { } /* --- RemoteReportItem.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - .div-wrapper .v-card-title-dialog { background-color: rgba(207, 158, 37, 0.2); border-radius: 0; @@ -363,21 +351,6 @@ html { padding-left: 1em; } -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -.locked-style { - border-color: lightblue !important; - border-width: 1px; - border-style: dashed; -} - -/* --- RemoteRerpotItemSelector.vue --- */ - /* --- ToolbarGroupAnalyze.vue --- */ .view .view-panel button.multi-select-button-pressed { background-color: orange !important; @@ -401,11 +374,6 @@ html { text-decoration: none; } -/* --- CardAssessItem.vue --- */ -#selector .card.focus { - background-color: #caecff; -} - /* --- ContentDataAssess.vue --- */ html, .v-dialog--active .cs-inside { @@ -432,30 +400,7 @@ html, } /* --- NewsItemAggregateDetail.vue --- */ -[role='tablist'] { - top: 48px; -} - -.title-limit { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 550px; - font-size: 1em; -} - /* --- NewsItemDetail.vue --- */ -[role='tablist'] { - top: 48px; -} -.title-limit { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 550px; - font-size: 1em; -} - /* --- NewsItemSingleDetail.vue --- */ [role='tablist'] { top: 48px; @@ -469,36 +414,6 @@ html, font-size: 1em; } -/* --- CardAsset.vue --- */ - - -/* --- CardVulnerability.vue --- */ - -/* --- CPETable.vue --- */ -.vue-csv-uploader button.load { - margin: 10px; - margin-left: 0; - padding: 4px 10px 4px 10px; - background-color: #4092dd; - border-radius: 4px; - color: white; -} - -.vue-csv-uploader-part-two table { - width: 400px; -} - -.vue-csv-uploader-part-two table thead { - text-align: left; -} - -.vue-csv-uploader-part-two table select { - -webkit-appearance: auto; - -moz-appearance: auto; - border: 1px solid gray; - border-radius: 4px; -} - /* --- NewAsset.vue --- */ .cx-toolbar-filter { @@ -507,42 +422,6 @@ html, z-index: 100; } -#selector .card.focus { - background-color: #caecff; -} - -/* --- ToolbarFilterAssets.vue --- */ -.v-chip-group .v-chip.filter { - height: 20px; - margin-top: 5px; -} - -/* --- VulnerabilityDetail.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - /* --- DataInput.vue --- */ .v-toolbar .v-input { padding-top: 12px; @@ -550,14 +429,11 @@ html, } /* --- CSButton.vue --- */ -.v-tooltip__content.hide-tooltip { - display: none !important; -} - /* --- CalculatorCVSS.vue --- */ .v-tooltip__content.hide-tooltip { display: none !important; } + .v-card.bsm { border-left: 4px solid #ddd; transition: border-left-color 250ms; @@ -594,6 +470,7 @@ html, .bsm.critical { border-left-color: red !important; } span.cs_metric_score { + color: black; background-color: rgba(255,255,255,1) !important; border-radius: 4px; } @@ -629,7 +506,6 @@ tbody tr { nav .v-list-item__title { text-align: center; white-space: unset; - /*font-size: 1vh;*/ } .navigation .navigation-list div.v-list-item:not(.section-icon) { @@ -646,13 +522,10 @@ nav .v-list-item__title { .chatEnv { position: relative; - z-index: 20; } .chatButton { - /*position: relative; - left: 0.5em;*/ } .taranis-chat .quick-chat-container { @@ -662,6 +535,7 @@ nav .v-list-item__title { } /* --- AttributeAttachment.vue --- */ +/* --- RemoteAttributeAttachment.vue --- */ #dropzone { width: 100%; height: 64px; @@ -683,7 +557,6 @@ nav .v-list-item__title { } [cs] .dz-details { - } [cs] [data-dz-size] { @@ -713,12 +586,8 @@ nav .v-list-item__title { margin-top: 8px; } -/* --- AttributeCVE.vue --- */ -.v-tooltip__content.hide-tooltip { - display: none !important; -} - /* --- AttributeContainer.vue --- */ +/* --- RemoteAttributeContainer.vue --- scoped */ .div-wrapper .theme--light.v-card { border-left: 0; margin-top: 4px; @@ -772,309 +641,6 @@ button.ql-publish:hover { content: "Publish"; } -/* --- RemoteAttributeAttachment.vue --- */ -#dropzone { - width: 100%; - height: 64px; - background-color: #e4e4e4; - border: 1px solid #ccc; - border-radius: 6px; - overflow: hidden; -} - -[cs] { - position: relative; - float: left; - width: 68px; - margin: 4px 12px; -} - -[cs] > div { - text-align: center; -} - -[cs] .dz-details { - -} - -[cs] [data-dz-size] { - font-size: 10px; - font-weight: bold; -} - -[cs] .dz-filename { - width: 64px; - overflow: hidden; - white-space: pre-wrap; - text-overflow: ellipsis; - line-height: 1; -} - -[cs] [data-dz-name] { - font-size: 10px; -} - -#dropzone.dz-started .dz-message { - display: none; -} - -.dropzone-wrapper-div { - margin-left: 8px; - margin-right: 8px; - margin-top: 8px; -} - -/* --- RemoteAttributeContainer.vue --- scoped */ -.div-wrapper .theme--light.v-card { - border-left: 0; - margin-top: 4px; -} - -/* --- RemoteAttributeString.vue --- scoped */ - -/* --- CardCompact.vue --- */ - -/* --- CardNode.vue --- */ - -/* --- CardPreset.vue --- */ - -/* --- NewAttribute.vue --- */ -.vue-csv-uploader button.load { - margin: 10px; - margin-left: 0; - padding: 4px 10px 4px 10px; - background-color: #4092dd; - border-radius: 4px; - color: white; -} - -.vue-csv-uploader-part-two table { - width: 400px; -} - -.vue-csv-uploader-part-two table thead { - text-align: left; -} - -.vue-csv-uploader-part-two table select { - -webkit-appearance: auto; - -moz-appearance: auto; - border: 1px solid gray; - border-radius: 4px; -} - -/* --- CardGroup.vue --- */ - -/* --- NewRole.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- CardSource.vue --- */ - -/* --- NewOSINTSourceGroup.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- CardProductType.vue --- */ - -/* --- NewRemoteAccess.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- NewRemoteNode.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- CardUser.vue --- */ - -/* --- NewACL.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- NewExternalUser.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- NewUser.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- WordTable.vue --- */ -.vue-csv-uploader button.load { - margin: 10px; - margin-left: 0; - padding: 4px 10px 4px 10px; - background-color: #4092dd; - border-radius: 4px; - color: white; -} - -.vue-csv-uploader-part-two table { - width: 400px; -} - -.vue-csv-uploader-part-two table thead { - text-align: left; -} - -.vue-csv-uploader-part-two table select { - -webkit-appearance: auto; - -moz-appearance: auto; - border: 1px solid gray; - border-radius: 4px; -} - /* --- AttributeItemLayout.vue --- */ .attribute-item-layout .row { width: 100%; @@ -1101,6 +667,14 @@ button.ql-publish:hover { background-color: rgba(106, 190, 242, 0.06); } +#app.theme--dark .attribute-value-layout:hover { + background-color: #252931; +} + +#app.theme--dark .ql-editor.ql-blank::before { + color: rgba(255, 255, 255, 0.6); +} + .icon-tooltip { position: absolute; opacity: 0.7; @@ -1112,9 +686,6 @@ button.ql-publish:hover { } /* --- ContentDataPublish.vue --- */ -html { - scroll-behavior: smooth; -} #selector_publish .card-assess { transition: background-color 1s; } @@ -1130,31 +701,3 @@ html { box-shadow: inset 0 0 0 3px red; background-color: rgba(255, 0, 0, 0.3); } - -/* --- NewProduct.vue --- */ -.div-wrapper .theme--light.v-card { - border-left: 5px solid rgb(255, 172, 33); -} - -.tabs [role='tablist'] { - background-color: #f5ebd5 !important; - -} - -.div-wrapper .v-card-title-dialog { - background-color: rgba(207, 158, 37, 0.2); - border-radius: 0; - font-size: 1.2em; - font-weight: bold; - padding: 0; - padding-left: 1em; -} - -.tabs .v-window-item { -} - -.icon-field-offset { - margin-left: 8px; -} - -/* --- ReportItemSelector.vue --- */ \ No newline at end of file diff --git a/src/gui/src/assets/common.css b/src/gui/src/assets/common.css index 2619f3116..3262aae02 100644 --- a/src/gui/src/assets/common.css +++ b/src/gui/src/assets/common.css @@ -56,4 +56,8 @@ .valueHolder:hover { background-color: #f8f8f8; box-shadow: -3px 0 0 #6abef2; -} \ No newline at end of file +} + +#app.theme--dark .valueHolder:hover { + background-color: #252931; +} diff --git a/src/gui/src/components/UserSettings.vue b/src/gui/src/components/UserSettings.vue index 89e073ec4..8e4505ca0 100644 --- a/src/gui/src/components/UserSettings.vue +++ b/src/gui/src/components/UserSettings.vue @@ -60,7 +60,7 @@ > @@ -76,8 +76,7 @@ diff --git a/src/gui/src/components/assets/CPETable.vue b/src/gui/src/components/assets/CPETable.vue index 20e91929a..42e444b17 100644 --- a/src/gui/src/components/assets/CPETable.vue +++ b/src/gui/src/components/assets/CPETable.vue @@ -6,7 +6,7 @@ class="elevation-1" >