├── .docker ├── compose.yml └── prod.Dockerfile ├── .dockerignore ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── config.yml │ └── issue-report.md ├── dependabot.yml └── workflows │ ├── changelog.yml │ ├── ci-js.yml │ ├── codeql-analysis.yml │ ├── container.yml │ ├── conventional-commits.yml │ ├── dependency-review.yml │ ├── release.yml │ └── sbom-upload.yml ├── .gitignore ├── .prettierrc.cjs ├── LICENSE ├── README.md ├── cliff.toml ├── eslint-script ├── allowedSnakeCase.js └── no-dynamic-i18n.js ├── eslint.config.js ├── i18next-parser.config.js ├── index.html ├── jsconfig.json ├── package-lock.json ├── package.json ├── public ├── img │ ├── cpe │ │ ├── a:apache:http_server.svg │ │ ├── a:drupal:drupal.svg │ │ ├── a:gnu.svg │ │ ├── a:google.svg │ │ ├── a:mysql:mysql.svg │ │ ├── a:openbsd:openssh.svg │ │ ├── a:otrs:otrs.svg │ │ ├── a:php:php.svg │ │ ├── a:postgresql:postgresql.svg │ │ ├── a:snort:snort.svg │ │ ├── a:sourcefire.svg │ │ ├── a:typo3:typo3.svg │ │ ├── a:wordpress:wordpress.svg │ │ └── other.svg │ ├── favicon.png │ ├── greenbone.svg │ ├── greenbone_banner.jpeg │ ├── greenbone_banner.png │ ├── greenbonehorizontal.png │ ├── gsa.svg │ ├── gsa_splash.svg │ ├── loading.gif │ ├── login-bottom.svg │ ├── login-label.svg │ ├── login-top.svg │ ├── os_aix.svg │ ├── os_apple.svg │ ├── os_arubanetworks.svg │ ├── os_centos.svg │ ├── os_checkpoint.svg │ ├── os_cisco.svg │ ├── os_conflict.svg │ ├── os_cyclades.svg │ ├── os_debian.svg │ ├── os_fedora.svg │ ├── os_fortinet.svg │ ├── os_freebsd.svg │ ├── os_gentoo.svg │ ├── os_gos.svg │ ├── os_hp.svg │ ├── os_huawai.svg │ ├── os_ipfire.svg │ ├── os_junos.svg │ ├── os_linux.svg │ ├── os_mandriva.svg │ ├── os_mcafee.svg │ ├── os_netbsd.svg │ ├── os_netgear.svg │ ├── os_novell.svg │ ├── os_openbsd.svg │ ├── os_paloalto.svg │ ├── os_redhat.svg │ ├── os_ruggedcom.svg │ ├── os_slackware.svg │ ├── os_sourcefire.svg │ ├── os_sun.svg │ ├── os_suse.svg │ ├── os_synology.svg │ ├── os_trustix.svg │ ├── os_ubuntu.svg │ ├── os_ucs.svg │ ├── os_unknown.svg │ ├── os_vmware.svg │ └── os_windows.svg ├── locales │ ├── gsa-ar.json │ ├── gsa-de.json │ ├── gsa-en.json │ ├── gsa-fr.json │ ├── gsa-pt_BR.json │ ├── gsa-ru.json │ ├── gsa-tr.json │ ├── gsa-zh_CN.json │ └── gsa-zh_TW.json └── robots.txt ├── src ├── __tests__ │ └── version.test.ts ├── gmp │ ├── __tests__ │ │ ├── cancel.test.ts │ │ ├── gmp.test.ts │ │ ├── gmpsettings.test.ts │ │ ├── log.test.ts │ │ ├── model.test.ts │ │ ├── parser.test.ts │ │ └── timezones.test.ts │ ├── cancel.ts │ ├── capabilities │ │ ├── __tests__ │ │ │ ├── capabilities.test.ts │ │ │ └── everything.test.ts │ │ ├── capabilities.ts │ │ └── everything.ts │ ├── collection │ │ ├── CollectionCounts.ts │ │ ├── __tests__ │ │ │ └── parser.test.ts │ │ └── parser.ts │ ├── command.ts │ ├── commands │ │ ├── __tests__ │ │ │ ├── audit.test.js │ │ │ ├── auditreport.test.js │ │ │ ├── auditreports.test.js │ │ │ ├── auth.test.ts │ │ │ ├── convert.test.js │ │ │ ├── credentials.test.js │ │ │ ├── dashboards.test.js │ │ │ ├── entities.test.js │ │ │ ├── entity.test.js │ │ │ ├── feedstatus.test.js │ │ │ ├── http.test.js │ │ │ ├── license.test.js │ │ │ ├── nvt.test.js │ │ │ ├── nvtfamilies.test.js │ │ │ ├── performance.test.ts │ │ │ ├── policies.test.js │ │ │ ├── policy.test.js │ │ │ ├── portlist.test.ts │ │ │ ├── report.test.js │ │ │ ├── reportconfig.test.js │ │ │ ├── reportconfigs.test.js │ │ │ ├── reports.test.js │ │ │ ├── resourcenames.test.js │ │ │ ├── result.test.js │ │ │ ├── results.test.js │ │ │ ├── scanconfig.test.js │ │ │ ├── tag.test.js │ │ │ ├── target.test.js │ │ │ ├── tasks.test.js │ │ │ ├── ticket.test.js │ │ │ ├── tickets.test.js │ │ │ ├── tlscertificates.test.js │ │ │ └── user.test.ts │ │ ├── alerts.js │ │ ├── auditreports.js │ │ ├── audits.js │ │ ├── auth.ts │ │ ├── certbund.js │ │ ├── convert.js │ │ ├── cpes.js │ │ ├── credentials.js │ │ ├── cves.js │ │ ├── cvsscalculator.js │ │ ├── dashboards.js │ │ ├── dfncert.js │ │ ├── entities.ts │ │ ├── entity.ts │ │ ├── feedstatus.js │ │ ├── filters.js │ │ ├── gmp.js │ │ ├── gmp.ts │ │ ├── groups.js │ │ ├── hosts.js │ │ ├── http.ts │ │ ├── infoentities.js │ │ ├── infoentity.js │ │ ├── license.js │ │ ├── login.ts │ │ ├── notes.js │ │ ├── nvt.js │ │ ├── nvtfamilies.js │ │ ├── os.js │ │ ├── overrides.js │ │ ├── performance.ts │ │ ├── permissions.js │ │ ├── policies.js │ │ ├── portlists.ts │ │ ├── reportconfigs.js │ │ ├── reportformats.js │ │ ├── reports.js │ │ ├── resourcenames.js │ │ ├── results.js │ │ ├── roles.js │ │ ├── scanconfigs.js │ │ ├── scanners.js │ │ ├── schedules.js │ │ ├── tags.js │ │ ├── targets.js │ │ ├── tasks.js │ │ ├── testing.ts │ │ ├── tickets.js │ │ ├── tlscertificates.js │ │ ├── trashcan.js │ │ ├── users.ts │ │ ├── vulns.js │ │ └── wizard.js │ ├── gmp.ts │ ├── gmpsettings.ts │ ├── http │ │ ├── __tests__ │ │ │ ├── http.test.ts │ │ │ ├── rejection.test.ts │ │ │ ├── response.test.ts │ │ │ └── utils.test.ts │ │ ├── gmp.ts │ │ ├── http.ts │ │ ├── rejection.ts │ │ ├── response.ts │ │ ├── transform │ │ │ ├── __tests__ │ │ │ │ ├── fastxml.test.ts │ │ │ │ └── xml.test.ts │ │ │ ├── default.ts │ │ │ ├── fastxml.ts │ │ │ ├── transform.ts │ │ │ └── xml.ts │ │ └── utils.ts │ ├── index.ts │ ├── locale │ │ ├── __tests__ │ │ │ ├── date.test.ts │ │ │ ├── detector.test.ts │ │ │ ├── lang.test.ts │ │ │ └── languages.test.ts │ │ ├── date.ts │ │ ├── detector.ts │ │ ├── index.ts │ │ ├── lang.ts │ │ └── languages.ts │ ├── log.ts │ ├── model.ts │ ├── models │ │ ├── __tests__ │ │ │ ├── alert.test.js │ │ │ ├── asset.test.js │ │ │ ├── audit.test.js │ │ │ ├── certbund.test.js │ │ │ ├── cpe.test.js │ │ │ ├── credential.test.js │ │ │ ├── cve.test.js │ │ │ ├── dfncert.test.js │ │ │ ├── event.test.js │ │ │ ├── filter.test.ts │ │ │ ├── group.test.js │ │ │ ├── host.test.js │ │ │ ├── info.test.js │ │ │ ├── license.test.js │ │ │ ├── login.test.ts │ │ │ ├── note.test.js │ │ │ ├── nvt.test.js │ │ │ ├── os.test.js │ │ │ ├── override.test.js │ │ │ ├── permission.test.js │ │ │ ├── policy.test.js │ │ │ ├── portlist.test.ts │ │ │ ├── reportconfig.test.js │ │ │ ├── reportformat.test.js │ │ │ ├── resourcename.test.js │ │ │ ├── result.test.js │ │ │ ├── role.test.js │ │ │ ├── scanconfig.test.js │ │ │ ├── scanner.test.js │ │ │ ├── schedule.test.js │ │ │ ├── secinfo.test.js │ │ │ ├── setting.test.ts │ │ │ ├── settings.test.ts │ │ │ ├── tag.test.js │ │ │ ├── target.test.js │ │ │ ├── task.test.js │ │ │ ├── ticket.test.js │ │ │ ├── tlscertificate.test.js │ │ │ ├── user.test.ts │ │ │ └── vulnerability.test.js │ │ ├── actionresult.ts │ │ ├── alert.js │ │ ├── asset.js │ │ ├── audit.js │ │ ├── auditreport.js │ │ ├── certbund.js │ │ ├── cpe.js │ │ ├── credential.js │ │ ├── cve.js │ │ ├── date.ts │ │ ├── dfncert.js │ │ ├── event.js │ │ ├── filter.ts │ │ ├── filter │ │ │ ├── __tests__ │ │ │ │ ├── convert.test.ts │ │ │ │ ├── filterterm.test.ts │ │ │ │ └── utils.test.ts │ │ │ ├── convert.ts │ │ │ ├── filterterm.ts │ │ │ ├── keywords.ts │ │ │ └── utils.ts │ │ ├── group.js │ │ ├── host.js │ │ ├── info.js │ │ ├── license.js │ │ ├── login.ts │ │ ├── note.js │ │ ├── nvt.js │ │ ├── os.js │ │ ├── override.js │ │ ├── permission.js │ │ ├── policy.js │ │ ├── portlist.ts │ │ ├── report.js │ │ ├── report │ │ │ ├── __tests__ │ │ │ │ ├── app.test.js │ │ │ │ ├── cve.test.js │ │ │ │ ├── host.test.js │ │ │ │ ├── os.test.js │ │ │ │ ├── parser.test.js │ │ │ │ ├── port.test.js │ │ │ │ ├── task.test.js │ │ │ │ └── tlscertificate.test.js │ │ │ ├── app.js │ │ │ ├── auditreport.js │ │ │ ├── cve.js │ │ │ ├── host.js │ │ │ ├── os.js │ │ │ ├── parser.js │ │ │ ├── port.js │ │ │ ├── report.js │ │ │ ├── task.js │ │ │ └── tlscertificate.js │ │ ├── reportconfig.js │ │ ├── reportformat.js │ │ ├── resourcename.js │ │ ├── result.js │ │ ├── role.js │ │ ├── scanconfig.js │ │ ├── scanner.js │ │ ├── schedule.js │ │ ├── secinfo.js │ │ ├── setting.ts │ │ ├── settings.ts │ │ ├── tag.js │ │ ├── target.js │ │ ├── task.js │ │ ├── testing.js │ │ ├── ticket.js │ │ ├── tlscertificate.js │ │ ├── user.ts │ │ └── vulnerability.js │ ├── parser.ts │ ├── parser │ │ ├── __tests__ │ │ │ ├── cvss.test.ts │ │ │ └── cvssV4.test.ts │ │ ├── cvss.ts │ │ └── cvssV4.ts │ ├── setupTests.ts │ ├── timezones.ts │ └── utils │ │ ├── __tests__ │ │ ├── array.test.ts │ │ ├── entitytype.test.ts │ │ ├── event.test.ts │ │ ├── id.test.ts │ │ ├── identity.test.ts │ │ ├── number.test.ts │ │ ├── object.test.ts │ │ └── string.test.ts │ │ ├── array.ts │ │ ├── entitytype.ts │ │ ├── event.ts │ │ ├── id.ts │ │ ├── identity.ts │ │ ├── number.ts │ │ ├── object.ts │ │ ├── severity.ts │ │ ├── string.ts │ │ └── trace.ts ├── index.tsx ├── setupTests.ts ├── testing.ts ├── version.ts ├── vite-env.d.ts └── web │ ├── App.tsx │ ├── Authorized.jsx │ ├── Routes.jsx │ ├── components │ ├── badge │ │ ├── Badge.jsx │ │ └── __tests__ │ │ │ └── Badge.test.jsx │ ├── bar │ │ ├── ComplianceBar.jsx │ │ ├── ComplianceStatusBar.jsx │ │ ├── ProgressBar.jsx │ │ ├── SeverityBar.tsx │ │ ├── StatusBar.jsx │ │ ├── Toolbar.jsx │ │ └── __tests__ │ │ │ ├── ComplianceStatusBar.test.jsx │ │ │ ├── ProgressBar.test.jsx │ │ │ ├── SeverityBar.test.jsx │ │ │ ├── StatusBar.test.jsx │ │ │ ├── Toolbar.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Toolbar.test.jsx.snap │ │ │ └── toolbar.test.jsx.snap │ ├── certinfo │ │ └── CertInfo.jsx │ ├── chart │ │ ├── Axis.jsx │ │ ├── Bar.jsx │ │ ├── Bubble.jsx │ │ ├── Donut.jsx │ │ ├── Group.jsx │ │ ├── HostsTopologyChart.tsx │ │ ├── Label.jsx │ │ ├── Legend.jsx │ │ ├── Line.jsx │ │ ├── Schedule.jsx │ │ ├── Svg.jsx │ │ ├── Tooltip.jsx │ │ ├── WordCloud.jsx │ │ ├── donut │ │ │ ├── Arc2d.jsx │ │ │ ├── Arc3d.jsx │ │ │ ├── Labels.jsx │ │ │ ├── Paths.jsx │ │ │ ├── Pie.jsx │ │ │ └── PropTypes.jsx │ │ └── utils │ │ │ ├── Arc.jsx │ │ │ ├── Constants.jsx │ │ │ ├── Path.jsx │ │ │ ├── Update.jsx │ │ │ └── __tests__ │ │ │ ├── Arc.test.jsx │ │ │ ├── Path.test.jsx │ │ │ ├── Update.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Arc.test.jsx.snap │ │ │ └── arc.test.jsx.snap │ ├── comment │ │ ├── Comment.jsx │ │ └── __tests__ │ │ │ └── Comment.test.jsx │ ├── conditionalRoute │ │ ├── ConditionalRoute.jsx │ │ └── __tests__ │ │ │ └── ConditionalRoute.test.jsx │ ├── dashboard │ │ ├── Controls.jsx │ │ ├── Dashboard.jsx │ │ ├── Registry.jsx │ │ ├── Utils.jsx │ │ ├── __tests__ │ │ │ └── Utils.test.jsx │ │ └── display │ │ │ ├── DataDisplay.tsx │ │ │ ├── DataDisplayIcons.tsx │ │ │ ├── DataTable.jsx │ │ │ ├── DataTableDisplay.jsx │ │ │ ├── Display.jsx │ │ │ ├── FilterSelection.jsx │ │ │ ├── __tests__ │ │ │ └── utils.test.js │ │ │ ├── createDisplay.jsx │ │ │ ├── created │ │ │ ├── CreatedDisplay.jsx │ │ │ └── CreatedTransform.jsx │ │ │ ├── cvss │ │ │ ├── CvssDisplay.jsx │ │ │ ├── CvssTableDisplay.jsx │ │ │ └── cvssTransform.js │ │ │ ├── severity │ │ │ ├── SeverityClassDisplay.tsx │ │ │ ├── SeverityClassTableDisplay.jsx │ │ │ ├── __tests__ │ │ │ │ └── utils.test.js │ │ │ ├── severityClassTransform.ts │ │ │ └── utils.ts │ │ │ ├── status │ │ │ └── StatusDisplay.jsx │ │ │ ├── utils.js │ │ │ └── withFilterSelection.jsx │ ├── date │ │ ├── DateTime.tsx │ │ └── __tests__ │ │ │ └── DateTime.test.jsx │ ├── dialog │ │ ├── CloseButton.jsx │ │ ├── ComposerContent.jsx │ │ ├── ConfirmationDialog.jsx │ │ ├── Container.jsx │ │ ├── Content.jsx │ │ ├── Dialog.jsx │ │ ├── DialogInlineNotification.jsx │ │ ├── Error.jsx │ │ ├── Footer.tsx │ │ ├── MultiStepFooter.jsx │ │ ├── SaveDialog.jsx │ │ ├── SaveDialogFooter.jsx │ │ ├── TwoButtonFooter.jsx │ │ └── __tests__ │ │ │ ├── CloseButton.test.jsx │ │ │ ├── ConfirmationDialog.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── Error.test.jsx │ │ │ ├── MultiStepFooter.test.jsx │ │ │ ├── SaveDialogFooter.test.jsx │ │ │ └── TwoButtonFooter.test.jsx │ ├── error │ │ ├── ErrorBoundary.jsx │ │ ├── ErrorContainer.jsx │ │ ├── ErrorMessage.tsx │ │ ├── ErrorPanel.jsx │ │ ├── Message.tsx │ │ ├── MessageContainer.jsx │ │ └── __tests__ │ │ │ ├── ErrorBoundary.test.jsx │ │ │ ├── ErrorContainer.test.jsx │ │ │ ├── ErrorMessage.test.jsx │ │ │ └── ErrorPanel.test.jsx │ ├── folding │ │ ├── Folding.jsx │ │ └── __tests__ │ │ │ └── Folding.test.jsx │ ├── footnote │ │ ├── Footnote.jsx │ │ └── __tests__ │ │ │ ├── Footnote.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Footnote.test.jsx.snap │ │ │ └── footnote.test.jsx.snap │ ├── form │ │ ├── Button.tsx │ │ ├── Checkbox.tsx │ │ ├── DatePicker.tsx │ │ ├── Download.tsx │ │ ├── ErrorMarker.tsx │ │ ├── FileField.tsx │ │ ├── FormGroup.tsx │ │ ├── MultiSelect.tsx │ │ ├── NumberField.tsx │ │ ├── PasswordField.tsx │ │ ├── Radio.tsx │ │ ├── Select.tsx │ │ ├── Spinner.tsx │ │ ├── TextArea.tsx │ │ ├── TextField.tsx │ │ ├── TimeZoneSelect.tsx │ │ ├── ToggleButton.tsx │ │ ├── YesNoRadio.tsx │ │ ├── __tests__ │ │ │ ├── Button.test.tsx │ │ │ ├── Checkbox.test.tsx │ │ │ ├── Download.test.tsx │ │ │ ├── FileField.test.tsx │ │ │ ├── FormGroup.test.tsx │ │ │ ├── MultiSelect.test.tsx │ │ │ ├── NumberField.test.tsx │ │ │ ├── PasswordField.test.tsx │ │ │ ├── Radio.test.tsx │ │ │ ├── Select.test.tsx │ │ │ ├── Spinner.test.tsx │ │ │ ├── TextArea.test.tsx │ │ │ ├── TextField.test.tsx │ │ │ ├── TimeZoneSelect.test.tsx │ │ │ ├── ToggleButton.test.tsx │ │ │ ├── YesNoRadio.test.tsx │ │ │ ├── __snapshots__ │ │ │ │ ├── ToggleButton.test.jsx.snap │ │ │ │ ├── ToggleButton.test.tsx.snap │ │ │ │ └── togglebutton.test.jsx.snap │ │ │ ├── useClickHandler.test.tsx │ │ │ ├── useDownload.test.tsx │ │ │ ├── useFormValidation.test.tsx │ │ │ ├── useFormValues.test.tsx │ │ │ ├── useValueChange.test.tsx │ │ │ ├── withClickHandler.test.tsx │ │ │ └── withDownload.test.tsx │ │ ├── useClickHandler.ts │ │ ├── useDownload.ts │ │ ├── useFormValidation.ts │ │ ├── useFormValues.ts │ │ ├── useValueChange.tsx │ │ ├── withClickHandler.tsx │ │ └── withDownload.tsx │ ├── icon │ │ ├── CpeIcon.jsx │ │ ├── DeleteIcon.tsx │ │ ├── DynamicIcon.tsx │ │ ├── ExportIcon.tsx │ │ ├── FoldStateIcon.tsx │ │ ├── GreenboneApplianceLogo.tsx │ │ ├── Icon.tsx │ │ ├── ListIcon.jsx │ │ ├── ManualIcon.jsx │ │ ├── OsIcon.jsx │ │ ├── SolutionTypeIcon.jsx │ │ ├── TagsIcon.jsx │ │ ├── TrashDeleteIcon.jsx │ │ ├── TrashIcon.tsx │ │ ├── createIconComponents.tsx │ │ ├── index.tsx │ │ ├── svg │ │ │ ├── Enterprise_150.svg │ │ │ ├── Enterprise_400.svg │ │ │ ├── Enterprise_450.svg │ │ │ ├── Enterprise_5400.svg │ │ │ ├── Enterprise_600.svg │ │ │ ├── Enterprise_650.svg │ │ │ ├── Enterprise_6500.svg │ │ │ ├── Enterprise_CENO.svg │ │ │ ├── Enterprise_DECA.svg │ │ │ ├── Enterprise_EXA.svg │ │ │ ├── Enterprise_PETA.svg │ │ │ ├── Enterprise_TERA.svg │ │ │ ├── add_to_assets.svg │ │ │ ├── calendar.svg │ │ │ ├── cert_bund_adv.svg │ │ │ ├── clone.svg │ │ │ ├── config.svg │ │ │ ├── cpe.svg │ │ │ ├── cve.svg │ │ │ ├── cvss_calculator.svg │ │ │ ├── delta.svg │ │ │ ├── delta_second.svg │ │ │ ├── dfn_cert_adv.svg │ │ │ ├── dl_csv.svg │ │ │ ├── dl_deb.svg │ │ │ ├── dl_exe.svg │ │ │ ├── dl_key.svg │ │ │ ├── dl_rpm.svg │ │ │ ├── dl_svg.svg │ │ │ ├── export.svg │ │ │ ├── greenbone.svg │ │ │ ├── host.svg │ │ │ ├── ldap.svg │ │ │ ├── legend.svg │ │ │ ├── new.svg │ │ │ ├── new_note.svg │ │ │ ├── new_override.svg │ │ │ ├── new_ticket.svg │ │ │ ├── note.svg │ │ │ ├── nvt.svg │ │ │ ├── os.svg │ │ │ ├── override.svg │ │ │ ├── port_list.svg │ │ │ ├── provide_view.svg │ │ │ ├── radius.svg │ │ │ ├── remove_from_assets.svg │ │ │ ├── report.svg │ │ │ ├── report_format.svg │ │ │ ├── restore.svg │ │ │ ├── result.svg │ │ │ ├── role.svg │ │ │ ├── scanner.svg │ │ │ ├── sensor.svg │ │ │ ├── st_mitigate.svg │ │ │ ├── st_nonavailable.svg │ │ │ ├── st_unknown.svg │ │ │ ├── st_vendorfix.svg │ │ │ ├── st_willnotfix.svg │ │ │ ├── st_workaround.svg │ │ │ ├── target.svg │ │ │ ├── task.svg │ │ │ ├── ticket.svg │ │ │ ├── tlscertificate.svg │ │ │ ├── toggle3d.svg │ │ │ ├── trend_down.svg │ │ │ ├── trend_less.svg │ │ │ ├── trend_more.svg │ │ │ ├── trend_nochange.svg │ │ │ ├── trend_up.svg │ │ │ ├── vulnerability.svg │ │ │ └── wizard.svg │ │ └── test │ │ │ ├── DynamicIcon.test.tsx │ │ │ ├── Icon.test.jsx │ │ │ ├── SolutionTypeIcon.test.jsx │ │ │ └── createIconComponent.test.tsx │ ├── img │ │ ├── Greenbone.jsx │ │ ├── GreenboneLoginLogo.jsx │ │ ├── Img.jsx │ │ ├── Product.jsx │ │ └── __tests__ │ │ │ ├── Greenbone.test.jsx │ │ │ ├── GreenboneLoginLogo.test.jsx │ │ │ ├── Img.test.jsx │ │ │ ├── Product.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Greenbone.test.jsx.snap │ │ │ ├── GreenboneLoginLogo.test.jsx.snap │ │ │ ├── Img.test.jsx.snap │ │ │ ├── Product.test.jsx.snap │ │ │ ├── greenbone.test.jsx.snap │ │ │ ├── greenboneloginlogo.test.jsx.snap │ │ │ ├── img.test.jsx.snap │ │ │ └── product.test.jsx.snap │ ├── label │ │ ├── ComplianceState.tsx │ │ ├── Label.tsx │ │ ├── SeverityClass.tsx │ │ └── __tests__ │ │ │ └── SeverityClass.test.jsx │ ├── layout │ │ ├── AutoSize.jsx │ │ ├── Column.tsx │ │ ├── Divider.tsx │ │ ├── GlobalStyles.jsx │ │ ├── HorizontalSep.tsx │ │ ├── IconDivider.jsx │ │ ├── Layout.tsx │ │ ├── PageTitle.jsx │ │ ├── Row.tsx │ │ ├── __tests__ │ │ │ ├── HorizontalSep.test.jsx │ │ │ ├── Layout.test.jsx │ │ │ ├── PageTitle.test.jsx │ │ │ ├── __snapshots__ │ │ │ │ ├── HorizontalSep.test.jsx.snap │ │ │ │ ├── Layout.test.jsx.snap │ │ │ │ └── withLayout.test.jsx.snap │ │ │ └── withLayout.test.jsx │ │ └── withLayout.tsx │ ├── link │ │ ├── BlankLink.jsx │ │ ├── CertLink.jsx │ │ ├── CveLink.jsx │ │ ├── DetailsLink.jsx │ │ ├── ExternalLink.jsx │ │ ├── InnerLink.jsx │ │ ├── Link.jsx │ │ ├── ManualLink.jsx │ │ ├── ProtocolDocLink.jsx │ │ ├── Target.jsx │ │ └── __tests__ │ │ │ ├── BlankLink.test.jsx │ │ │ ├── CertLink.test.jsx │ │ │ ├── CveLink.test.jsx │ │ │ ├── DetailsLink.test.jsx │ │ │ ├── ExternalLink.test.jsx │ │ │ ├── InnerLink.test.jsx │ │ │ ├── Link.test.jsx │ │ │ ├── ManualLink.test.jsx │ │ │ ├── ProtocolDocLink.test.jsx │ │ │ ├── Target.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Target.test.jsx.snap │ │ │ └── target.test.jsx.snap │ ├── loading │ │ ├── Loading.jsx │ │ ├── Reload.jsx │ │ └── __tests__ │ │ │ ├── Loading.test.jsx │ │ │ └── Reload.test.jsx │ ├── menu │ │ ├── IconMenu.jsx │ │ ├── Menu.jsx │ │ ├── MenuEntry.tsx │ │ ├── MenuHelpEntry.jsx │ │ ├── MenuSection.jsx │ │ └── __tests__ │ │ │ ├── Menu.test.jsx │ │ │ └── MenuEntry.test.tsx │ ├── notification │ │ ├── DialogNotification.jsx │ │ ├── FeedSyncNotification │ │ │ ├── FeedSyncNotification.jsx │ │ │ ├── Helpers.jsx │ │ │ └── __tests__ │ │ │ │ ├── FeedSyncNotification.test.jsx │ │ │ │ └── Helpers.test.jsx │ │ ├── LicenseNotification.jsx │ │ ├── __tests__ │ │ │ ├── DialogNotification.test.jsx │ │ │ └── LicenseNotification.test.jsx │ │ ├── useDialogNotification.jsx │ │ └── withDialogNotifiaction.jsx │ ├── observer │ │ ├── LocationObserver.jsx │ │ └── SessionObserver.jsx │ ├── pagination │ │ └── Pagination.jsx │ ├── panel │ │ ├── Button.jsx │ │ ├── InfoPanel.jsx │ │ └── __tests__ │ │ │ ├── Button.test.jsx │ │ │ ├── InfoPanel.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Button.test.jsx.snap │ │ │ └── button.test.jsx.snap │ ├── portal │ │ ├── Portal.jsx │ │ └── __tests__ │ │ │ └── Portal.test.jsx │ ├── powerfilter │ │ ├── ApplyOverridesGroup.jsx │ │ ├── BooleanFilterGroup.jsx │ │ ├── ComplianceLevelsGroup.tsx │ │ ├── CreateNamedFilterGroup.jsx │ │ ├── Dialog.jsx │ │ ├── DialogPropTypes.jsx │ │ ├── FilterDialog.jsx │ │ ├── FilterSearchGroup.jsx │ │ ├── FilterStringGroup.jsx │ │ ├── FirstResultGroup.jsx │ │ ├── MinQodGroup.jsx │ │ ├── PowerFilter.jsx │ │ ├── RelationSelector.jsx │ │ ├── ResultsPerPageGroup.jsx │ │ ├── SeverityLevelsGroup.tsx │ │ ├── SeverityValuesGroup.jsx │ │ ├── SolutionTypeGroup.jsx │ │ ├── SortByGroup.jsx │ │ ├── TaskTrendGroup.jsx │ │ ├── TicketStatusGroup.jsx │ │ ├── __tests__ │ │ │ ├── ApplyOverridesGroup.test.jsx │ │ │ ├── ComplianceLevelsGroup.test.tsx │ │ │ ├── RelationSelector.test.jsx │ │ │ ├── SeverityLevelsGroup.test.tsx │ │ │ ├── SeverityValuesGroup.test.jsx │ │ │ ├── SolutionTypeGroup.test.jsx │ │ │ ├── SortByGroup.test.jsx │ │ │ ├── TaskTrendGroup.test.jsx │ │ │ ├── TicketStatusGroup.test.jsx │ │ │ └── __snapshots__ │ │ │ │ ├── booleanfiltergroup.jsx.snap │ │ │ │ ├── createnamedfiltergroup.jsx.snap │ │ │ │ ├── filtersearchgroup.jsx.snap │ │ │ │ ├── filterstringgroup.jsx.snap │ │ │ │ ├── firstresultgroup.jsx.snap │ │ │ │ ├── minqodgroup.jsx.snap │ │ │ │ └── resultsperpagegroup.jsx.snap │ │ ├── useFilterDialog.jsx │ │ ├── useFilterDialogSave.jsx │ │ └── withFilterDialog.jsx │ ├── provider │ │ ├── CapabilitiesProvider.tsx │ │ ├── GmpProvider.tsx │ │ ├── IconSizeProvider.tsx │ │ ├── LanguageProvider.tsx │ │ ├── LicenseProvider.jsx │ │ └── SubscriptionProvider.jsx │ ├── qod │ │ ├── Qod.jsx │ │ └── __tests__ │ │ │ ├── Qod.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Qod.test.jsx.snap │ │ │ └── qod.test.jsx.snap │ ├── searchbar │ │ ├── SearchBar.jsx │ │ └── __tests__ │ │ │ └── SearchBar.test.jsx │ ├── section │ │ ├── Header.tsx │ │ └── Section.tsx │ ├── sessionTimer │ │ └── SessionTimer.jsx │ ├── snackbar │ │ ├── Snackbar.jsx │ │ └── __tests__ │ │ │ ├── Snackbar.test.jsx │ │ │ └── __snapshots__ │ │ │ ├── Snackbar.test.jsx.snap │ │ │ └── snackbar.test.jsx.snap │ ├── sortable │ │ ├── EmptyRow.jsx │ │ ├── Grid.jsx │ │ ├── Item.jsx │ │ ├── Resizer.jsx │ │ └── Row.jsx │ ├── sortby │ │ └── SortBy.tsx │ ├── structure │ │ ├── Footer.jsx │ │ ├── Header.jsx │ │ ├── LanguageSwitch.tsx │ │ ├── Main.jsx │ │ ├── __tests__ │ │ │ ├── Footer.test.jsx │ │ │ ├── Header.test.jsx │ │ │ ├── LanguageSwitch.test.jsx │ │ │ ├── Main.test.jsx │ │ │ ├── __snapshots__ │ │ │ │ ├── Main.test.jsx.snap │ │ │ │ └── main.test.jsx.snap │ │ │ └── getLogo.test.jsx │ │ └── getLogo.jsx │ ├── tab │ │ ├── Tab.jsx │ │ ├── TabLayout.jsx │ │ ├── TabList.jsx │ │ ├── TabPanel.jsx │ │ ├── TabPanels.tsx │ │ ├── Tabs.tsx │ │ └── __tests__ │ │ │ └── TabPanels.test.tsx │ └── table │ │ ├── Body.jsx │ │ ├── Col.tsx │ │ ├── Data.tsx │ │ ├── DetailsTable.jsx │ │ ├── Footer.jsx │ │ ├── Head.tsx │ │ ├── Header.jsx │ │ ├── InfoTable.jsx │ │ ├── Row.jsx │ │ ├── SimpleTable.jsx │ │ ├── StripedTable.tsx │ │ ├── Table.tsx │ │ └── __tests__ │ │ └── DetailsTable.test.jsx │ ├── entities │ ├── Actions.jsx │ ├── BulkTags.jsx │ ├── Container.jsx │ ├── EntityNameTableData.jsx │ ├── FilterProvider.jsx │ ├── Footer.jsx │ ├── Header.jsx │ ├── Page.jsx │ ├── RowDetailsToggle.jsx │ ├── Selection.jsx │ ├── Table.jsx │ ├── TagsDialog.jsx │ ├── __tests__ │ │ ├── BulkTags.test.jsx │ │ ├── Container.test.jsx │ │ ├── FilterProvider.test.jsx │ │ ├── Footer.test.jsx │ │ ├── RowDetailsToggle.test.jsx │ │ ├── TagsDialog.test.jsx │ │ └── useEntitiesReloadInterval.test.jsx │ ├── useEntitiesReloadInterval.js │ ├── withEntitiesActions.jsx │ ├── withEntitiesContainer.jsx │ └── withRowDetails.jsx │ ├── entity │ ├── Block.jsx │ ├── Box.jsx │ ├── Container.jsx │ ├── EntityComponent.jsx │ ├── EntityInfo.tsx │ ├── EntityPage.tsx │ ├── Link.jsx │ ├── Note.jsx │ ├── Override.jsx │ ├── Page.jsx │ ├── Permissions.jsx │ ├── Tab.jsx │ ├── Tags.jsx │ ├── __tests__ │ │ ├── Block.test.jsx │ │ ├── Box.test.jsx │ │ ├── EntityComponent.test.jsx │ │ ├── Info.test.jsx │ │ ├── Link.test.jsx │ │ ├── Note.test.jsx │ │ ├── Override.test.jsx │ │ └── navigation.tests.js │ ├── hooks │ │ ├── __tests__ │ │ │ ├── actionFunction.test.js │ │ │ ├── usEntityClone.test.js │ │ │ ├── useActiveTab.test.ts │ │ │ ├── useEntityDelete.test.js │ │ │ ├── useEntityDownload.test.js │ │ │ └── useEntitySave.test.js │ │ ├── actionFunction.ts │ │ ├── useActiveTab.ts │ │ ├── useEntityClone.ts │ │ ├── useEntityDelete.ts │ │ ├── useEntityDownload.ts │ │ └── useEntitySave.ts │ ├── icon │ │ ├── CloneIcon.tsx │ │ ├── CreateIcon.tsx │ │ ├── DeleteIcon.tsx │ │ ├── EditIcon.tsx │ │ ├── ObserverIcon.tsx │ │ ├── TrashIcon.tsx │ │ ├── VerifyIcon.tsx │ │ └── __tests__ │ │ │ ├── CloneIcon.test.jsx │ │ │ ├── CreateIcon.test.jsx │ │ │ ├── DeleteIcon.test.jsx │ │ │ ├── EditIcon.test.jsx │ │ │ ├── ObserverIcon.test.jsx │ │ │ ├── TrashIcon.test.jsx │ │ │ └── VerifyIcon.test.jsx │ ├── navigation.ts │ └── withEntityContainer.jsx │ ├── hooks │ ├── __tests__ │ │ ├── useCapabilities.test.jsx │ │ ├── useFilterSortBy.test.jsx │ │ ├── useGmp.test.jsx │ │ ├── useIconSize.test.jsx │ │ ├── useInstanceVariable.test.tsx │ │ ├── useLanguage.test.tsx │ │ ├── useLoadCapabilities.test.jsx │ │ ├── useManualURL.test.jsx │ │ ├── usePageFilter.test.jsx │ │ ├── usePagination.test.jsx │ │ ├── usePreviousValue.test.jsx │ │ ├── useReload.test.jsx │ │ ├── useSelection.test.jsx │ │ ├── useShallowEqualSelector.test.jsx │ │ ├── useTiming.test.jsx │ │ ├── useTranslation.test.jsx │ │ ├── useUserName.test.jsx │ │ ├── useUserSessionTimeout.test.jsx │ │ └── useUserTimezone.test.jsx │ ├── useCapabilities.ts │ ├── useFilterSortBy.js │ ├── useGmp.ts │ ├── useIconSize.ts │ ├── useInstanceVariable.ts │ ├── useLanguage.ts │ ├── useLicense.js │ ├── useLoadCapabilities.jsx │ ├── useManualURL.js │ ├── usePageFilter.js │ ├── usePagination.js │ ├── usePreviousValue.js │ ├── useReload.js │ ├── useSelection.js │ ├── useShallowEqualSelector.ts │ ├── useTiming.js │ ├── useTranslation.ts │ ├── useUserIsLoggedIn.js │ ├── useUserName.js │ ├── useUserSessionTimeout.js │ ├── useUserTimezone.ts │ └── withLanguage.tsx │ ├── pages │ ├── NotFoundPage.jsx │ ├── Omp.jsx │ ├── Page.jsx │ ├── __mocks__ │ │ └── CurrentSettings.js │ ├── alerts │ │ ├── AlembavFireMethodPart.jsx │ │ ├── AlertComponent.jsx │ │ ├── Condition.jsx │ │ ├── ContentComposerDialog.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── EmailMethodPart.jsx │ │ ├── Event.jsx │ │ ├── FilterCountChangedConditionPart.jsx │ │ ├── FilterCountLeastConditionPart.jsx │ │ ├── FilterDialog.jsx │ │ ├── HttpMethodPart.jsx │ │ ├── ListPage.jsx │ │ ├── Method.jsx │ │ ├── Row.jsx │ │ ├── ScpMethodPart.jsx │ │ ├── SecInfoEventPart.jsx │ │ ├── SendMethodPart.jsx │ │ ├── SeverityChangedConditionPart.jsx │ │ ├── SeverityLeastConditionPart.jsx │ │ ├── SmbMethodPart.jsx │ │ ├── SnmpMethodPart.jsx │ │ ├── SourceFireMethodPart.jsx │ │ ├── StartTaskMethodPart.jsx │ │ ├── Table.jsx │ │ ├── TaskEventPart.jsx │ │ ├── TicketEventPart.jsx │ │ ├── TippingPointMethodPart.jsx │ │ ├── VeriniceMethodPart.jsx │ │ └── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ └── ListPage.test.jsx │ ├── audits │ │ ├── Actions.jsx │ │ ├── AuditComponent.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ ├── Actions.test.jsx │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ └── Table.test.jsx │ ├── certbund │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── CvssDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── cpes │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ └── ListPage.test.jsx │ │ └── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── CvssDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── credentials │ │ ├── CredentialsComponent.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── DownloadIcon.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ └── ListPage.test.jsx │ ├── cves │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ └── Table.test.jsx │ │ └── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── CvssDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── dfncert │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── CvssDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── extras │ │ ├── CvssCalculatorPage.jsx │ │ ├── FeedStatusPage.jsx │ │ ├── TrashActions.jsx │ │ ├── TrashCanPage.jsx │ │ ├── __tests__ │ │ │ ├── CvssCalculatorPage.test.jsx │ │ │ ├── FeedStatusPage.test.jsx │ │ │ └── TrashCanPage.test.jsx │ │ └── cvssV4 │ │ │ ├── CvssV4Calculator.jsx │ │ │ ├── Metrics.jsx │ │ │ ├── MetricsGroups.jsx │ │ │ ├── __tests__ │ │ │ ├── Metrics.test.jsx │ │ │ └── cvssV4Calculator.test.jsx │ │ │ └── cvssConfig.js │ ├── filters │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterComponent.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ └── Table.jsx │ ├── groups │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── GroupComponent.jsx │ │ ├── Header.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ └── Table.jsx │ ├── help │ │ ├── About.jsx │ │ └── __tests__ │ │ │ └── About.test.jsx │ ├── hosts │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── HostComponent.jsx │ │ ├── Identifiers.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ └── ListPage.test.jsx │ │ └── dashboard │ │ │ ├── CvssDisplay.jsx │ │ │ ├── HostsTopologyDisplay.jsx │ │ │ ├── HostsVulnScoreDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── ModifiedDisplay.jsx │ │ │ ├── ModifiedHighDisplay.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── ldap │ │ ├── LdapDialog.tsx │ │ ├── LdapPage.tsx │ │ └── __tests__ │ │ │ └── LdapDialog.test.tsx │ ├── login │ │ ├── LoginForm.jsx │ │ ├── LoginPage.tsx │ │ ├── __tests__ │ │ │ ├── LoginForm.test.jsx │ │ │ └── LoginPage.test.jsx │ │ └── notifications │ │ │ ├── CommunityFeedUsageNotification.tsx │ │ │ └── __tests__ │ │ │ └── CommunityFeedUsageNotification.test.tsx │ ├── notes │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── NoteComponent.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ └── ListPage.test.jsx │ │ └── dashboard │ │ │ ├── ActiveDaysDisplay.jsx │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── WordCloudDisplay.jsx │ │ │ └── index.jsx │ ├── nvts │ │ ├── Component.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── NvtPreference.jsx │ │ ├── Preferences.jsx │ │ ├── Preformatted.jsx │ │ ├── References.jsx │ │ ├── Row.jsx │ │ ├── Solution.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── NvtPreference.test.jsx │ │ │ └── Row.test.jsx │ │ └── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── CvssDisplay.jsx │ │ │ ├── FamilyDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── QodDisplay.jsx │ │ │ ├── QodTypeDisplay.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ ├── operatingsystems │ │ ├── Component.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── dashboard │ │ │ ├── CvssDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ ├── VulnScoreDisplay.jsx │ │ │ └── index.jsx │ ├── overrides │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── OverrideComponent.jsx │ │ ├── Row.tsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ └── ListPage.test.jsx │ │ └── dashboard │ │ │ ├── ActiveDaysDisplay.jsx │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── WordCloudDisplay.jsx │ │ │ └── index.jsx │ ├── performance │ │ ├── PerformancePage.tsx │ │ ├── PerformanceReport.tsx │ │ ├── StartEndTimeSelection.tsx │ │ ├── __tests__ │ │ │ ├── PerformanceReport.test.tsx │ │ │ ├── StartEndTimeSelection.test.jsx │ │ │ └── durations.test.ts │ │ └── durations.ts │ ├── permissions │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── MultipleDialog.jsx │ │ ├── PermissionsComponent.jsx │ │ ├── Row.jsx │ │ └── Table.jsx │ ├── policies │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── Header.jsx │ │ ├── ListPage.jsx │ │ ├── PoliciesComponent.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ └── Table.test.jsx │ ├── portlists │ │ ├── Details.tsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── PortListComponent.tsx │ │ ├── PortListDialog.tsx │ │ ├── PortListImportDialog.tsx │ │ ├── PortRangeDialog.tsx │ │ ├── PortRangesTable.tsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ ├── PortListComponent.test.jsx │ │ │ └── PortRangeDialog.test.jsx │ ├── radius │ │ ├── RadiusDialog.tsx │ │ ├── RadiusPage.tsx │ │ └── __tests__ │ │ │ ├── RadiusDialog.test.tsx │ │ │ └── RadiusPage.test.tsx │ ├── reportconfigs │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── ReportConfigsComponent.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __mocks__ │ │ │ ├── MockReportConfig.jsx │ │ │ └── MockReportFormats.jsx │ │ └── __tests__ │ │ │ ├── Component.test.jsx │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ └── Table.test.jsx │ ├── reportformats │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── ReportFormatComponent.jsx │ │ ├── Row.jsx │ │ └── Table.jsx │ ├── reports │ │ ├── AuditDeltaDetailsPage.jsx │ │ ├── AuditDetailsContent.jsx │ │ ├── AuditDetailsPage.jsx │ │ ├── AuditFilterDialog.jsx │ │ ├── AuditReportRow.jsx │ │ ├── AuditReportsListPage.jsx │ │ ├── AuditReportsTable.jsx │ │ ├── DeltaDetailsContent.jsx │ │ ├── DeltaDetailsPage.jsx │ │ ├── DeltaResultsFilterGroup.jsx │ │ ├── DetailsContent.jsx │ │ ├── DetailsFilterDialog.jsx │ │ ├── DetailsPage.jsx │ │ ├── DownloadReportDialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ImportDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── ThresholdMessage.jsx │ │ ├── TriggerAlertDialog.jsx │ │ ├── __mocks__ │ │ │ ├── MockAuditDeltaReport.jsx │ │ │ ├── MockAuditReport.jsx │ │ │ ├── MockDeltaReport.jsx │ │ │ └── MockReport.jsx │ │ ├── __tests__ │ │ │ ├── AuditDeltaDetailsPage.test.jsx │ │ │ ├── AuditDetailsContent.test.jsx │ │ │ ├── AuditFilterDialog.test.jsx │ │ │ ├── AuditReportRow.test.jsx │ │ │ ├── AuditReportsListPage.test.jsx │ │ │ ├── DeltaDetailsContent.test.jsx │ │ │ ├── DetailsContent.test.jsx │ │ │ └── DetailsFilterDialog.test.jsx │ │ ├── auditdashboard │ │ │ ├── Loaders.jsx │ │ │ ├── StatusDisplay.jsx │ │ │ └── index.jsx │ │ ├── dashboard │ │ │ ├── CvssDisplay.jsx │ │ │ ├── HighResultsDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ └── index.jsx │ │ └── details │ │ │ ├── AlertActions.jsx │ │ │ ├── ApplicationsTab.jsx │ │ │ ├── ApplicationsTable.jsx │ │ │ ├── AuditThresholdPanel.jsx │ │ │ ├── ClosedCvesTab.jsx │ │ │ ├── ClosedCvesTable.jsx │ │ │ ├── CvesTab.jsx │ │ │ ├── CvesTable.jsx │ │ │ ├── DeltaResultsTab.jsx │ │ │ ├── EmptyReport.jsx │ │ │ ├── EmptyResultsReport.jsx │ │ │ ├── ErrorsTab.jsx │ │ │ ├── ErrorsTable.jsx │ │ │ ├── HostsTab.jsx │ │ │ ├── HostsTable.jsx │ │ │ ├── OperatingSystemsTab.jsx │ │ │ ├── OperatingSystemsTable.jsx │ │ │ ├── PortsTab.jsx │ │ │ ├── PortsTable.jsx │ │ │ ├── ReportEntitiesContainer.jsx │ │ │ ├── ReportPanel.jsx │ │ │ ├── ResultsTab.jsx │ │ │ ├── Summary.jsx │ │ │ ├── TabTitle.jsx │ │ │ ├── ThresholdPanel.jsx │ │ │ ├── TlsCertificatesTab.jsx │ │ │ ├── TlsCertificatesTable.jsx │ │ │ ├── ToolbarIcons.jsx │ │ │ └── __tests__ │ │ │ ├── ApplicationsTab.test.jsx │ │ │ ├── ClosedCvesTab.test.jsx │ │ │ ├── CvesTab.test.jsx │ │ │ ├── DeltaResultsTab.test.jsx │ │ │ ├── EmptyReport.test.jsx │ │ │ ├── EmptyResultsReport.test.jsx │ │ │ ├── ErrorsTab.test.jsx │ │ │ ├── HostsTab.test.jsx │ │ │ ├── OperatingSystemsTab.test.jsx │ │ │ ├── PortsTab.test.jsx │ │ │ ├── ResultsTab.test.jsx │ │ │ ├── Summary.test.jsx │ │ │ ├── ThresholdPanel.test.jsx │ │ │ ├── TlsCertificatesTab.test.jsx │ │ │ └── ToolbarIcons.test.jsx │ ├── results │ │ ├── Delta.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Diff.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Diff.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ └── Row.test.jsx │ │ └── dashboard │ │ │ ├── CvssDisplay.jsx │ │ │ ├── DescriptionWordCloudDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ ├── WordCloudDisplay.jsx │ │ │ └── index.jsx │ ├── roles │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── RoleComponent.jsx │ │ ├── Row.jsx │ │ └── Table.jsx │ ├── scanconfigs │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── EditConfigFamilyDialog.jsx │ │ ├── EditDialog.jsx │ │ ├── EditNvtDetailsDialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── Header.jsx │ │ ├── ImportDialog.jsx │ │ ├── ListPage.jsx │ │ ├── NvtFamilies.jsx │ │ ├── NvtPreferences.jsx │ │ ├── Row.jsx │ │ ├── ScanConfigComponent.jsx │ │ ├── ScannerPreferences.jsx │ │ ├── Settings.jsx │ │ ├── Table.jsx │ │ ├── Trend.jsx │ │ └── __tests__ │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── EditConfigFamilyDialog.test.jsx │ │ │ ├── EditDialog.test.jsx │ │ │ ├── EditNvtDetailsDialog.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ ├── Table.test.jsx │ │ │ └── Trend.test.jsx │ ├── scanners │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── ScannerComponent.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ └── Dialog.test.jsx │ ├── schedules │ │ ├── DaySelect.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── MonthDaysSelect.jsx │ │ ├── Render.jsx │ │ ├── Row.jsx │ │ ├── ScheduleComponent.jsx │ │ ├── Table.jsx │ │ ├── TimeUnitSelect.jsx │ │ ├── WeekdaySelect.jsx │ │ └── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ └── ListPage.test.jsx │ ├── start │ │ ├── ConfirmRemoveDialog.jsx │ │ ├── Dashboard.jsx │ │ ├── EditDashboardDialog.jsx │ │ ├── NewDashboardDialog.jsx │ │ ├── Page.jsx │ │ └── __tests__ │ │ │ └── Page.test.jsx │ ├── tags │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── ResourceList.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── TagsComponent.jsx │ ├── targets │ │ ├── Component.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── __tests__ │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ └── Row.test.jsx │ ├── tasks │ │ ├── Actions.jsx │ │ ├── AddResultsToAssetsGroup.jsx │ │ ├── AutoDeleteReportsGroup.jsx │ │ ├── Component.jsx │ │ ├── ContainerDialog.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Status.jsx │ │ ├── Table.jsx │ │ ├── Task.jsx │ │ ├── Trend.jsx │ │ ├── __tests__ │ │ │ ├── Actions.test.jsx │ │ │ ├── AutoDeleteReportsGroup.test.jsx │ │ │ ├── ContainerDialog.test.jsx │ │ │ ├── Details.test.jsx │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── Dialog.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ ├── Status.test.jsx │ │ │ ├── Table.test.jsx │ │ │ └── Trend.test.jsx │ │ ├── dashboard │ │ │ ├── CvssDisplay.jsx │ │ │ ├── HighResults.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── MostHighResults.jsx │ │ │ ├── SchedulesDisplay.jsx │ │ │ ├── SeverityClassDisplay.jsx │ │ │ ├── StatusDisplay.jsx │ │ │ └── index.jsx │ │ └── icons │ │ │ ├── ImportReportIcon.jsx │ │ │ ├── NewIconMenu.jsx │ │ │ ├── ResumeIcon.jsx │ │ │ ├── ScheduleIcon.jsx │ │ │ ├── StartIcon.jsx │ │ │ ├── StopIcon.jsx │ │ │ ├── TaskIconsWithSync.jsx │ │ │ └── __tests__ │ │ │ ├── NewIconMenu.test.jsx │ │ │ ├── ResumeIcon.test.jsx │ │ │ ├── StartIcon.test.jsx │ │ │ ├── StopIcon.test.jsx │ │ │ └── TaskIconsWithSync.test.jsx │ ├── tickets │ │ ├── CreateDialog.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── EditDialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Table.jsx │ │ ├── TicketComponent.jsx │ │ ├── __tests__ │ │ │ ├── CreateDialog.test.jsx │ │ │ └── EditDialog.test.jsx │ │ ├── dashboard │ │ │ ├── CreatedDisplay.jsx │ │ │ ├── Loaders.jsx │ │ │ ├── StatusDisplay.jsx │ │ │ ├── UsersAssignedDisplay.jsx │ │ │ └── index.jsx │ │ └── validationrules.jsx │ ├── tlscertificates │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ ├── TlsCertificateComponent.jsx │ │ ├── __tests__ │ │ │ ├── DetailsPage.test.jsx │ │ │ ├── ListPage.test.jsx │ │ │ ├── Row.test.jsx │ │ │ └── Table.test.jsx │ │ └── dashboard │ │ │ ├── Loaders.jsx │ │ │ ├── ModifiedDisplay.jsx │ │ │ ├── TimeStatusDisplay.jsx │ │ │ └── index.jsx │ ├── users │ │ ├── ConfirmDeleteDialog.jsx │ │ ├── Details.jsx │ │ ├── DetailsPage.jsx │ │ ├── Dialog.jsx │ │ ├── FilterDialog.jsx │ │ ├── Header.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── UserComponent.jsx │ ├── usersettings │ │ ├── DefaultsPart.jsx │ │ ├── Dialog.jsx │ │ ├── FilterPart.jsx │ │ ├── GeneralPart.jsx │ │ ├── SeverityPart.jsx │ │ ├── UserSettingsPage.jsx │ │ └── validationrules.jsx │ └── vulns │ │ ├── FilterDialog.jsx │ │ ├── ListPage.jsx │ │ ├── Row.jsx │ │ ├── Table.jsx │ │ └── dashboard │ │ ├── CvssDisplay.jsx │ │ ├── HostsDisplay.jsx │ │ ├── Loaders.jsx │ │ ├── SeverityClassDisplay.jsx │ │ └── index.jsx │ ├── setupTests.ts │ ├── store │ ├── __tests__ │ │ └── utils.test.js │ ├── actions.js │ ├── dashboard │ │ ├── data │ │ │ ├── __tests__ │ │ │ │ ├── actions.test.js │ │ │ │ ├── loader.test.js │ │ │ │ ├── reducers.test.js │ │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── loader.js │ │ │ ├── reducers.js │ │ │ └── selectors.js │ │ └── settings │ │ │ ├── __tests__ │ │ │ ├── actions.test.js │ │ │ ├── reducers.test.js │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── reducers.js │ │ │ └── selectors.js │ ├── entities │ │ ├── __tests__ │ │ │ ├── alerts.test.js │ │ │ ├── audits.test.js │ │ │ ├── certbund.test.js │ │ │ ├── cpes.test.js │ │ │ ├── credentials.test.js │ │ │ ├── cves.test.js │ │ │ ├── dfncerts.test.js │ │ │ ├── filters.test.js │ │ │ ├── groups.test.js │ │ │ ├── hosts.test.js │ │ │ ├── notes.test.js │ │ │ ├── nvts.test.js │ │ │ ├── operatingsystems.test.js │ │ │ ├── overrides.test.js │ │ │ ├── permissions.test.js │ │ │ ├── policies.test.js │ │ │ ├── portlists.test.js │ │ │ ├── reducers.test.js │ │ │ ├── reportformats.test.js │ │ │ ├── reports.test.js │ │ │ ├── results.test.js │ │ │ ├── roles.test.js │ │ │ ├── scanconfigs.test.js │ │ │ ├── scanners.test.js │ │ │ ├── schedules.test.js │ │ │ ├── tags.test.js │ │ │ ├── targets.test.js │ │ │ ├── tasks.test.js │ │ │ ├── tickets.test.js │ │ │ ├── users.test.js │ │ │ └── vulns.test.js │ │ ├── alerts.js │ │ ├── auditreports.js │ │ ├── audits.js │ │ ├── certbund.js │ │ ├── cpes.js │ │ ├── credentials.js │ │ ├── cves.js │ │ ├── dfncerts.js │ │ ├── filters.js │ │ ├── groups.js │ │ ├── hosts.js │ │ ├── notes.js │ │ ├── nvts.js │ │ ├── operatingsystems.js │ │ ├── overrides.js │ │ ├── permissions.js │ │ ├── policies.js │ │ ├── portlists.js │ │ ├── reducers.js │ │ ├── report │ │ │ ├── __tests__ │ │ │ │ ├── actions.test.js │ │ │ │ ├── reducers.test.js │ │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── reducers.js │ │ │ └── selectors.js │ │ ├── reportconfigs.js │ │ ├── reportformats.js │ │ ├── reports.js │ │ ├── reports │ │ │ ├── __tests__ │ │ │ │ └── reducers.test.js │ │ │ └── reducers.js │ │ ├── results.js │ │ ├── roles.js │ │ ├── scanconfigs.js │ │ ├── scanners.js │ │ ├── schedules.js │ │ ├── tags.js │ │ ├── targets.js │ │ ├── tasks.js │ │ ├── tickets.js │ │ ├── tlscertificates.js │ │ ├── users.js │ │ ├── utils │ │ │ ├── __tests__ │ │ │ │ ├── actions.test.js │ │ │ │ ├── main.test.js │ │ │ │ ├── reducers.test.js │ │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── main.js │ │ │ ├── reducers.js │ │ │ ├── selectors.js │ │ │ └── testing.js │ │ └── vulns.js │ ├── feedStatus │ │ ├── __tests__ │ │ │ ├── actions.test.js │ │ │ └── reducers.test.js │ │ ├── actions.js │ │ └── reducers.js │ ├── index.js │ ├── pages │ │ ├── __tests__ │ │ │ ├── actions.test.js │ │ │ ├── reducers.test.js │ │ │ └── selectors.test.js │ │ ├── actions.js │ │ ├── reducers.js │ │ └── selectors.js │ ├── reducers.js │ ├── usersettings │ │ ├── __tests__ │ │ │ ├── actions.test.js │ │ │ ├── reducers.test.js │ │ │ └── selectors.test.js │ │ ├── actions.js │ │ ├── defaultfilters │ │ │ ├── __tests__ │ │ │ │ ├── actions.test.js │ │ │ │ ├── reducers.test.js │ │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── reducers.js │ │ │ └── selectors.js │ │ ├── defaults │ │ │ ├── __tests__ │ │ │ │ ├── actions.test.js │ │ │ │ ├── reducers.test.js │ │ │ │ └── selectors.test.js │ │ │ ├── actions.js │ │ │ ├── reducers.js │ │ │ └── selectors.js │ │ ├── reducers.js │ │ └── selectors.js │ └── utils.js │ ├── testing │ ├── __tests__ │ │ └── screen.test.ts │ ├── actions.ts │ ├── allQueries.ts │ ├── customQueries.ts │ ├── helpers.ts │ ├── index.ts │ ├── screen.ts │ └── within.ts │ ├── utils │ ├── Cert.jsx │ ├── Compose.jsx │ ├── Cpe.jsx │ ├── Languages.jsx │ ├── Os.jsx │ ├── PropTypes.jsx │ ├── Render.jsx │ ├── SelectionType.jsx │ ├── Sort.jsx │ ├── State.jsx │ ├── Testing.tsx │ ├── Theme.tsx │ ├── Urls.jsx │ ├── Warning.jsx │ ├── __tests__ │ │ ├── Render.test.jsx │ │ ├── Sort.test.jsx │ │ ├── severity.tests.ts │ │ └── timePickerHelpers.test.js │ ├── applianceData.js │ ├── severity.ts │ ├── timePickerHelpers.js │ ├── userSettingTimeDateFormatters.js │ ├── withCapabilities.jsx │ ├── withComponentDefaults.jsx │ ├── withGmp.jsx │ ├── withPrefix.jsx │ ├── withRouter.jsx │ ├── withSubscription.jsx │ └── withTranslation.tsx │ └── wizard │ ├── AdvancedTaskWizard.jsx │ ├── ModifyTaskWizard.jsx │ ├── TaskWizard.jsx │ └── __tests__ │ ├── AdvancedTaskWizard.test.jsx │ └── ModifyTaskWizard.test.jsx ├── tsconfig.json ├── vite.config.ts └── vitest.projects.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | build/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # default reviewers 2 | * @greenbone/gea 3 | 4 | # dev ops 5 | .github/ @greenbone/devops @greenbone/gea 6 | .docker/ @greenbone/devops @greenbone/gea 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Greenbone Community Forum 4 | url: https://community.greenbone.net/c/gse 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/workflows/container.yml: -------------------------------------------------------------------------------- 1 | name: Build and Push to Container Image 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - 'v24*' 9 | pull_request: 10 | branches: 11 | - main 12 | workflow_dispatch: 13 | inputs: 14 | ref-name: 15 | type: string 16 | description: 'The ref to build a container image from. For example a tag v23.0.0.' 17 | required: true 18 | 19 | concurrency: 20 | group: ${{ github.workflow }}-${{ github.ref }} 21 | cancel-in-progress: true 22 | 23 | jobs: 24 | build: 25 | name: Build and Push to Greenbone Registry 26 | uses: greenbone/workflows/.github/workflows/container-build-push-2nd-gen.yml@main 27 | with: 28 | image-url: community/gsa 29 | image-labels: | 30 | org.opencontainers.image.vendor=Greenbone 31 | org.opencontainers.image.base.name=greenbone/gsad 32 | ref-name: ${{ inputs.ref-name }} 33 | secrets: inherit 34 | -------------------------------------------------------------------------------- /.github/workflows/conventional-commits.yml: -------------------------------------------------------------------------------- 1 | name: Conventional Commits 2 | 3 | on: 4 | pull_request_target: 5 | 6 | permissions: 7 | pull-requests: write 8 | contents: read 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | conventional-commits: 16 | name: Conventional Commits 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Report Conventional Commits 20 | uses: greenbone/actions/conventional-commits@v3 21 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | name: 'Dependency Review' 2 | on: [pull_request] 3 | 4 | concurrency: 5 | group: ${{ github.workflow }}-${{ github.ref }} 6 | cancel-in-progress: true 7 | 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | 12 | jobs: 13 | dependency-review: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: 'Dependency Review' 17 | uses: greenbone/actions/dependency-review@v3 18 | -------------------------------------------------------------------------------- /.github/workflows/sbom-upload.yml: -------------------------------------------------------------------------------- 1 | name: SBOM upload 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: ["main"] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | SBOM-upload: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | id-token: write 16 | contents: write 17 | steps: 18 | - name: 'SBOM upload' 19 | uses: greenbone/actions/sbom-upload@v3 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | *.local 11 | 12 | dist/ 13 | build/ 14 | coverage/ 15 | node_modules/ 16 | 17 | public/config.js 18 | 19 | .vscode/ 20 | .tern-project 21 | 22 | # directory files for image previews 23 | .directory 24 | 25 | .venv 26 | .eslintcache 27 | -------------------------------------------------------------------------------- /.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable header/header */ 2 | const config = { 3 | arrowParens: 'avoid', 4 | bracketSpacing: false, 5 | jsxSingleQuote: false, 6 | bracketSameLine: false, 7 | semi: true, 8 | singleQuote: true, 9 | tabWidth: 2, 10 | trailingComma: 'all', 11 | }; 12 | 13 | module.exports = config; 14 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Greenbone Security Assistant 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src", 4 | "paths": { 5 | "gmp/*": ["./gmp/*"], 6 | "web/*": ["./web/*"], 7 | "@gsa/testing": ["./testing"] 8 | } 9 | }, 10 | "include": ["src/**/*"], 11 | "exclude": ["build", "coverage", "node_modules"], 12 | "typeAcquisition": { 13 | "enable": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /public/img/cpe/other.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenbone/gsa/7857a19db865eb97b4b027b06e6f3c637f1ba2dd/public/img/favicon.png -------------------------------------------------------------------------------- /public/img/greenbone_banner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenbone/gsa/7857a19db865eb97b4b027b06e6f3c637f1ba2dd/public/img/greenbone_banner.jpeg -------------------------------------------------------------------------------- /public/img/greenbone_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenbone/gsa/7857a19db865eb97b4b027b06e6f3c637f1ba2dd/public/img/greenbone_banner.png -------------------------------------------------------------------------------- /public/img/greenbonehorizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenbone/gsa/7857a19db865eb97b4b027b06e6f3c637f1ba2dd/public/img/greenbonehorizontal.png -------------------------------------------------------------------------------- /public/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenbone/gsa/7857a19db865eb97b4b027b06e6f3c637f1ba2dd/public/img/loading.gif -------------------------------------------------------------------------------- /public/locales/gsa-fr.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /public/locales/gsa-ru.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /public/locales/gsa-tr.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / -------------------------------------------------------------------------------- /src/__tests__/version.test.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import {RELEASE_VERSION} from 'src/version'; 8 | 9 | describe('Version tests', () => { 10 | test('release version should only contain major.minor', () => { 11 | expect(RELEASE_VERSION.split('.').length).toEqual(2); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/gmp/__tests__/timezones.test.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect, expectTypeOf} from '@gsa/testing'; 7 | import timezones from 'gmp/timezones'; 8 | import {isArray} from 'gmp/utils/identity'; 9 | 10 | describe('timezones tests', () => { 11 | test('should be a list of timezone objects', () => { 12 | expect(isArray(timezones)).toEqual(true); 13 | }); 14 | 15 | test('should contain more then one timezone', () => { 16 | expect(timezones.length).toBeGreaterThan(1); 17 | }); 18 | 19 | test('should contain timezones as strings', () => { 20 | for (const zone of timezones) { 21 | expectTypeOf(zone).toBeString(); 22 | } 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/gmp/capabilities/everything.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Capabilities from 'gmp/capabilities/capabilities'; 7 | 8 | class EverythingCapabilities extends Capabilities { 9 | constructor() { 10 | super(['everything']); 11 | } 12 | } 13 | 14 | export default EverythingCapabilities; 15 | -------------------------------------------------------------------------------- /src/gmp/command.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import GmpCommand from 'gmp/commands/gmp'; 7 | 8 | const COMMANDS: Record = {}; 9 | 10 | const registerCommand = (name: string, clazz: typeof GmpCommand) => { 11 | COMMANDS[name] = clazz; 12 | }; 13 | 14 | export const getCommands = () => COMMANDS; 15 | 16 | export default registerCommand; 17 | -------------------------------------------------------------------------------- /src/gmp/commands/__tests__/convert.test.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import {convertBoolean} from 'gmp/commands/convert'; 8 | 9 | describe('convertBoolean tests', () => { 10 | test('should convert true', () => { 11 | expect(convertBoolean(true)).toEqual(1); 12 | }); 13 | 14 | test('should convert false', () => { 15 | expect(convertBoolean(false)).toEqual(0); 16 | }); 17 | 18 | test('should convert to undefined for other value', () => { 19 | expect(convertBoolean('true')).toBeUndefined(); 20 | expect(convertBoolean('false')).toBeUndefined(); 21 | expect(convertBoolean('1')).toBeUndefined(); 22 | expect(convertBoolean('0')).toBeUndefined(); 23 | }); 24 | 25 | test('should convert to legacy 0 and 1 values', () => { 26 | expect(convertBoolean(1)).toEqual(1); 27 | expect(convertBoolean(0)).toEqual(0); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/gmp/commands/__tests__/result.test.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import {ResultCommand} from 'gmp/commands/results'; 8 | import {createEntityResponse, createHttp} from 'gmp/commands/testing'; 9 | 10 | describe('ResultCommand tests', () => { 11 | test('should return single result', () => { 12 | const response = createEntityResponse('result', {_id: 'foo'}); 13 | const fakeHttp = createHttp(response); 14 | 15 | expect.hasAssertions(); 16 | 17 | const cmd = new ResultCommand(fakeHttp); 18 | return cmd.get({id: 'foo'}).then(resp => { 19 | expect(fakeHttp.request).toHaveBeenCalledWith('get', { 20 | args: { 21 | cmd: 'get_result', 22 | result_id: 'foo', 23 | }, 24 | }); 25 | 26 | const {data} = resp; 27 | expect(data.id).toEqual('foo'); 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/gmp/commands/convert.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import logger from 'gmp/log'; 7 | import {trace} from 'gmp/utils/trace'; 8 | 9 | const log = logger.getLogger('gmp.commands.utils'); 10 | 11 | /** 12 | * Convert boolean true/false to API 1/0 values 13 | * 14 | * It converts true to int 1 and false to 0. Converting other values returns 15 | * undefined. 16 | */ 17 | export const convertBoolean = value => { 18 | if (value === true) { 19 | return 1; 20 | } 21 | if (value === false) { 22 | return 0; 23 | } 24 | if (value === 1 || value === 0) { 25 | log.warn('Passed 1 or 0 instead of a true or false', trace()); 26 | return value; 27 | } 28 | return undefined; 29 | }; 30 | -------------------------------------------------------------------------------- /src/gmp/commands/cvsscalculator.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import registerCommand from 'gmp/command'; 7 | import HttpCommand from 'gmp/commands/http'; 8 | import {parseSeverity} from 'gmp/parser'; 9 | 10 | class CvssCalculator extends HttpCommand { 11 | constructor(http) { 12 | super(http, {cmd: 'cvss_calculator'}); 13 | } 14 | 15 | calculateScoreFromVector(cvss_vector) { 16 | return this.httpGet({ 17 | cvss_vector, 18 | }).then(response => { 19 | const {data: envelope} = response; 20 | const score = parseSeverity(envelope.cvss_calculator.cvss_score); 21 | return response.setData(score); 22 | }); 23 | } 24 | } 25 | 26 | registerCommand('cvsscalculator', CvssCalculator); 27 | -------------------------------------------------------------------------------- /src/gmp/commands/infoentity.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import EntityCommand from 'gmp/commands/entity'; 7 | 8 | class InfoEntityCommand extends EntityCommand { 9 | constructor(http, info_type, model) { 10 | super(http, 'info', model); 11 | this.setDefaultParam('info_type', info_type); 12 | this.setDefaultParam('details', '1'); 13 | } 14 | 15 | getElementFromRoot(root) { 16 | /* return the first info element from the response 17 | * the second info element is for the counts */ 18 | return root.get_info.get_info_response.info[0]; 19 | } 20 | } 21 | 22 | export default InfoEntityCommand; 23 | -------------------------------------------------------------------------------- /src/gmp/commands/license.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import registerCommand from 'gmp/command'; 7 | import GMPCommand from 'gmp/commands/gmp'; 8 | import {License} from 'gmp/models/license'; 9 | 10 | export class LicenseCommand extends GMPCommand { 11 | constructor(http) { 12 | super(http, {cmd: 'get_license'}); 13 | } 14 | 15 | getLicenseInformation() { 16 | return this.httpGet().then(response => { 17 | const {data: envelope} = response; 18 | const {get_license_response: licenseResponse} = envelope.get_license; 19 | const license = License.fromElement(licenseResponse.license); 20 | 21 | return response.setData(license); 22 | }); 23 | } 24 | 25 | modifyLicense(file) { 26 | return this.action({ 27 | cmd: 'save_license', 28 | file, 29 | }); 30 | } 31 | } 32 | 33 | registerCommand('license', LicenseCommand); 34 | -------------------------------------------------------------------------------- /src/gmp/commands/nvtfamilies.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import registerCommand from 'gmp/command'; 7 | import GmpCommand from 'gmp/commands/gmp'; 8 | import {parseInt} from 'gmp/parser'; 9 | import {map} from 'gmp/utils/array'; 10 | 11 | export class NvtFamiliesCommand extends GmpCommand { 12 | constructor(http) { 13 | super(http, {cmd: 'get_nvt_families'}); 14 | } 15 | 16 | get(params, options) { 17 | return this.httpGet(params, options).then(response => { 18 | const {data} = response; 19 | const {family: families} = 20 | data.get_nvt_families.get_nvt_families_response.families; 21 | return response.set( 22 | map(families, family => ({ 23 | name: family.name, 24 | maxNvtCount: parseInt(family.max_nvt_count), 25 | })), 26 | ); 27 | }); 28 | } 29 | } 30 | 31 | registerCommand('nvtfamilies', NvtFamiliesCommand); 32 | -------------------------------------------------------------------------------- /src/gmp/http/__tests__/response.test.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import Response from 'gmp/http/response'; 8 | 9 | describe('Response tests', () => { 10 | test('should allow to get plain data', () => { 11 | const xhr = { 12 | response: 'foo', 13 | responseText: 'bar', 14 | responseXML: 'ipsum', 15 | } as unknown as XMLHttpRequest; 16 | const response = new Response(xhr, {}); 17 | 18 | expect(response.plainData()).toEqual('foo'); 19 | expect(response.plainData('text')).toEqual('bar'); 20 | expect(response.plainData('xml')).toEqual('ipsum'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /src/gmp/http/transform/default.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | const noop = (arg: T): T => arg; 7 | 8 | const noopObject = { 9 | success: noop, 10 | rejection: noop, 11 | }; 12 | 13 | export default noopObject; 14 | -------------------------------------------------------------------------------- /src/gmp/index.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Gmp from 'gmp/gmp'; 7 | 8 | export default Gmp; 9 | -------------------------------------------------------------------------------- /src/gmp/locale/index.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {_} from 'gmp/locale/lang'; 7 | 8 | export default _; 9 | -------------------------------------------------------------------------------- /src/gmp/locale/languages.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const BROWSER_LANGUAGE = 'Browser Language'; 7 | 8 | export const getLanguageCodes = () => Object.keys(Languages); 9 | 10 | const Languages = { 11 | de: { 12 | name: 'German', 13 | native_name: 'Deutsch', 14 | }, 15 | en: { 16 | name: 'English', 17 | native_name: 'English', 18 | }, 19 | zh_TW: { 20 | name: 'Traditional Chinese', 21 | native_name: '繁體中文', 22 | }, 23 | } as const; 24 | 25 | export default Languages; 26 | -------------------------------------------------------------------------------- /src/gmp/models/__tests__/asset.test.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Asset from 'gmp/models/asset'; 7 | import {testModel} from 'gmp/models/testing'; 8 | 9 | testModel(Asset, 'asset'); 10 | -------------------------------------------------------------------------------- /src/gmp/models/__tests__/info.test.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Info from 'gmp/models/info'; 7 | import {testModel} from 'gmp/models/testing'; 8 | 9 | testModel(Info, 'info'); 10 | -------------------------------------------------------------------------------- /src/gmp/models/__tests__/vulnerability.test.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {testModel} from 'gmp/models/testing'; 7 | import Vulnerability from 'gmp/models/vulnerability'; 8 | 9 | testModel(Vulnerability, 'vulnerability'); 10 | -------------------------------------------------------------------------------- /src/gmp/models/actionresult.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {Element} from 'gmp/model'; 7 | 8 | interface ActionResultElement extends Element { 9 | action_result: { 10 | id: string; 11 | action: string; 12 | message: string; 13 | }; 14 | } 15 | 16 | class ActionResult { 17 | readonly action: string; 18 | readonly id: string; 19 | readonly message: string; 20 | 21 | constructor(elem: Element) { 22 | const {action_result: result} = elem as ActionResultElement; 23 | 24 | this.id = result.id; 25 | this.action = result.action; 26 | this.message = result.message; 27 | } 28 | } 29 | 30 | export default ActionResult; 31 | -------------------------------------------------------------------------------- /src/gmp/models/asset.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model'; 7 | 8 | class Asset extends Model { 9 | static entityType = 'asset'; 10 | } 11 | 12 | export default Asset; 13 | -------------------------------------------------------------------------------- /src/gmp/models/filter/keywords.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const EXTRA_KEYWORDS = [ 7 | 'apply_overrides', 8 | 'compliance_levels', 9 | 'delta_states', 10 | 'first', 11 | 'levels', 12 | 'min_qod', 13 | 'notes', 14 | 'overrides', 15 | 'report_compliance_levels', 16 | 'result_hosts_only', 17 | 'rows', 18 | 'solution_type', 19 | 'sort', 20 | 'sort-reverse', 21 | 'timezone', 22 | ]; 23 | -------------------------------------------------------------------------------- /src/gmp/models/filter/utils.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Filter from 'gmp/models/filter'; 7 | import {isDefined} from 'gmp/utils/identity'; 8 | 9 | export const isFilter = (filter?: Filter | string | number): filter is Filter => 10 | isDefined((filter as Filter)?.toFilterString); 11 | 12 | export const filterString = (filter?: Filter | number | string) => 13 | isFilter(filter) ? filter.toFilterString() : String(filter); 14 | -------------------------------------------------------------------------------- /src/gmp/models/group.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model'; 7 | import {parseCsv} from 'gmp/parser'; 8 | 9 | class Group extends Model { 10 | static entityType = 'group'; 11 | 12 | static parseElement(element) { 13 | const ret = super.parseElement(element); 14 | 15 | ret.users = parseCsv(element.users); 16 | 17 | return ret; 18 | } 19 | } 20 | 21 | export default Group; 22 | -------------------------------------------------------------------------------- /src/gmp/models/info.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model.js'; 7 | import {isDefined} from 'gmp/utils/identity'; 8 | 9 | class Info extends Model { 10 | static entityType = 'info'; 11 | 12 | static parseElement(elem, infoType) { 13 | const info_elem = elem[infoType]; 14 | 15 | if (isDefined(info_elem)) { 16 | // elem is an info element content is in its child 17 | elem = { 18 | ...elem, 19 | ...info_elem, 20 | }; 21 | 22 | delete elem[infoType]; 23 | } 24 | 25 | return super.parseElement(elem); 26 | } 27 | } 28 | 29 | export default Info; 30 | -------------------------------------------------------------------------------- /src/gmp/models/resourcename.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {isDefined} from 'gmp/utils/identity'; 7 | 8 | export class ResourceName { 9 | constructor({id, name, type}) { 10 | this.id = id; 11 | this.name = name; 12 | this.type = type; 13 | } 14 | 15 | static fromElement(element, type) { 16 | const {_id, name} = element; 17 | 18 | return new ResourceName({ 19 | id: isDefined(_id) ? _id : '', 20 | name: isDefined(name) ? name : '', 21 | type: type, 22 | }); 23 | } 24 | } 25 | 26 | export default ResourceName; 27 | -------------------------------------------------------------------------------- /src/gmp/models/role.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model'; 7 | import {parseCsv} from 'gmp/parser'; 8 | 9 | class Role extends Model { 10 | static entityType = 'role'; 11 | 12 | static parseElement(element) { 13 | const ret = super.parseElement(element); 14 | 15 | ret.users = parseCsv(element.users); 16 | 17 | return ret; 18 | } 19 | } 20 | 21 | export default Role; 22 | -------------------------------------------------------------------------------- /src/gmp/models/settings.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {isDefined} from 'gmp/utils/identity'; 7 | 8 | class Settings { 9 | private readonly _settings: Record; 10 | 11 | constructor() { 12 | this._settings = {}; 13 | } 14 | 15 | has(name: string) { 16 | return name in this._settings; 17 | } 18 | 19 | set(name: string, value: unknown) { 20 | this._settings[name] = value; 21 | } 22 | 23 | get(name: string) { 24 | const setting = this._settings[name]; 25 | if (isDefined(setting)) { 26 | return setting; 27 | } 28 | return {}; 29 | } 30 | 31 | getEntries() { 32 | return Object.entries(this._settings); 33 | } 34 | } 35 | 36 | export default Settings; 37 | -------------------------------------------------------------------------------- /src/gmp/models/tag.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model'; 7 | import {parseInt} from 'gmp/parser'; 8 | import {normalizeType} from 'gmp/utils/entitytype'; 9 | import {isDefined} from 'gmp/utils/identity'; 10 | import {isEmpty} from 'gmp/utils/string'; 11 | 12 | class Tag extends Model { 13 | static entityType = 'tag'; 14 | 15 | static parseElement(element) { 16 | const ret = super.parseElement(element); 17 | 18 | if (isDefined(element.resources)) { 19 | ret.resourceType = normalizeType(element.resources.type); 20 | ret.resourceCount = parseInt(element.resources.count.total); 21 | } else { 22 | ret.resourceCount = 0; 23 | } 24 | ret.value = isEmpty(element.value) ? undefined : element.value; 25 | 26 | return ret; 27 | } 28 | } 29 | 30 | export default Tag; 31 | -------------------------------------------------------------------------------- /src/gmp/models/vulnerability.js: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Model from 'gmp/model'; 7 | import {parseDate} from 'gmp/parser'; 8 | import {isDefined} from 'gmp/utils/identity'; 9 | 10 | class Vulnerability extends Model { 11 | static entityType = 'vulnerability'; 12 | 13 | static parseElement(element) { 14 | const ret = super.parseElement(element); 15 | 16 | if (isDefined(ret.results)) { 17 | ret.results.newest = parseDate(ret.results.newest); 18 | ret.results.oldest = parseDate(ret.results.oldest); 19 | } 20 | 21 | return ret; 22 | } 23 | } 24 | 25 | export default Vulnerability; 26 | -------------------------------------------------------------------------------- /src/gmp/setupTests.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | // eslint-disable-next-line no-restricted-imports 7 | import '../setupTests'; 8 | -------------------------------------------------------------------------------- /src/gmp/utils/__tests__/number.test.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import {severityValue} from 'gmp/utils/number'; 8 | 9 | describe('severityValue function tests', () => { 10 | test('should convert numbers to severity', () => { 11 | expect(severityValue(0)).toEqual('0.0'); 12 | expect(severityValue(1)).toEqual('1.0'); 13 | expect(severityValue(1.0)).toEqual('1.0'); 14 | expect(severityValue(1.1)).toEqual('1.1'); 15 | expect(severityValue(1.1)).toEqual('1.1'); 16 | expect(severityValue(1.15)).toEqual('1.1'); 17 | expect(severityValue(1.16)).toEqual('1.2'); 18 | expect(severityValue(1.19)).toEqual('1.2'); 19 | expect(severityValue(undefined)).toBeUndefined(); 20 | expect(severityValue('A')).toBeUndefined(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /src/gmp/utils/object.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | type ExcludeFunc = (key: string) => boolean; 7 | 8 | export const exclude = (object: {}, func: ExcludeFunc) => 9 | Object.keys(object) 10 | .filter(key => !func(key)) 11 | .reduce((obj, key) => { 12 | obj[key] = object[key]; 13 | return obj; 14 | }, {}); 15 | 16 | export const excludeObjectProps = (object: {}, excludeArray: string[]) => 17 | exclude(object, key => excludeArray.includes(key)); 18 | -------------------------------------------------------------------------------- /src/gmp/utils/severity.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2025 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const SEVERITY_RATING_CVSS_2 = 'CVSSv2'; 7 | export const SEVERITY_RATING_CVSS_3 = 'CVSSv3'; 8 | export const DEFAULT_SEVERITY_RATING = SEVERITY_RATING_CVSS_2; 9 | 10 | export type SeverityRating = 11 | | typeof SEVERITY_RATING_CVSS_2 12 | | typeof SEVERITY_RATING_CVSS_3; 13 | -------------------------------------------------------------------------------- /src/gmp/utils/trace.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** Return the current stack trace a string */ 7 | export const trace = () => { 8 | try { 9 | throw Error(); 10 | } catch (e) { 11 | return (e as Error).stack; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {createRoot} from 'react-dom/client'; 7 | import {StyleSheetManager} from 'styled-components'; 8 | import App from 'web/App'; 9 | 10 | const root = createRoot(document.getElementById('app') as HTMLElement); 11 | root.render( 12 | 13 | 14 | , 15 | ); 16 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {initLocale} from 'gmp/locale/lang'; 7 | import I18NextHttpBackend from 'i18next-http-backend'; 8 | 9 | class FakeBackend { 10 | static type = 'backend'; 11 | 12 | read(language, namespace, callback) { 13 | if (language.startsWith('en') || language.startsWith('de')) { 14 | // change language by calling the callback function 15 | return callback(); 16 | } 17 | // change language and pass error message 18 | return callback('Unknown lang'); 19 | } 20 | } 21 | 22 | class FakeLanguageDetector { 23 | static type = 'languageDetector'; 24 | 25 | init() {} 26 | 27 | detect() { 28 | return 'en'; 29 | } 30 | 31 | cacheUserLanguage() {} 32 | } 33 | 34 | void initLocale({ 35 | backend: FakeBackend as typeof I18NextHttpBackend, 36 | detector: FakeLanguageDetector, 37 | }); 38 | -------------------------------------------------------------------------------- /src/testing.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {vi} from 'vitest'; 7 | 8 | export * from 'vitest'; 9 | 10 | // alternatively for jest 11 | // export * from '@jest/globals'; 12 | 13 | export {vi as testing}; 14 | -------------------------------------------------------------------------------- /src/version.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | const getMajorMinorVersion = () => { 7 | let [major, minor] = VERSION.split('.'); 8 | const minorVersion = parseInt(minor); 9 | if (minorVersion < 10) { 10 | // add a leading zero for the links 11 | minor = `0${minorVersion}`; 12 | } 13 | return `${major}.${minor}`; 14 | }; 15 | 16 | export const VERSION = '25.0.1-dev1'; 17 | 18 | export const RELEASE_VERSION = getMajorMinorVersion(); 19 | 20 | export default VERSION; 21 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | // eslint-disable-next-line header/header 5 | -------------------------------------------------------------------------------- /src/web/components/bar/Toolbar.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import React from 'react'; 7 | import Layout from 'web/components/layout/Layout'; 8 | import IconSizeProvider from 'web/components/provider/IconSizeProvider'; 9 | 10 | const Toolbar = props => { 11 | return ( 12 | 13 | 19 | 20 | ); 21 | }; 22 | 23 | export default Toolbar; 24 | -------------------------------------------------------------------------------- /src/web/components/bar/__tests__/Toolbar.test.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import Toolbar from 'web/components/bar/Toolbar'; 8 | import {render} from 'web/utils/Testing'; 9 | 10 | describe('Toolbar tests', () => { 11 | test('should render', () => { 12 | const {element} = render(); 13 | 14 | expect(element).toMatchSnapshot(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/web/components/bar/__tests__/__snapshots__/Toolbar.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Toolbar tests > should render 1`] = ` 4 | .c0 { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-flex-direction: row; 10 | -ms-flex-direction: row; 11 | flex-direction: row; 12 | -webkit-box-pack: justify; 13 | -webkit-justify-content: space-between; 14 | justify-content: space-between; 15 | -webkit-align-items: flex-start; 16 | -webkit-box-align: flex-start; 17 | -ms-flex-align: flex-start; 18 | align-items: flex-start; 19 | } 20 | 21 |
24 | `; 25 | -------------------------------------------------------------------------------- /src/web/components/bar/__tests__/__snapshots__/toolbar.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Toolbar tests > should render 1`] = ` 4 | .c0 { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-flex-direction: row; 10 | -ms-flex-direction: row; 11 | flex-direction: row; 12 | -webkit-box-pack: justify; 13 | -webkit-justify-content: space-between; 14 | justify-content: space-between; 15 | -webkit-align-items: flex-start; 16 | -webkit-box-align: flex-start; 17 | -ms-flex-align: flex-start; 18 | align-items: flex-start; 19 | } 20 | 21 |
24 | `; 25 | -------------------------------------------------------------------------------- /src/web/components/chart/Group.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {isDefined} from 'gmp/utils/identity'; 7 | import React from 'react'; 8 | import styled from 'styled-components'; 9 | import PropTypes from 'web/utils/PropTypes'; 10 | 11 | const StyledGroup = styled.g` 12 | ${props => 13 | isDefined(props.onClick) 14 | ? { 15 | cursor: 'pointer', 16 | } 17 | : undefined}; 18 | `; 19 | 20 | const Group = ({left = 0, top = 0, scale = 1, ...props}) => ( 21 | 25 | ); 26 | 27 | Group.propTypes = { 28 | left: PropTypes.number, 29 | scale: PropTypes.number, 30 | top: PropTypes.number, 31 | }; 32 | 33 | export default Group; 34 | -------------------------------------------------------------------------------- /src/web/components/chart/Label.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import React from 'react'; 7 | import PropTypes from 'web/utils/PropTypes'; 8 | import Theme from 'web/utils/Theme'; 9 | 10 | const Label = React.forwardRef(({x, y, children, ...props}, ref) => ( 11 | 23 | {children} 24 | 25 | )); 26 | 27 | Label.propTypes = { 28 | x: PropTypes.number.isRequired, 29 | y: PropTypes.number.isRequired, 30 | }; 31 | 32 | export default Label; 33 | -------------------------------------------------------------------------------- /src/web/components/chart/Svg.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | 8 | const Svg = styled.svg` 9 | overflow: visible; 10 | & text { 11 | user-select: none; 12 | } 13 | `; 14 | 15 | export default Svg; 16 | -------------------------------------------------------------------------------- /src/web/components/chart/donut/PropTypes.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import PropTypes from 'web/utils/PropTypes'; 7 | 8 | export const ArcDataPropType = PropTypes.shape({ 9 | color: PropTypes.toString.isRequired, 10 | value: PropTypes.numberOrNumberString.isRequired, 11 | label: PropTypes.any, 12 | toolTip: PropTypes.elementOrString, 13 | }); 14 | 15 | export const DataPropType = PropTypes.arrayOf(ArcDataPropType); 16 | -------------------------------------------------------------------------------- /src/web/components/chart/utils/Constants.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const MENU_PLACEHOLDER_WIDTH = 26; 7 | -------------------------------------------------------------------------------- /src/web/components/chart/utils/Update.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** 7 | * Default implementation for checking if a chart component must be updated 8 | * 9 | * A chart must always be re-rendered if data, width or height has changed. 10 | * 11 | * @param {Object} nextProps Next props to be set 12 | * @param {Object} props Current set props 13 | * 14 | * @returns {Boolean} true if the chart component must be re-rendered 15 | */ 16 | export const shouldUpdate = (nextProps, props) => 17 | nextProps.data !== props.data || 18 | nextProps.width !== props.width || 19 | nextProps.height !== props.height || 20 | nextProps.showLegend !== props.showLegend; 21 | -------------------------------------------------------------------------------- /src/web/components/comment/Comment.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {isDefined} from 'gmp/utils/identity'; 7 | import React from 'react'; 8 | import PropTypes from 'web/utils/PropTypes'; 9 | 10 | const Comment = ({text, children}) => { 11 | if (!isDefined(text)) { 12 | text = children; 13 | } 14 | 15 | if (!isDefined(text)) { 16 | return null; 17 | } 18 | return ( 19 |
20 | {text} 21 |
22 | ); 23 | }; 24 | 25 | Comment.propTypes = { 26 | text: PropTypes.string, 27 | }; 28 | 29 | export default Comment; 30 | -------------------------------------------------------------------------------- /src/web/components/comment/__tests__/Comment.test.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import Comment from 'web/components/comment/Comment'; 8 | import {render} from 'web/utils/Testing'; 9 | 10 | describe('Comment tests', () => { 11 | test('should render children', () => { 12 | const {element} = render(Hello World); 13 | 14 | expect(element).toHaveTextContent('Hello World'); 15 | }); 16 | 17 | test('should render comment with text', () => { 18 | const {element} = render( 19 | Should not be rendered, 20 | ); 21 | 22 | expect(element).toHaveTextContent('Hello World'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/web/components/conditionalRoute/ConditionalRoute.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import PropTypes from 'prop-types'; 7 | import {Navigate} from 'react-router'; 8 | import useCapabilities from 'web/hooks/useCapabilities'; 9 | 10 | const ConditionalRoute = ({component: Component, feature, ...rest}) => { 11 | const capabilities = useCapabilities(); 12 | const isEnabled = capabilities.featureEnabled(feature); 13 | 14 | return ( 15 | <>{isEnabled ? : } 16 | ); 17 | }; 18 | 19 | ConditionalRoute.propTypes = { 20 | component: PropTypes.elementType.isRequired, 21 | feature: PropTypes.string.isRequired, 22 | }; 23 | 24 | export default ConditionalRoute; 25 | -------------------------------------------------------------------------------- /src/web/components/dashboard/display/created/CreatedTransform.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {parseInt, parseDate} from 'gmp/parser'; 7 | import {formattedUserSettingShortDate} from 'web/utils/userSettingTimeDateFormatters'; 8 | 9 | const transformCreated = (data = {}) => { 10 | const {groups = []} = data; 11 | return groups.map(group => { 12 | const {value, count, c_count} = group; 13 | const createdDate = parseDate(value); 14 | return { 15 | x: createdDate, 16 | label: formattedUserSettingShortDate(createdDate), 17 | y: parseInt(count), 18 | y2: parseInt(c_count), 19 | }; 20 | }); 21 | }; 22 | 23 | export default transformCreated; 24 | -------------------------------------------------------------------------------- /src/web/components/dashboard/display/cvss/CvssTableDisplay.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import transformCvssData, { 7 | cvssDataRow, 8 | } from 'web/components/dashboard/display/cvss/cvssTransform'; 9 | import DataTableDisplay from 'web/components/dashboard/display/DataTableDisplay'; 10 | import useGmp from 'web/hooks/useGmp'; 11 | 12 | const CvssTableDisplay = props => { 13 | const gmp = useGmp(); 14 | const severityRating = gmp.settings.severityRating; 15 | return ( 16 | 22 | ); 23 | }; 24 | 25 | export default CvssTableDisplay; 26 | -------------------------------------------------------------------------------- /src/web/components/dashboard/display/severity/SeverityClassTableDisplay.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import DataTableDisplay from 'web/components/dashboard/display/DataDisplay'; 7 | import transformSeverityClassData from 'web/components/dashboard/display/severity/severityClassTransform'; 8 | 9 | const severityClassDataRow = row => [row.label, row.value]; 10 | 11 | const SeverityClassTableDisplay = props => ( 12 | 17 | ); 18 | 19 | export default SeverityClassTableDisplay; 20 | -------------------------------------------------------------------------------- /src/web/components/dialog/Content.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | 8 | const DialogContent = styled.div` 9 | display: flex; 10 | flex-direction: column; 11 | height: inherit; 12 | padding: 0; 13 | gap: 20px; 14 | white-space: pre-line; 15 | `; 16 | 17 | export default DialogContent; 18 | -------------------------------------------------------------------------------- /src/web/components/dialog/DialogInlineNotification.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | 8 | const DialogInlineNotification = styled.div` 9 | font-size: 14px; 10 | margin-bottom: 0px; 11 | display: flex; 12 | justify-content: center; 13 | `; 14 | 15 | export default DialogInlineNotification; 16 | -------------------------------------------------------------------------------- /src/web/components/error/ErrorContainer.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | import Layout from 'web/components/layout/Layout'; 8 | import Theme from 'web/utils/Theme'; 9 | 10 | const ErrorContainer = styled(Layout)` 11 | padding: 15px; 12 | margin: 15px 15px 15px 15px; 13 | border: 1px solid ${Theme.mediumLightRed}; 14 | background-color: ${Theme.lightRed}; 15 | `; 16 | 17 | export default ErrorContainer; 18 | -------------------------------------------------------------------------------- /src/web/components/error/MessageContainer.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | import Layout from 'web/components/layout/Layout'; 8 | 9 | const MessageContainer = styled(Layout)` 10 | padding: 15px; 11 | margin: 15px 15px 15px 15px; 12 | border: 1px solid; 13 | `; 14 | 15 | export default MessageContainer; 16 | -------------------------------------------------------------------------------- /src/web/components/error/__tests__/ErrorContainer.test.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import ErrorContainer from 'web/components/error/ErrorContainer'; 8 | import {render} from 'web/utils/Testing'; 9 | 10 | describe('ErrorContainer tests', () => { 11 | test('should render', () => { 12 | const {element} = render( 13 | 14 | An error 15 | , 16 | ); 17 | 18 | expect(element).toBeVisible(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /src/web/components/footnote/Footnote.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | import Layout from 'web/components/layout/Layout'; 8 | import Theme from 'web/utils/Theme'; 9 | 10 | const FootNote = styled(Layout)` 11 | font-size: 10px; 12 | color: ${Theme.mediumGray}; 13 | text-align: left; 14 | `; 15 | 16 | export default FootNote; 17 | -------------------------------------------------------------------------------- /src/web/components/footnote/__tests__/Footnote.test.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {describe, test, expect} from '@gsa/testing'; 7 | import FootNote from 'web/components/footnote/Footnote'; 8 | import {render} from 'web/utils/Testing'; 9 | 10 | describe('Footnote tests', () => { 11 | test('should render footnote', () => { 12 | const {element} = render(); 13 | 14 | expect(element).toMatchSnapshot(); 15 | }); 16 | 17 | test('should render children', () => { 18 | const {element} = render(Hello World); 19 | 20 | expect(element).toHaveTextContent('Hello World'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /src/web/components/footnote/__tests__/__snapshots__/Footnote.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Footnote tests > should render footnote 1`] = ` 4 | .c0 { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-flex-direction: row; 10 | -ms-flex-direction: row; 11 | flex-direction: row; 12 | -webkit-box-pack: start; 13 | -ms-flex-pack: start; 14 | -webkit-justify-content: start; 15 | justify-content: start; 16 | -webkit-align-items: center; 17 | -webkit-box-align: center; 18 | -ms-flex-align: center; 19 | align-items: center; 20 | } 21 | 22 | .c1 { 23 | font-size: 10px; 24 | color: #7F7F7F; 25 | text-align: left; 26 | } 27 | 28 |
31 | `; 32 | -------------------------------------------------------------------------------- /src/web/components/footnote/__tests__/__snapshots__/footnote.test.jsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Footnote tests > should render footnote 1`] = ` 4 | .c0 { 5 | display: -webkit-box; 6 | display: -webkit-flex; 7 | display: -ms-flexbox; 8 | display: flex; 9 | -webkit-flex-direction: row; 10 | -ms-flex-direction: row; 11 | flex-direction: row; 12 | -webkit-box-pack: start; 13 | -ms-flex-pack: start; 14 | -webkit-justify-content: start; 15 | justify-content: start; 16 | -webkit-align-items: center; 17 | -webkit-box-align: center; 18 | -ms-flex-align: center; 19 | align-items: center; 20 | } 21 | 22 | .c1 { 23 | font-size: 10px; 24 | color: #7F7F7F; 25 | text-align: left; 26 | } 27 | 28 |
31 | `; 32 | -------------------------------------------------------------------------------- /src/web/components/form/ErrorMarker.tsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | import Theme from 'web/utils/Theme'; 8 | 9 | interface StyledMarkerProps { 10 | $isVisible?: boolean; 11 | } 12 | 13 | const StyledMarker = styled.div` 14 | color: ${Theme.darkRed}; 15 | font-weight: bold; 16 | font-size: 19px; 17 | padding-bottom: 1px; 18 | padding-left: 4px; 19 | display: ${props => (props.$isVisible ? 'inline' : 'none')}; 20 | `; 21 | 22 | const ErrorMarker = ({isVisible}) => ( 23 | 24 | × 25 | 26 | ); 27 | 28 | export default ErrorMarker; 29 | -------------------------------------------------------------------------------- /src/web/components/form/Spinner.tsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {forwardRef} from 'react'; 7 | import NumberField, {NumberFieldProps} from 'web/components/form/NumberField'; 8 | 9 | interface SpinnerProps 10 | extends Omit< 11 | NumberFieldProps, 12 | 'fixedDecimalScale' | 'hideControls' | 'onChange' | 'value' | 'allowEmpty' 13 | > { 14 | value?: number; 15 | onChange?: (value: number, name?: string) => void; 16 | } 17 | 18 | const Spinner = forwardRef( 19 | ({onChange, type = 'int', ...props}, ref) => ( 20 | 29 | ), 30 | ); 31 | export default Spinner; 32 | -------------------------------------------------------------------------------- /src/web/components/form/TimeZoneSelect.tsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import timezones, {DEFAULT_TIMEZONE} from 'gmp/timezones'; 7 | import {useMemo} from 'react'; 8 | import Select, {SelectProps} from 'web/components/form/Select'; 9 | 10 | interface TimeZoneSelectProps extends Omit { 11 | value?: string; 12 | } 13 | 14 | const TimeZoneSelectComponent = ({ 15 | value = DEFAULT_TIMEZONE, 16 | ...props 17 | }: TimeZoneSelectProps) => { 18 | const timezoneItems = useMemo( 19 | () => 20 | timezones.map(name => ({ 21 | label: name, 22 | value: name, 23 | })), 24 | [], 25 | ); 26 | 27 | return ({ 14 | label: `${name} (${value})`, 15 | value: value, 16 | }))} 17 | label={`${metric.name} (${metricShort})`} 18 | name={metricShort} 19 | value={selectedOptions[metricShort]} 20 | onChange={handleOptionChange} 21 | /> 22 | 23 | ); 24 | }); 25 | }; 26 | 27 | export default Metrics; 28 | -------------------------------------------------------------------------------- /src/web/pages/groups/Table.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {_l} from 'gmp/locale/lang'; 7 | import {createEntitiesFooter} from 'web/entities/Footer'; 8 | import {createEntitiesTable} from 'web/entities/Table'; 9 | import withRowDetails from 'web/entities/withRowDetails'; 10 | import GroupDetails from 'web/pages/groups/Details'; 11 | import Header from 'web/pages/groups/Header'; 12 | import Row from 'web/pages/groups/Row'; 13 | 14 | export const SORT_FIELDS = [ 15 | { 16 | name: 'name', 17 | displayName: _l('Name'), 18 | }, 19 | ]; 20 | 21 | const GroupsTable = createEntitiesTable({ 22 | emptyTitle: _l('No Groups available'), 23 | header: Header, 24 | row: Row, 25 | rowDetails: withRowDetails('group')(GroupDetails), 26 | footer: createEntitiesFooter({ 27 | download: 'groups.xml', 28 | span: 7, 29 | trash: true, 30 | }), 31 | }); 32 | 33 | export default GroupsTable; 34 | -------------------------------------------------------------------------------- /src/web/pages/hosts/Details.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import React from 'react'; 7 | import Layout from 'web/components/layout/Layout'; 8 | import Identifiers from 'web/pages/hosts/Identifiers'; 9 | import PropTypes from 'web/utils/PropTypes'; 10 | 11 | const HostDetails = ({entity, onHostIdentifierDeleteClick}) => { 12 | const {identifiers} = entity; 13 | return ( 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | HostDetails.propTypes = { 25 | entity: PropTypes.model.isRequired, 26 | onHostIdentifierDeleteClick: PropTypes.func, 27 | }; 28 | 29 | export default HostDetails; 30 | -------------------------------------------------------------------------------- /src/web/pages/nvts/Preformatted.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import styled from 'styled-components'; 7 | 8 | /* 9 | nvt tags should preserve newlines 10 | whitespaces can be collapsed 11 | */ 12 | const Preformatted = styled.div` 13 | white-space: pre-line; 14 | `; 15 | 16 | export default Preformatted; 17 | -------------------------------------------------------------------------------- /src/web/pages/operatingsystems/Component.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import React from 'react'; 7 | import EntityComponent from 'web/entity/EntityComponent'; 8 | 9 | const OsComponent = props => ( 10 | 11 | ); 12 | 13 | export default OsComponent; 14 | -------------------------------------------------------------------------------- /src/web/pages/performance/durations.ts: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2025 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const DURATION_HOUR = 60 * 60; 7 | export const DURATION_DAY = DURATION_HOUR * 24; 8 | export const DURATION_WEEK = DURATION_DAY * 7; 9 | export const DURATION_MONTH = DURATION_DAY * 31; 10 | export const DURATION_YEAR = DURATION_DAY * 365; 11 | 12 | const DURATIONS = { 13 | hour: DURATION_HOUR, 14 | day: DURATION_DAY, 15 | week: DURATION_WEEK, 16 | month: DURATION_MONTH, 17 | year: DURATION_YEAR, 18 | } as const; 19 | 20 | export type Duration = keyof typeof DURATIONS; 21 | 22 | export const getDurationInSeconds = (duration: Duration): number => { 23 | return DURATIONS[duration]; 24 | }; 25 | -------------------------------------------------------------------------------- /src/web/pages/reportconfigs/__mocks__/MockReportFormats.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export const mockReportFormats = [ 7 | { 8 | id: '123456', 9 | name: 'example-configurable-1', 10 | configurable: true, 11 | }, 12 | { 13 | id: '654321', 14 | name: 'non-configurable-1', 15 | configurable: false, 16 | }, 17 | { 18 | id: '1234567', 19 | name: 'example-configurable-2', 20 | configurable: true, 21 | }, 22 | { 23 | id: '7654321', 24 | name: 'non-configurable-2', 25 | configurable: false, 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /src/web/pages/reports/ThresholdMessage.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import React from 'react'; 7 | import ErrorContainer from 'web/components/error/ErrorContainer'; 8 | import useTranslation from 'web/hooks/useTranslation'; 9 | import PropTypes from 'web/utils/PropTypes'; 10 | 11 | const ThresholdMessage = ({threshold}) => { 12 | const [_] = useTranslation(); 13 | 14 | return ( 15 | 16 | {_( 17 | 'WARNING: Please be aware that the report has more results than ' + 18 | 'the threshold of {{threshold}}. Therefore, this action can take ' + 19 | 'a really long time to finish. It might even exceed the session ' + 20 | 'timeout!', 21 | {threshold}, 22 | )} 23 | 24 | ); 25 | }; 26 | 27 | ThresholdMessage.propTypes = { 28 | threshold: PropTypes.number.isRequired, 29 | }; 30 | 31 | export default ThresholdMessage; 32 | -------------------------------------------------------------------------------- /src/web/pages/reports/auditdashboard/Loaders.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Loader, { 7 | loadFunc, 8 | loaderPropTypes, 9 | } from 'web/store/dashboard/data/loader'; 10 | 11 | export const REPORTS_COMPLIANCE = 'reports-compliance'; 12 | 13 | export const reportComplianceLoader = loadFunc( 14 | ({gmp, filter}) => 15 | gmp.auditreports.getComplianceAggregates({filter}).then(r => r.data), 16 | REPORTS_COMPLIANCE, 17 | ); 18 | 19 | export const ReportCompianceLoader = ({children, filter}) => ( 20 | 26 | {children} 27 | 28 | ); 29 | 30 | ReportCompianceLoader.propTypes = loaderPropTypes; 31 | -------------------------------------------------------------------------------- /src/web/pages/results/Delta.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {Delta} from 'gmp/models/result'; 7 | import React from 'react'; 8 | import useTranslation from 'web/hooks/useTranslation'; 9 | import PropTypes from 'web/utils/PropTypes'; 10 | 11 | const ResultDelta = ({delta}) => { 12 | const [_] = useTranslation(); 13 | switch (delta.delta_type) { 14 | case Delta.TYPE_NEW: 15 | return [ + ]; 16 | case Delta.TYPE_CHANGED: 17 | return [ ~ ]; 18 | case Delta.TYPE_GONE: 19 | return [ − ]; 20 | case Delta.TYPE_SAME: 21 | return [ = ]; 22 | default: 23 | return null; 24 | } 25 | }; 26 | 27 | ResultDelta.propTypes = { 28 | delta: PropTypes.object.isRequired, 29 | }; 30 | 31 | export default ResultDelta; 32 | -------------------------------------------------------------------------------- /src/web/pages/roles/Table.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {_l} from 'gmp/locale/lang'; 7 | import {createEntitiesFooter} from 'web/entities/Footer'; 8 | import {createEntitiesTable} from 'web/entities/Table'; 9 | import withRowDetails from 'web/entities/withRowDetails'; 10 | import Header from 'web/pages/groups/Header'; 11 | import RoleDetails from 'web/pages/roles/Details'; 12 | import Row from 'web/pages/roles/Row'; 13 | 14 | export const SORT_FIELDS = [ 15 | { 16 | name: 'name', 17 | displayName: _l('Name'), 18 | width: '92%', 19 | }, 20 | ]; 21 | 22 | const RolesTable = createEntitiesTable({ 23 | emptyTitle: _l('No Roles available'), 24 | header: Header, 25 | row: Row, 26 | rowDetails: withRowDetails('role')(RoleDetails), 27 | footer: createEntitiesFooter({ 28 | download: 'roles.xml', 29 | span: 7, 30 | trash: true, 31 | }), 32 | }); 33 | 34 | export default RolesTable; 35 | -------------------------------------------------------------------------------- /src/web/pages/scanconfigs/Table.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {_l} from 'gmp/locale/lang'; 7 | import {createEntitiesFooter} from 'web/entities/Footer'; 8 | import {createEntitiesTable} from 'web/entities/Table'; 9 | import withRowDetails from 'web/entities/withRowDetails'; 10 | import ScanConfigDetails from 'web/pages/scanconfigs/Details'; 11 | import Header from 'web/pages/scanconfigs/Header'; 12 | import Row from 'web/pages/scanconfigs/Row'; 13 | 14 | const ScanConfigsTable = createEntitiesTable({ 15 | emptyTitle: _l('No Scan Configs available'), 16 | header: Header, 17 | row: Row, 18 | rowDetails: withRowDetails('scanconfig')(ScanConfigDetails), 19 | footer: createEntitiesFooter({ 20 | download: 'scanconfigs.xml', 21 | span: 6, 22 | trash: true, 23 | }), 24 | }); 25 | 26 | export default ScanConfigsTable; 27 | -------------------------------------------------------------------------------- /src/web/pages/schedules/TimeUnitSelect.jsx: -------------------------------------------------------------------------------- 1 | /* SPDX-FileCopyrightText: 2024 Greenbone AG 2 | * 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import {ReccurenceFrequency} from 'gmp/models/event'; 7 | import React from 'react'; 8 | import Select from 'web/components/form/Select'; 9 | import useTranslation from 'web/hooks/useTranslation'; 10 | 11 | const TimeUnitSelect = props => { 12 | const [_] = useTranslation(); 13 | const TIME_UNIT_ITEMS = [ 14 | {value: ReccurenceFrequency.HOURLY, label: _('hour(s)')}, 15 | {value: ReccurenceFrequency.DAILY, label: _('day(s)')}, 16 | {value: ReccurenceFrequency.WEEKLY, label: _('week(s)')}, 17 | {value: ReccurenceFrequency.MONTHLY, label: _('month(s)')}, 18 | {value: ReccurenceFrequency.YEARLY, label: _('year(s)')}, 19 | ]; 20 | 21 | return