From 2a397e01d3bea082f17a215d888d46aaee880130 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Mon, 15 Jul 2024 05:21:17 +0200 Subject: [PATCH 01/12] Implement remote connection checks for remote-reindex migrations (#19879) * Implement remote connection checks for remote-reindex migrations * datanode trust manager for connection checks * Added changelog * fixed forbidden api usage * fixed forbidden apis * fixed forbidden apis #3 --- changelog/unreleased/pr-19879.toml | 4 + .../bindings/OpensearchProcessBindings.java | 3 + .../DatanodeTrustManagerProvider.java | 72 ++++++++++ .../OpensearchConnectionCheckController.java | 130 ++++++++++++++++++ .../graylog/datanode/rest/RestBindings.java | 1 + .../AggregatedConnectionResponse.java | 111 +++++++++++++++ .../opensearch2/ConnectionCheckRequest.java | 22 +++ .../opensearch2/ConnectionCheckResponse.java | 59 ++++++++ .../RemoteReindexingMigrationAdapterOS2.java | 121 +++++++--------- .../datanode/RemoteReindexAllowlistEvent.java | 31 +---- .../datanode/MigrationConfiguration.java | 13 +- .../IndexerConnectionCheckResult.java | 4 + .../RemoteReindexAllowlistEventTest.java | 15 +- ...RemoteReindexMigrationServiceImplTest.java | 5 +- 14 files changed, 491 insertions(+), 100 deletions(-) create mode 100644 changelog/unreleased/pr-19879.toml create mode 100644 data-node/src/main/java/org/graylog/datanode/configuration/DatanodeTrustManagerProvider.java create mode 100644 data-node/src/main/java/org/graylog/datanode/rest/OpensearchConnectionCheckController.java create mode 100644 graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/AggregatedConnectionResponse.java create mode 100644 graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckRequest.java create mode 100644 graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckResponse.java diff --git a/changelog/unreleased/pr-19879.toml b/changelog/unreleased/pr-19879.toml new file mode 100644 index 000000000000..30d9c05fc6c5 --- /dev/null +++ b/changelog/unreleased/pr-19879.toml @@ -0,0 +1,4 @@ +type = "c" +message = "Run remote reindex connection checks from datanodes, aggregate results." + +pulls = ["19879"] diff --git a/data-node/src/main/java/org/graylog/datanode/bindings/OpensearchProcessBindings.java b/data-node/src/main/java/org/graylog/datanode/bindings/OpensearchProcessBindings.java index 6eee4b3f0301..4209d418ce58 100644 --- a/data-node/src/main/java/org/graylog/datanode/bindings/OpensearchProcessBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/bindings/OpensearchProcessBindings.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.Service; import com.google.inject.AbstractModule; import com.google.inject.multibindings.Multibinder; +import org.graylog.datanode.configuration.DatanodeTrustManagerProvider; import org.graylog.datanode.configuration.OpensearchConfigurationService; import org.graylog.datanode.metrics.ConfigureMetricsIndexSettings; import org.graylog.datanode.opensearch.OpensearchProcess; @@ -45,6 +46,8 @@ protected void configure() { serviceBinder.addBinding().to(OpensearchConfigurationService.class).asEagerSingleton(); serviceBinder.addBinding().to(OpensearchProcessService.class).asEagerSingleton(); + bind(DatanodeTrustManagerProvider.class); + // tracer Multibinder tracerBinder = Multibinder.newSetBinder(binder(), StateMachineTracer.class); tracerBinder.addBinding().to(ClusterNodeStateTracer.class).asEagerSingleton(); diff --git a/data-node/src/main/java/org/graylog/datanode/configuration/DatanodeTrustManagerProvider.java b/data-node/src/main/java/org/graylog/datanode/configuration/DatanodeTrustManagerProvider.java new file mode 100644 index 000000000000..c40f9ec5683a --- /dev/null +++ b/data-node/src/main/java/org/graylog/datanode/configuration/DatanodeTrustManagerProvider.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.datanode.configuration; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import org.graylog.datanode.configuration.variants.OpensearchSecurityConfiguration; +import org.graylog.datanode.opensearch.OpensearchConfigurationChangeEvent; +import org.graylog2.security.CustomCAX509TrustManager; +import org.graylog2.security.TrustManagerAggregator; + +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.List; +import java.util.Optional; + +public class DatanodeTrustManagerProvider implements Provider { + + private final CustomCAX509TrustManager customCAX509TrustManager; + private volatile KeyStore datanodeTruststore; + + @Inject + public DatanodeTrustManagerProvider(CustomCAX509TrustManager CustomCAX509TrustManager, EventBus eventBus) { + customCAX509TrustManager = CustomCAX509TrustManager; + eventBus.register(this); + } + + @Subscribe + public void onOpensearchConfigurationChange(OpensearchConfigurationChangeEvent e) { + Optional.ofNullable(e.config().opensearchSecurityConfiguration()) + .flatMap(OpensearchSecurityConfiguration::getTruststore) + .map(t -> { + try { + return t.loadKeystore(); + } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException ex) { + throw new RuntimeException(ex); + } + }) + .ifPresent(this::setTruststore); + } + + private void setTruststore(KeyStore keyStore) { + this.datanodeTruststore = keyStore; + } + + + @Override + public X509TrustManager get() { + final X509TrustManager datanodeTrustManager = TrustManagerAggregator.trustManagerFromKeystore(this.datanodeTruststore); + return new TrustManagerAggregator(List.of(datanodeTrustManager, customCAX509TrustManager)); + } +} diff --git a/data-node/src/main/java/org/graylog/datanode/rest/OpensearchConnectionCheckController.java b/data-node/src/main/java/org/graylog/datanode/rest/OpensearchConnectionCheckController.java new file mode 100644 index 000000000000..96170bb78226 --- /dev/null +++ b/data-node/src/main/java/org/graylog/datanode/rest/OpensearchConnectionCheckController.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.datanode.rest; + +import jakarta.annotation.Nonnull; +import jakarta.inject.Inject; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import okhttp3.Credentials; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import org.graylog.datanode.configuration.DatanodeTrustManagerProvider; +import org.graylog.storage.opensearch2.ConnectionCheckRequest; +import org.graylog.storage.opensearch2.ConnectionCheckResponse; +import org.graylog2.security.TrustAllX509TrustManager; +import org.graylog2.security.untrusted.UntrustedCertificateExtractor; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; + +@Path("/connection-check") +@Produces(MediaType.APPLICATION_JSON) +public class OpensearchConnectionCheckController { + + public static final Duration CONNECT_TIMEOUT = Duration.ofSeconds(10); + public static final Duration WRITE_TIMEOUT = Duration.ofSeconds(10); + public static final Duration READ_TIMEOUT = Duration.ofSeconds(10); + private final DatanodeTrustManagerProvider datanodeTrustManagerProvider; + + private final OkHttpClient httpClient; + + @Inject + public OpensearchConnectionCheckController(DatanodeTrustManagerProvider datanodeTrustManagerProvider) { + this.datanodeTrustManagerProvider = datanodeTrustManagerProvider; + this.httpClient = new OkHttpClient.Builder() + .retryOnConnectionFailure(true) + .connectTimeout(CONNECT_TIMEOUT) + .writeTimeout(WRITE_TIMEOUT) + .readTimeout(READ_TIMEOUT) + .build(); + } + + @POST + @Path("opensearch") + public ConnectionCheckResponse status(ConnectionCheckRequest request) { + final List unknownCertificates = new LinkedList<>(); + try { + unknownCertificates.addAll(extractUnknownCertificates(request.host())); + final List indices = getAllIndicesFrom(request.host(), request.username(), request.password(), request.trustUnknownCerts()); + return ConnectionCheckResponse.success(indices, unknownCertificates); + } catch (Exception e) { + return ConnectionCheckResponse.error(e, unknownCertificates); + } + } + + List getAllIndicesFrom(final String host, final String username, final String password, boolean trustUnknownCerts) { + var url = (host.endsWith("/") ? host : host + "/") + "_cat/indices?h=index"; + try (var response = getClient(trustUnknownCerts).newCall(new Request.Builder().url(url).header("Authorization", Credentials.basic(username, password)).build()).execute()) { + if (response.isSuccessful() && response.body() != null) { + // filtering all indices that start with "." as they indicate a system index - we don't want to reindex those + return new BufferedReader(new StringReader(response.body().string())).lines().filter(i -> !i.startsWith(".")).sorted().toList(); + } else { + String message = String.format(Locale.ROOT, "Could not read list of indices from %s. Code=%d, message=%s", host, response.code(), response.message()); + throw new RuntimeException(message); + } + } catch (IOException e) { + throw new RuntimeException("Could not read list of indices from " + host + ", " + e.getMessage(), e); + } + } + + + private OkHttpClient getClient(boolean trustUnknownCerts) { + try { + final SSLContext ctx = SSLContext.getInstance("TLS"); + final X509TrustManager trustManager = getTrustManager(trustUnknownCerts); + ctx.init(null, new TrustManager[]{trustManager}, new SecureRandom()); + return httpClient.newBuilder().sslSocketFactory(ctx.getSocketFactory(), trustManager).build(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + throw new RuntimeException(e); + + } + } + + @Nonnull + private X509TrustManager getTrustManager(boolean trustUnknownCerts) { + if (trustUnknownCerts) { + return new TrustAllX509TrustManager(); + } else { + return datanodeTrustManagerProvider.get(); + } + } + + @Nonnull + private List extractUnknownCertificates(String host) { + final UntrustedCertificateExtractor extractor = new UntrustedCertificateExtractor(httpClient); + try { + return extractor.extractUntrustedCerts(host); + } catch (NoSuchAlgorithmException | IOException | KeyManagementException e) { + throw new RuntimeException(e); + } + } +} diff --git a/data-node/src/main/java/org/graylog/datanode/rest/RestBindings.java b/data-node/src/main/java/org/graylog/datanode/rest/RestBindings.java index bbc396b9c8a3..2cc6e83e64c4 100644 --- a/data-node/src/main/java/org/graylog/datanode/rest/RestBindings.java +++ b/data-node/src/main/java/org/graylog/datanode/rest/RestBindings.java @@ -25,5 +25,6 @@ protected void configure() { addSystemRestResource(LogsController.class); addSystemRestResource(ManagementController.class); addSystemRestResource(IndicesDirectoryController.class); + addSystemRestResource(OpensearchConnectionCheckController.class); } } diff --git a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/AggregatedConnectionResponse.java b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/AggregatedConnectionResponse.java new file mode 100644 index 000000000000..4195f14d88c5 --- /dev/null +++ b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/AggregatedConnectionResponse.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.storage.opensearch2; + +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.openssl.PEMParser; + +import javax.xml.bind.DatatypeConverter; +import java.io.IOException; +import java.io.StringReader; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +public record AggregatedConnectionResponse(Map responses) { + public List indices() { + return responses.values().stream().flatMap(v -> v.indices().stream()).sorted(Comparator.naturalOrder()).collect(Collectors.toList()); + } + + public String error() { + + final String errorMessage = responses.entrySet().stream().filter(e -> e.getValue().error() != null).map(e -> e.getKey() + ": " + e.getValue().error()).collect(Collectors.joining(";")); + + if (errorMessage.isEmpty()) { + return null; + } + + final StringBuilder errorBuilder = new StringBuilder(); + errorBuilder.append(errorMessage); + + if (!certificates().isEmpty()) { + errorBuilder.append("\n").append("Unknown certificates: \n").append(certificates().stream().map(AggregatedConnectionResponse::decode).map(this::info).collect(Collectors.joining("\n\n"))); + } + return errorBuilder.toString(); + } + + private String info(X509Certificate certificate) { + return """ + Issued to: %s, + Issued by: %s, + Serial number: %s, + Issued on: %s, + Expires on: %s, + SHA-256 fingerprint: %s, + SHA-1 Fingerprint: %s + """.formatted( + certificate.getSubjectX500Principal().getName(), + certificate.getIssuerX500Principal().getName(), + certificate.getSerialNumber(), + certificate.getNotBefore(), + certificate.getNotAfter(), + getfingerprint(certificate, "SHA-256"), + getfingerprint(certificate, "SHA-1") + ); + } + + public List certificates() { + return responses.values().stream() + .filter(v -> v.certificates() != null) + .flatMap(v -> v.certificates().stream()).distinct().collect(Collectors.toList()); + } + + private static X509Certificate decode(String pemEncodedCert) { + final PEMParser pemParser = new PEMParser(new StringReader(pemEncodedCert)); + try { + Object parsed = pemParser.readObject(); + if (parsed instanceof X509CertificateHolder certificate) { + return new JcaX509CertificateConverter().getCertificate(certificate); + } else { + throw new IllegalArgumentException("Couldn't parse x509 certificate from provided string, unknown type"); + } + } catch (IOException | CertificateException e) { + throw new RuntimeException(e); + } + } + + private static String getfingerprint(X509Certificate cert, String type) { + try { + MessageDigest md = MessageDigest.getInstance(type); + byte[] der = cert.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + String digestHex = DatatypeConverter.printHexBinary(digest); + return digestHex.toLowerCase(Locale.ROOT); + } catch (CertificateEncodingException | NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } +} diff --git a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckRequest.java b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckRequest.java new file mode 100644 index 000000000000..40b082ca2df0 --- /dev/null +++ b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckRequest.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.storage.opensearch2; + +import java.net.URI; + +public record ConnectionCheckRequest(String host, String username, String password, boolean trustUnknownCerts) { +} diff --git a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckResponse.java b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckResponse.java new file mode 100644 index 000000000000..64e4429c75cd --- /dev/null +++ b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/ConnectionCheckResponse.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog.storage.opensearch2; + +import com.fasterxml.jackson.annotation.JsonInclude; +import jakarta.annotation.Nonnull; +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; + +import java.io.IOException; +import java.io.StringWriter; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public record ConnectionCheckResponse(List indices, List certificates, + String error) { + public static ConnectionCheckResponse success(List indices, List certificates) { + return new ConnectionCheckResponse(indices, encodeCerts(certificates), null); + } + + public static ConnectionCheckResponse error(Exception e, List certificates) { + return new ConnectionCheckResponse(Collections.emptyList(), encodeCerts(certificates), e.getMessage()); + } + + @Nonnull + private static List encodeCerts(List trustedCertificates) { + return Optional.ofNullable(trustedCertificates) + .map(certs -> certs.stream().map(ConnectionCheckResponse::encode).collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + + + private static String encode(X509Certificate certificate) { + var writer = new StringWriter(); + try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(writer)) { + jcaPEMWriter.writeObject(certificate); + } catch (IOException e) { + throw new RuntimeException(e); + } + return writer.toString(); + } +} diff --git a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/RemoteReindexingMigrationAdapterOS2.java b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/RemoteReindexingMigrationAdapterOS2.java index 9d672bfea90d..072d0ff2f212 100644 --- a/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/RemoteReindexingMigrationAdapterOS2.java +++ b/graylog-storage-opensearch2/src/main/java/org/graylog/storage/opensearch2/RemoteReindexingMigrationAdapterOS2.java @@ -16,6 +16,7 @@ */ package org.graylog.storage.opensearch2; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.rholder.retry.Attempt; import com.github.rholder.retry.RetryException; @@ -28,9 +29,7 @@ import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.inject.Singleton; -import okhttp3.Credentials; -import okhttp3.OkHttpClient; -import okhttp3.Request; +import jakarta.ws.rs.core.MultivaluedHashMap; import org.apache.commons.lang.time.DurationFormatUtils; import org.graylog.shaded.opensearch2.org.opensearch.OpenSearchException; import org.graylog.shaded.opensearch2.org.opensearch.action.admin.cluster.health.ClusterHealthRequest; @@ -54,6 +53,7 @@ import org.graylog2.indexer.IndexSetRegistry; import org.graylog2.indexer.datanode.IndexMigrationConfiguration; import org.graylog2.indexer.datanode.MigrationConfiguration; +import org.graylog2.indexer.datanode.ProxyRequestAdapter; import org.graylog2.indexer.datanode.RemoteReindexMigrationService; import org.graylog2.indexer.datanode.RemoteReindexRequest; import org.graylog2.indexer.datanode.RemoteReindexingMigrationAdapter; @@ -66,26 +66,19 @@ import org.graylog2.indexer.migration.RemoteReindexMigration; import org.graylog2.indexer.migration.TaskStatus; import org.graylog2.plugin.Tools; -import org.graylog2.security.TrustAllX509TrustManager; -import org.graylog2.security.untrusted.UntrustedCertificateExtractor; +import org.graylog2.rest.resources.datanodes.DatanodeRestApiProxy; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.StringReader; import java.net.MalformedURLException; import java.net.URI; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; +import java.nio.charset.StandardCharsets; import java.util.Comparator; import java.util.List; import java.util.Locale; @@ -108,7 +101,6 @@ public class RemoteReindexingMigrationAdapterOS2 implements RemoteReindexingMigr public static final int TASK_UPDATE_INTERVAL_MILLIS = 1000; private final OpenSearchClient client; - private final OkHttpClient httpClient; private final Indices indices; private final IndexSetRegistry indexSetRegistry; private final ClusterEventBus eventBus; @@ -116,35 +108,33 @@ public class RemoteReindexingMigrationAdapterOS2 implements RemoteReindexingMigr private final RemoteReindexMigrationService reindexMigrationService; + private final DatanodeRestApiProxy datanodeRestApiProxy; + @Inject public RemoteReindexingMigrationAdapterOS2(final OpenSearchClient client, - final OkHttpClient httpClient, final Indices indices, final IndexSetRegistry indexSetRegistry, final ClusterEventBus eventBus, - final ObjectMapper objectMapper, RemoteReindexMigrationService reindexMigrationService) { + final ObjectMapper objectMapper, + RemoteReindexMigrationService reindexMigrationService, + DatanodeRestApiProxy datanodeRestApiProxy) { this.client = client; - this.httpClient = httpClient; this.indices = indices; this.indexSetRegistry = indexSetRegistry; this.eventBus = eventBus; this.objectMapper = objectMapper; this.reindexMigrationService = reindexMigrationService; + this.datanodeRestApiProxy = datanodeRestApiProxy; } @Override public String start(RemoteReindexRequest request) { - final MigrationConfiguration migration = reindexMigrationService.saveMigration(MigrationConfiguration.forIndices(collectIndices(request))); + final AggregatedConnectionResponse response = getAllIndicesFrom(request.uri(), request.username(), request.password(), request.trustUnknownCerts()); + final List indices = isAllIndices(request.indices()) ? response.indices() : request.indices(); + final MigrationConfiguration migration = reindexMigrationService.saveMigration(MigrationConfiguration.forIndices(indices, response.certificates())); doStartMigration(migration, request); return migration.id(); - } - private List collectIndices(RemoteReindexRequest request) { - try { - return isAllIndices(request.indices()) ? getAllIndicesFrom(request.uri(), request.username(), request.password(), request.trustUnknownCerts()) : request.indices(); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } } private void doStartMigration(MigrationConfiguration migration, RemoteReindexRequest request) { @@ -176,7 +166,7 @@ private void prepareCluster(RemoteReindexRequest req, MigrationConfiguration mig // this is expected state for fresh datanode cluster - there is no value configured in the reindex.remote.allowlist // we have to add it to the configuration and wait till the whole cluster restarts logInfo(migration, "Preparing cluster for remote reindexing, setting allowlist to: " + req.allowlist()); - allowReindexing(allowlist, req, migration); + allowReindexing(allowlist, migration); waitForClusterRestart(allowlist, migration); } else { logInfo(migration, "Remote reindex allowlist already configured, skipping cluster configuration and restart."); @@ -239,13 +229,15 @@ private String getErrors(GetTaskResponse task) { @Override public IndexerConnectionCheckResult checkConnection(@Nonnull URI remoteHost, @Nullable String username, @Nullable String password, @Nullable String allowlist, boolean trustUnknownCerts) { - - try { final RemoteReindexAllowlist reindexAllowlist = new RemoteReindexAllowlist(remoteHost, allowlist); reindexAllowlist.validate(); - final List discoveredIndices = getAllIndicesFrom(remoteHost, username, password, trustUnknownCerts); - return IndexerConnectionCheckResult.success(discoveredIndices); + final AggregatedConnectionResponse results = getAllIndicesFrom(remoteHost, username, password, trustUnknownCerts); + if (results.error() != null && !results.error().isEmpty()) { + return IndexerConnectionCheckResult.failure(results.error()); + } else { + return IndexerConnectionCheckResult.success(results.indices()); + } } catch (Exception e) { return IndexerConnectionCheckResult.failure(e); } @@ -308,56 +300,43 @@ private boolean isClusterReady() { } } - void allowReindexing(RemoteReindexAllowlist allowlist, final RemoteReindexRequest request, MigrationConfiguration migration) { - if (request.trustUnknownCerts()) { - try { - final String host = request.uri().toURL().toString(); - final List untrustedCerts = extractHostCertificates(host, migration); - eventBus.post(RemoteReindexAllowlistEvent.add(allowlist.value(), untrustedCerts)); - } catch (NoSuchAlgorithmException | IOException | KeyManagementException e) { - throw new RuntimeException("Failed to extract trusted certificates", e); - } + void allowReindexing(RemoteReindexAllowlist allowlist, MigrationConfiguration migration) { + if (migration.certificates() != null && !migration.certificates().isEmpty()) { + eventBus.post(RemoteReindexAllowlistEvent.add(allowlist.value(), migration.certificates())); } else { eventBus.post(RemoteReindexAllowlistEvent.add(allowlist.value())); } } - @Nonnull - private List extractHostCertificates(String host, MigrationConfiguration migration) throws NoSuchAlgorithmException, IOException, KeyManagementException { - logInfo(migration, "Extracting certificates of host " + host); - final UntrustedCertificateExtractor extractor = new UntrustedCertificateExtractor(httpClient); - final List untrustedCerts = extractor.extractUntrustedCerts(host); - logInfo(migration, "Found following certificates that will be added to truststore " + untrustedCerts.stream().map(c -> c.getSubjectX500Principal().getName()).toList()); - return untrustedCerts; - } - - List getAllIndicesFrom(final URI uri, final String username, final String password, boolean trustUnknownCerts) throws MalformedURLException { - final var host = uri.toURL().toString(); - var url = (host.endsWith("/") ? host : host + "/") + "_cat/indices?h=index"; - try (var response = getClient(trustUnknownCerts).newCall(new Request.Builder().url(url).header("Authorization", Credentials.basic(username, password)).build()).execute()) { - if (response.isSuccessful() && response.body() != null) { - // filtering all indices that start with "." as they indicate a system index - we don't want to reindex those - return new BufferedReader(new StringReader(response.body().string())).lines().filter(i -> !i.startsWith(".")).sorted().toList(); - } else { - throw new RuntimeException("Could not read list of indices from " + host); - } + /** + * Request indices list of a remote host, asking each datanode in the cluster. This also verifies that we can actually connect to the + * remote host from each datanode. Additionally, the call delivers unknown SSL certificates that may be present. They + * will be used to display better error message or transported back to the datanodes as trusted, if user decides so. + */ + private AggregatedConnectionResponse getAllIndicesFrom(final URI uri, final String username, final String password, boolean trustUnknownCerts) { + final ByteArrayInputStream body = new ByteArrayInputStream(""" + { + "host": "%s", + "username": "%s", + "password": "%s", + "trust_unknown_certs": %b + } + """.formatted(uriToString(uri), username, password, trustUnknownCerts).getBytes(StandardCharsets.UTF_8)); + try { + final ProxyRequestAdapter.ProxyResponse response = datanodeRestApiProxy.request(new ProxyRequestAdapter.ProxyRequest("POST", "/connection-check/opensearch", body, "all", new MultivaluedHashMap<>())); + // datanode_hostname -> ConnectionCheckResponse + TypeReference> typeRef = new TypeReference<>() {}; + return new AggregatedConnectionResponse(objectMapper.readValue(response.response(), typeRef)); } catch (IOException e) { - throw new RuntimeException("Could not read list of indices from " + host + ", " + e.getMessage(), e); + throw new RuntimeException(e); } } - private OkHttpClient getClient(boolean trustUnknownCerts) { - if (trustUnknownCerts) { - try { - final SSLContext ctx = SSLContext.getInstance("TLS"); - final TrustAllX509TrustManager trustManager = new TrustAllX509TrustManager(); - ctx.init(null, new TrustManager[]{trustManager}, new SecureRandom()); - return httpClient.newBuilder().sslSocketFactory(ctx.getSocketFactory(), trustManager).build(); - } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new RuntimeException(e); - } - } else { - return httpClient; + private static String uriToString(URI uri){ + try { + return uri.toURL().toString(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); } } diff --git a/graylog2-server/src/main/java/org/graylog2/datanode/RemoteReindexAllowlistEvent.java b/graylog2-server/src/main/java/org/graylog2/datanode/RemoteReindexAllowlistEvent.java index 2b88ade0409c..07a57a417bfe 100644 --- a/graylog2-server/src/main/java/org/graylog2/datanode/RemoteReindexAllowlistEvent.java +++ b/graylog2-server/src/main/java/org/graylog2/datanode/RemoteReindexAllowlistEvent.java @@ -17,20 +17,16 @@ package org.graylog2.datanode; import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.annotation.Nonnull; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import java.io.IOException; import java.io.StringReader; -import java.io.StringWriter; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; public record RemoteReindexAllowlistEvent(List allowlist, ACTION action, @@ -44,37 +40,24 @@ public static RemoteReindexAllowlistEvent add(List allowlist) { return add(allowlist, Collections.emptyList()); } - public static RemoteReindexAllowlistEvent add(List allowlist, List trustedCertificates) { - return new RemoteReindexAllowlistEvent(allowlist, ACTION.ADD, encodeCerts(trustedCertificates)); + /** + * @param allowlist + * @param trustedCertificates PEM encoded certificates that the datanodes should trust + * @return + */ + public static RemoteReindexAllowlistEvent add(List allowlist, List trustedCertificates) { + return new RemoteReindexAllowlistEvent(allowlist, ACTION.ADD, trustedCertificates); } public static RemoteReindexAllowlistEvent remove() { return new RemoteReindexAllowlistEvent(Collections.emptyList(), ACTION.REMOVE, Collections.emptyList()); } - @Nonnull - private static List encodeCerts(List trustedCertificates) { - return Optional.ofNullable(trustedCertificates) - .map(certs -> certs.stream().map(RemoteReindexAllowlistEvent::encode).collect(Collectors.toList())) - .orElse(Collections.emptyList()); - } - - @JsonIgnore public List trustedCertificates() { return pemEncodedTrustedCertificates.stream().map(RemoteReindexAllowlistEvent::decode).collect(Collectors.toList()); } - private static String encode(X509Certificate certificate) { - var writer = new StringWriter(); - try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(writer)) { - jcaPEMWriter.writeObject(certificate); - } catch (IOException e) { - throw new RuntimeException(e); - } - return writer.toString(); - } - private static X509Certificate decode(String pemEncodedCert) { final PEMParser pemParser = new PEMParser(new StringReader(pemEncodedCert)); try { diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/datanode/MigrationConfiguration.java b/graylog2-server/src/main/java/org/graylog2/indexer/datanode/MigrationConfiguration.java index 6578e639f783..b6bba1da1515 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/datanode/MigrationConfiguration.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/datanode/MigrationConfiguration.java @@ -42,6 +42,9 @@ public record MigrationConfiguration( @JsonProperty(FIELD_INDICES) List indices, + @JsonProperty(FIELD_CERTIFICATES) + List certificates, + @JsonProperty(FIELD_LOGS) List logs ) { @@ -49,9 +52,15 @@ public record MigrationConfiguration( public static final String FIELD_INDICES = "indices"; public static final String FIELD_CREATED = "created"; public static final String FIELD_LOGS = "logs"; + public static final String FIELD_CERTIFICATES = "certificates"; - public static MigrationConfiguration forIndices(List indices) { - return new MigrationConfiguration(null, new DateTime(DateTimeZone.UTC), indices.stream().map(indexName -> new IndexMigrationConfiguration(indexName, null)).collect(Collectors.toList()), Collections.emptyList()); + /** + * @param indices + * @param trustedCertificates PEM encoded list of certificates that the migration should trust + * @return + */ + public static MigrationConfiguration forIndices(List indices, List trustedCertificates) { + return new MigrationConfiguration(null, new DateTime(DateTimeZone.UTC), indices.stream().map(indexName -> new IndexMigrationConfiguration(indexName, null)).collect(Collectors.toList()), trustedCertificates, Collections.emptyList()); } @JsonIgnore diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/migration/IndexerConnectionCheckResult.java b/graylog2-server/src/main/java/org/graylog2/indexer/migration/IndexerConnectionCheckResult.java index 093c8c106c77..5c698b7db7b7 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/migration/IndexerConnectionCheckResult.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/migration/IndexerConnectionCheckResult.java @@ -28,4 +28,8 @@ public static IndexerConnectionCheckResult success(List indexNames) { public static IndexerConnectionCheckResult failure(Exception e) { return new IndexerConnectionCheckResult(Collections.emptyList(), e.getMessage()); } + + public static IndexerConnectionCheckResult failure(String errorMessage) { + return new IndexerConnectionCheckResult(Collections.emptyList(), errorMessage); + } } diff --git a/graylog2-server/src/test/java/org/graylog2/datanode/RemoteReindexAllowlistEventTest.java b/graylog2-server/src/test/java/org/graylog2/datanode/RemoteReindexAllowlistEventTest.java index 865ea29f72ad..6a4723b5f62d 100644 --- a/graylog2-server/src/test/java/org/graylog2/datanode/RemoteReindexAllowlistEventTest.java +++ b/graylog2-server/src/test/java/org/graylog2/datanode/RemoteReindexAllowlistEventTest.java @@ -17,11 +17,14 @@ package org.graylog2.datanode; import org.assertj.core.api.Assertions; +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.graylog.security.certutil.CertRequest; import org.graylog.security.certutil.CertificateGenerator; import org.graylog.security.certutil.KeyPair; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.io.StringWriter; import java.security.cert.X509Certificate; import java.time.Duration; import java.util.List; @@ -32,7 +35,7 @@ class RemoteReindexAllowlistEventTest { void testEncodeDecodeCertificate() throws Exception { final KeyPair keyPair = CertificateGenerator.generate(CertRequest.selfSigned("my-server").validity(Duration.ofDays(31))); final X509Certificate certificate = keyPair.certificate(); - final RemoteReindexAllowlistEvent event = RemoteReindexAllowlistEvent.add(List.of("localhost:9200"), List.of(certificate)); + final RemoteReindexAllowlistEvent event = RemoteReindexAllowlistEvent.add(List.of("localhost:9200"), List.of(encodeAsPem(certificate))); final List certificates = event.trustedCertificates(); Assertions.assertThat(certificates) @@ -40,4 +43,14 @@ void testEncodeDecodeCertificate() throws Exception { .contains(certificate); } + + private String encodeAsPem(X509Certificate certificate) { + var writer = new StringWriter(); + try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(writer)) { + jcaPEMWriter.writeObject(certificate); + } catch (IOException e) { + throw new RuntimeException(e); + } + return writer.toString(); + } } diff --git a/graylog2-server/src/test/java/org/graylog2/indexer/datanode/RemoteReindexMigrationServiceImplTest.java b/graylog2-server/src/test/java/org/graylog2/indexer/datanode/RemoteReindexMigrationServiceImplTest.java index 22878b7299f9..aa5dcccbd0fe 100644 --- a/graylog2-server/src/test/java/org/graylog2/indexer/datanode/RemoteReindexMigrationServiceImplTest.java +++ b/graylog2-server/src/test/java/org/graylog2/indexer/datanode/RemoteReindexMigrationServiceImplTest.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.util.Collections; import java.util.List; @ExtendWith(MongoDBExtension.class) @@ -46,7 +47,7 @@ void setUp(MongoDBTestService mongodb, @Test void testCreateReadUpdate() { - MigrationConfiguration migration = migrationService.saveMigration(MigrationConfiguration.forIndices(List.of("index_1", "index_2", "errors_1"))); + MigrationConfiguration migration = migrationService.saveMigration(MigrationConfiguration.forIndices(List.of("index_1", "index_2", "errors_1"), Collections.emptyList())); final String migrationID = migration.id(); Assertions.assertThat(migration) .satisfies(m -> Assertions.assertThat(m.id()).isNotEmpty()) @@ -75,7 +76,7 @@ private static OptionalAssert assertIndexAndTaskMap @Test void testLogs() { - MigrationConfiguration migration = migrationService.saveMigration(MigrationConfiguration.forIndices(List.of("index_1", "index_2", "errors_1"))); + MigrationConfiguration migration = migrationService.saveMigration(MigrationConfiguration.forIndices(List.of("index_1", "index_2", "errors_1"), Collections.emptyList())); migrationService.appendLogEntry(migration.id(), new LogEntry(DateTime.now(DateTimeZone.UTC), LogLevel.INFO, "info entry")); migrationService.appendLogEntry(migration.id(), new LogEntry(DateTime.now(DateTimeZone.UTC), LogLevel.ERROR, "error entry")); Assertions.assertThat(migrationService.getMigration(migration.id())) From 8065ffa57857638ed26a1d89923accbc8e27ad83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 08:03:54 +0200 Subject: [PATCH 02/12] Bump eslint-plugin-react (#19906) Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.34.3 to 7.34.4. - [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases) - [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.3...v7.34.4) --- updated-dependencies: - dependency-name: eslint-plugin-react dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../packages/eslint-config-graylog/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graylog2-web-interface/packages/eslint-config-graylog/package.json b/graylog2-web-interface/packages/eslint-config-graylog/package.json index 708a5c2b6b65..07a20df3bd26 100644 --- a/graylog2-web-interface/packages/eslint-config-graylog/package.json +++ b/graylog2-web-interface/packages/eslint-config-graylog/package.json @@ -27,7 +27,7 @@ "eslint-plugin-jest-dom": "5.4.0", "eslint-plugin-jest-formatting": "3.1.0", "eslint-plugin-jsx-a11y": "6.9.0", - "eslint-plugin-react": "7.34.3", + "eslint-plugin-react": "7.34.4", "eslint-plugin-react-hooks": "4.6.2", "eslint-plugin-testing-library": "6.2.2" } From 1cdf890fade43de6be7b5be58357a00ef42b4eef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 08:10:10 +0200 Subject: [PATCH 03/12] Bump org.apache.maven.plugins:maven-release-plugin from 3.1.0 to 3.1.1 (#19903) Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.1.0...maven-release-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 698c24d4610c..1b8d8760d550 100644 --- a/pom.xml +++ b/pom.xml @@ -567,7 +567,7 @@ org.apache.maven.plugins maven-release-plugin - 3.1.0 + 3.1.1 org.apache.maven.plugins From 6451c8b509f947ddfa9ed35973c0be3bade2452b Mon Sep 17 00:00:00 2001 From: luk-kaminski Date: Mon, 15 Jul 2024 08:37:26 +0200 Subject: [PATCH 04/12] threat_coverage flag explicitly set to off (#19898) Co-authored-by: Bernd Ahlers --------- Co-authored-by: Bernd Ahlers --- .../resources/org/graylog2/featureflag/feature-flag.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graylog2-server/src/main/resources/org/graylog2/featureflag/feature-flag.config b/graylog2-server/src/main/resources/org/graylog2/featureflag/feature-flag.config index c748d1e9e63d..c017a6fe652f 100644 --- a/graylog2-server/src/main/resources/org/graylog2/featureflag/feature-flag.config +++ b/graylog2-server/src/main/resources/org/graylog2/featureflag/feature-flag.config @@ -73,3 +73,6 @@ data_tiering_cloud=off # Enable data node migration data_node_migration=on +# Threat coverage widget +threat_coverage=off + From 8c2efdc353b3fded3a6927b477aae0eacf8fa595 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 10:15:16 +0200 Subject: [PATCH 05/12] Bump org.apache.maven.plugins:maven-pmd-plugin from 3.23.0 to 3.24.0 (#19902) Bumps [org.apache.maven.plugins:maven-pmd-plugin](https://github.com/apache/maven-pmd-plugin) from 3.23.0 to 3.24.0. - [Release notes](https://github.com/apache/maven-pmd-plugin/releases) - [Commits](https://github.com/apache/maven-pmd-plugin/compare/maven-pmd-plugin-3.23.0...maven-pmd-plugin-3.24.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-pmd-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Othello Maurer --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1b8d8760d550..e984000c2415 100644 --- a/pom.xml +++ b/pom.xml @@ -572,7 +572,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.23.0 + 3.24.0 org.apache.maven.plugins From 39539184b32fd8deed4b45086f8525929bd7b1c9 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 15 Jul 2024 13:39:48 +0200 Subject: [PATCH 06/12] Bump package.json version to 6.1.0-alpha.5 --- graylog2-web-interface/manifests/package.json | 2 +- graylog2-web-interface/package.json | 2 +- graylog2-web-interface/packages/graylog-web-plugin/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/graylog2-web-interface/manifests/package.json b/graylog2-web-interface/manifests/package.json index 5ee9df35fe99..42902dfe0a13 100644 --- a/graylog2-web-interface/manifests/package.json +++ b/graylog2-web-interface/manifests/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-manifests", - "version": "6.1.0-SNAPSHOT", + "version": "6.1.0-alpha.5", "description": "Manifests needed to reuse vendor & shared bundles in graylog web interface plugins", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/graylog2-web-interface/package.json b/graylog2-web-interface/package.json index dc731681b24d..26dd0ca86a7c 100644 --- a/graylog2-web-interface/package.json +++ b/graylog2-web-interface/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-interface", - "version": "6.1.0-SNAPSHOT", + "version": "6.1.0-alpha.5", "description": "Graylog Web Interface", "author": "torch", "license": "SSPL-1.0", diff --git a/graylog2-web-interface/packages/graylog-web-plugin/package.json b/graylog2-web-interface/packages/graylog-web-plugin/package.json index 5cb70552d0da..86becd7dc34b 100644 --- a/graylog2-web-interface/packages/graylog-web-plugin/package.json +++ b/graylog2-web-interface/packages/graylog-web-plugin/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-plugin", - "version": "6.1.0-SNAPSHOT", + "version": "6.1.0-alpha.5", "description": "Helper code for streamlining Graylog web interface plugin development", "main": "index.js", "repository": { From e52dca4bfb6a051129a3dec753b0e0d0e136a8ef Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 15 Jul 2024 13:39:51 +0200 Subject: [PATCH 07/12] [graylog2-server] prepare release 6.1.0-alpha.5 --- data-node/pom.xml | 2 +- distribution/pom.xml | 2 +- full-backend-tests/pom.xml | 2 +- graylog-plugin-archetype/pom.xml | 2 +- graylog-plugin-parent/graylog-plugin-web-parent/pom.xml | 2 +- graylog-plugin-parent/pom.xml | 2 +- graylog-project-parent/pom.xml | 2 +- graylog-storage-elasticsearch7/pom.xml | 2 +- graylog-storage-opensearch2/pom.xml | 2 +- graylog2-server/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/data-node/pom.xml b/data-node/pom.xml index 34eef05c73d9..f8171602f886 100644 --- a/data-node/pom.xml +++ b/data-node/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-project-parent diff --git a/distribution/pom.xml b/distribution/pom.xml index 3bd1d10c1b66..97d0072b11bf 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -23,7 +23,7 @@ graylog-parent org.graylog - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 4.0.0 diff --git a/full-backend-tests/pom.xml b/full-backend-tests/pom.xml index 047b1ffd2df6..7aa490c50761 100644 --- a/full-backend-tests/pom.xml +++ b/full-backend-tests/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-project-parent diff --git a/graylog-plugin-archetype/pom.xml b/graylog-plugin-archetype/pom.xml index 00bc46eecfc8..27f500f004bb 100644 --- a/graylog-plugin-archetype/pom.xml +++ b/graylog-plugin-archetype/pom.xml @@ -22,7 +22,7 @@ org.graylog graylog-project-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-project-parent diff --git a/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml b/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml index 19d5058d3fe9..95eee3bf8f15 100644 --- a/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml +++ b/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml @@ -22,7 +22,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 graylog-plugin-web-parent diff --git a/graylog-plugin-parent/pom.xml b/graylog-plugin-parent/pom.xml index 3356bab9e2f5..0b0581abdb97 100644 --- a/graylog-plugin-parent/pom.xml +++ b/graylog-plugin-parent/pom.xml @@ -26,7 +26,7 @@ org.graylog graylog-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 org.graylog.plugins diff --git a/graylog-project-parent/pom.xml b/graylog-project-parent/pom.xml index 707c64787a3f..6af22c921c84 100644 --- a/graylog-project-parent/pom.xml +++ b/graylog-project-parent/pom.xml @@ -27,7 +27,7 @@ org.graylog graylog-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 graylog-project-parent diff --git a/graylog-storage-elasticsearch7/pom.xml b/graylog-storage-elasticsearch7/pom.xml index 7c9b1a4baf33..894e1d8d8fc0 100644 --- a/graylog-storage-elasticsearch7/pom.xml +++ b/graylog-storage-elasticsearch7/pom.xml @@ -23,7 +23,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-plugin-parent 4.0.0 diff --git a/graylog-storage-opensearch2/pom.xml b/graylog-storage-opensearch2/pom.xml index 277035d495ee..842f1dc7f094 100644 --- a/graylog-storage-opensearch2/pom.xml +++ b/graylog-storage-opensearch2/pom.xml @@ -23,7 +23,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-plugin-parent 4.0.0 diff --git a/graylog2-server/pom.xml b/graylog2-server/pom.xml index 2f2fe4744d6f..7c6acfaa9b05 100644 --- a/graylog2-server/pom.xml +++ b/graylog2-server/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 ../graylog-project-parent diff --git a/pom.xml b/pom.xml index e984000c2415..6df245017289 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ org.graylog graylog-parent - 6.1.0-SNAPSHOT + 6.1.0-alpha.5 pom Graylog Parent POM From 08ae589fe3ee869e0102e71c3cbd86f30b55c7e0 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 15 Jul 2024 13:56:24 +0200 Subject: [PATCH 08/12] Bump package.json version to 6.1.0-SNAPSHOT --- graylog2-web-interface/manifests/package.json | 2 +- graylog2-web-interface/package.json | 2 +- graylog2-web-interface/packages/graylog-web-plugin/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/graylog2-web-interface/manifests/package.json b/graylog2-web-interface/manifests/package.json index 42902dfe0a13..5ee9df35fe99 100644 --- a/graylog2-web-interface/manifests/package.json +++ b/graylog2-web-interface/manifests/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-manifests", - "version": "6.1.0-alpha.5", + "version": "6.1.0-SNAPSHOT", "description": "Manifests needed to reuse vendor & shared bundles in graylog web interface plugins", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/graylog2-web-interface/package.json b/graylog2-web-interface/package.json index 26dd0ca86a7c..dc731681b24d 100644 --- a/graylog2-web-interface/package.json +++ b/graylog2-web-interface/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-interface", - "version": "6.1.0-alpha.5", + "version": "6.1.0-SNAPSHOT", "description": "Graylog Web Interface", "author": "torch", "license": "SSPL-1.0", diff --git a/graylog2-web-interface/packages/graylog-web-plugin/package.json b/graylog2-web-interface/packages/graylog-web-plugin/package.json index 86becd7dc34b..5cb70552d0da 100644 --- a/graylog2-web-interface/packages/graylog-web-plugin/package.json +++ b/graylog2-web-interface/packages/graylog-web-plugin/package.json @@ -1,6 +1,6 @@ { "name": "graylog-web-plugin", - "version": "6.1.0-alpha.5", + "version": "6.1.0-SNAPSHOT", "description": "Helper code for streamlining Graylog web interface plugin development", "main": "index.js", "repository": { From 890ff674b911527207c1eb6d2eb58d8656bae868 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 15 Jul 2024 13:56:26 +0200 Subject: [PATCH 09/12] [graylog2-server] prepare for next development iteration --- data-node/pom.xml | 2 +- distribution/pom.xml | 2 +- full-backend-tests/pom.xml | 2 +- graylog-plugin-archetype/pom.xml | 2 +- graylog-plugin-parent/graylog-plugin-web-parent/pom.xml | 2 +- graylog-plugin-parent/pom.xml | 2 +- graylog-project-parent/pom.xml | 2 +- graylog-storage-elasticsearch7/pom.xml | 2 +- graylog-storage-opensearch2/pom.xml | 2 +- graylog2-server/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/data-node/pom.xml b/data-node/pom.xml index f8171602f886..34eef05c73d9 100644 --- a/data-node/pom.xml +++ b/data-node/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-project-parent diff --git a/distribution/pom.xml b/distribution/pom.xml index 97d0072b11bf..3bd1d10c1b66 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -23,7 +23,7 @@ graylog-parent org.graylog - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT 4.0.0 diff --git a/full-backend-tests/pom.xml b/full-backend-tests/pom.xml index 7aa490c50761..047b1ffd2df6 100644 --- a/full-backend-tests/pom.xml +++ b/full-backend-tests/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-project-parent diff --git a/graylog-plugin-archetype/pom.xml b/graylog-plugin-archetype/pom.xml index 27f500f004bb..00bc46eecfc8 100644 --- a/graylog-plugin-archetype/pom.xml +++ b/graylog-plugin-archetype/pom.xml @@ -22,7 +22,7 @@ org.graylog graylog-project-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-project-parent diff --git a/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml b/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml index 95eee3bf8f15..19d5058d3fe9 100644 --- a/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml +++ b/graylog-plugin-parent/graylog-plugin-web-parent/pom.xml @@ -22,7 +22,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT graylog-plugin-web-parent diff --git a/graylog-plugin-parent/pom.xml b/graylog-plugin-parent/pom.xml index 0b0581abdb97..3356bab9e2f5 100644 --- a/graylog-plugin-parent/pom.xml +++ b/graylog-plugin-parent/pom.xml @@ -26,7 +26,7 @@ org.graylog graylog-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT org.graylog.plugins diff --git a/graylog-project-parent/pom.xml b/graylog-project-parent/pom.xml index 6af22c921c84..707c64787a3f 100644 --- a/graylog-project-parent/pom.xml +++ b/graylog-project-parent/pom.xml @@ -27,7 +27,7 @@ org.graylog graylog-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT graylog-project-parent diff --git a/graylog-storage-elasticsearch7/pom.xml b/graylog-storage-elasticsearch7/pom.xml index 894e1d8d8fc0..7c9b1a4baf33 100644 --- a/graylog-storage-elasticsearch7/pom.xml +++ b/graylog-storage-elasticsearch7/pom.xml @@ -23,7 +23,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-plugin-parent 4.0.0 diff --git a/graylog-storage-opensearch2/pom.xml b/graylog-storage-opensearch2/pom.xml index 842f1dc7f094..277035d495ee 100644 --- a/graylog-storage-opensearch2/pom.xml +++ b/graylog-storage-opensearch2/pom.xml @@ -23,7 +23,7 @@ org.graylog.plugins graylog-plugin-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-plugin-parent 4.0.0 diff --git a/graylog2-server/pom.xml b/graylog2-server/pom.xml index 7c6acfaa9b05..2f2fe4744d6f 100644 --- a/graylog2-server/pom.xml +++ b/graylog2-server/pom.xml @@ -23,7 +23,7 @@ org.graylog graylog-project-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT ../graylog-project-parent diff --git a/pom.xml b/pom.xml index 6df245017289..e984000c2415 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ org.graylog graylog-parent - 6.1.0-alpha.5 + 6.1.0-SNAPSHOT pom Graylog Parent POM From 214beb5a024b3bf0f3f108a1d33cddca6ec501b5 Mon Sep 17 00:00:00 2001 From: maxiadlovskii Date: Mon, 15 Jul 2024 14:04:15 +0200 Subject: [PATCH 10/12] Add select all rest fields and deselect button to export messages modal (#19463) * Add select all and deselect all fields buttons to export messages widget * Add collapse button * Add change log * fix eslint errors * Change field list limit * small improvements --- changelog/unreleased/pr-19463.toml | 5 ++ .../aggregationwizard/FieldSelect.tsx | 73 ++++++++++++++----- .../components/export/ExportSettings.tsx | 5 +- .../widgets/FieldsConfiguration.tsx | 60 ++++++++++++++- 4 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 changelog/unreleased/pr-19463.toml diff --git a/changelog/unreleased/pr-19463.toml b/changelog/unreleased/pr-19463.toml new file mode 100644 index 000000000000..0cb29c5e7267 --- /dev/null +++ b/changelog/unreleased/pr-19463.toml @@ -0,0 +1,5 @@ +type="a" +message="Add option to select all fields for messages export widget" + +pulls = ["19463"] +issues=["Graylog2/graylog-plugin-enterprise#5616"] diff --git a/graylog2-web-interface/src/views/components/aggregationwizard/FieldSelect.tsx b/graylog2-web-interface/src/views/components/aggregationwizard/FieldSelect.tsx index 06bc82602ea3..69c20f3a10d1 100644 --- a/graylog2-web-interface/src/views/components/aggregationwizard/FieldSelect.tsx +++ b/graylog2-web-interface/src/views/components/aggregationwizard/FieldSelect.tsx @@ -15,7 +15,8 @@ * . */ import * as React from 'react'; -import { useContext, useMemo } from 'react'; +import type { SyntheticEvent } from 'react'; +import { useCallback, useContext, useMemo } from 'react'; import * as Immutable from 'immutable'; import styled, { css } from 'styled-components'; @@ -27,6 +28,7 @@ import FieldTypeIcon from 'views/components/sidebar/fields/FieldTypeIcon'; import type FieldType from 'views/logic/fieldtypes/FieldType'; import useActiveQueryId from 'views/hooks/useActiveQueryId'; import type { SelectRef } from 'components/common/Select/Select'; +import { Button } from 'components/bootstrap'; const FieldName = styled.span` display: inline-flex; @@ -34,6 +36,13 @@ const FieldName = styled.span` align-items: center; `; +const ButtonRow = styled.div` + margin-top: 5px; + display: inline-flex; + gap: 5px; + margin-bottom: 10px; +`; + type Props = { ariaLabel?: string, autoFocus?: boolean, @@ -53,6 +62,10 @@ type Props = { selectRef?: SelectRef, size?: 'normal' | 'small', value: string | undefined, + onSelectAllRest?: (fieldNames: Array) => void, + showSelectAllRest?: boolean, + onDeSelectAll?: (e: SyntheticEvent) => void, + showDeSelectAll?: boolean, } const sortByLabel = ({ label: label1 }: { label: string }, { label: label2 }: { label: string }) => defaultCompare(label1, label2); @@ -100,6 +113,10 @@ const FieldSelect = ({ selectRef, size, value, + onSelectAllRest, + showSelectAllRest, + onDeSelectAll, + showDeSelectAll, }: Props) => { const activeQuery = useActiveQueryId(); const fieldTypes = useContext(FieldTypesContext); @@ -115,25 +132,39 @@ const FieldSelect = ({ .toArray() .sort(sortByLabel), [activeQuery, excludedFields, fieldTypes.queryFields, isFieldQualified]); + const _onSelectAllRest = useCallback(() => onSelectAllRest(fieldOptions.map(({ value: fieldValue }) => fieldValue)), [fieldOptions, onSelectAllRest]); + + const _showSelectAllRest = !!fieldOptions?.length && showSelectAllRest && typeof _onSelectAllRest === 'function'; + + const _showDeSelectAll = showDeSelectAll && typeof onDeSelectAll === 'function'; + return ( - + {(_showSelectAllRest || _showDeSelectAll) && ( + + {_showSelectAllRest && } + {_showDeSelectAll && } + + )} + ); }; @@ -153,6 +184,10 @@ FieldSelect.defaultProps = { selectRef: undefined, size: 'small', menuPortalTarget: undefined, + onSelectAllRest: undefined, + showSelectAllRest: false, + onDeSelectAll: undefined, + showDeSelectAll: false, }; export default FieldSelect; diff --git a/graylog2-web-interface/src/views/components/export/ExportSettings.tsx b/graylog2-web-interface/src/views/components/export/ExportSettings.tsx index 1087ceffff5d..14eeb6dcde7d 100644 --- a/graylog2-web-interface/src/views/components/export/ExportSettings.tsx +++ b/graylog2-web-interface/src/views/components/export/ExportSettings.tsx @@ -84,7 +84,10 @@ const ExportSettings = ({ } selectSize="normal" displaySortableListOverlayInPortal - selectedFields={value.map(({ field }) => field)} /> + selectedFields={value.map(({ field }) => field)} + showSelectAllRest + showDeSelectAll + showListCollapseButton /> )} diff --git a/graylog2-web-interface/src/views/components/widgets/FieldsConfiguration.tsx b/graylog2-web-interface/src/views/components/widgets/FieldsConfiguration.tsx index 12d86ff1dacc..ace2a3a2a41e 100644 --- a/graylog2-web-interface/src/views/components/widgets/FieldsConfiguration.tsx +++ b/graylog2-web-interface/src/views/components/widgets/FieldsConfiguration.tsx @@ -16,12 +16,27 @@ */ import * as React from 'react'; -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; +import styled from 'styled-components'; +import { Button } from 'components/bootstrap'; +import { Icon } from 'components/common'; import SelectedFieldsList from 'views/components/widgets/SelectedFieldsList'; import FieldSelect from 'views/components/aggregationwizard/FieldSelect'; import type FieldTypeMapping from 'views/logic/fieldtypes/FieldTypeMapping'; +const FIELD_LIST_LIMIT = 1; + +const ToggleButton = styled(Button)` + padding: 0; + margin-bottom: 10px; + display: block; +`; + +const ToggleIcon = styled(Icon)` + margin-left: 5px; +`; + type Props = { createSelectPlaceholder?: string displaySortableListOverlayInPortal?: boolean, @@ -31,6 +46,9 @@ type Props = { selectSize?: 'normal' | 'small', selectedFields: Array, testPrefix?: string, + showSelectAllRest?: boolean, + showDeSelectAll?: boolean, + showListCollapseButton?: boolean } const FieldsConfiguration = ({ @@ -42,18 +60,49 @@ const FieldsConfiguration = ({ selectSize, selectedFields, testPrefix, + showSelectAllRest, + showDeSelectAll, + showListCollapseButton, }: Props) => { + const [showSelectedList, setShowSelectedList] = useState(true); const onAddField = useCallback((newField: string) => ( onChange([...selectedFields, newField]) ), [onChange, selectedFields]); + const _showListCollapseButton = showListCollapseButton && selectedFields.length > FIELD_LIST_LIMIT; + + const onSelectAllRest = (newFields: Array) => { + const _selectedFields = [...selectedFields, ...newFields]; + onChange(_selectedFields); + + if (showListCollapseButton && _selectedFields.length > FIELD_LIST_LIMIT) { + setShowSelectedList(false); + } + }; + + const onDeselectAll = () => { + onChange([]); + setShowSelectedList(true); + }; + return ( <> + {_showListCollapseButton && ( + { + setShowSelectedList((cur) => !cur); + }}> + {showSelectedList ? `Hide ${selectedFields.length} selected fields` : `Show ${selectedFields.length} selected fields`} + + )} + {showSelectedList && ( + )} + ariaLabel={createSelectPlaceholder} + onSelectAllRest={showSelectAllRest && onSelectAllRest} + showSelectAllRest={showSelectAllRest} + onDeSelectAll={onDeselectAll} + showDeSelectAll={showDeSelectAll && !!selectedFields.length} /> ); }; @@ -77,6 +130,9 @@ FieldsConfiguration.defaultProps = { selectSize: undefined, menuPortalTarget: undefined, testPrefix: '', + showSelectAllRest: false, + showDeSelectAll: false, + showListCollapseButton: false, }; export default FieldsConfiguration; From a5cd37b1a315fe983c0e4c73d7a0fc789b557a89 Mon Sep 17 00:00:00 2001 From: Linus Pahl <46300478+linuspahl@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:35:51 +0200 Subject: [PATCH 11/12] Update `vendor-module-ids.json`. (#19909) --- graylog2-web-interface/webpack/vendor-module-ids.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/graylog2-web-interface/webpack/vendor-module-ids.json b/graylog2-web-interface/webpack/vendor-module-ids.json index 9291a5cb72f9..5cc5e98dd7dc 100644 --- a/graylog2-web-interface/webpack/vendor-module-ids.json +++ b/graylog2-web-interface/webpack/vendor-module-ids.json @@ -1305,6 +1305,8 @@ "javascript/esm|./node_modules/@mantine/core/esm/components/Avatar/AvatarGroup/AvatarGroup.context.mjs": 1228, "javascript/esm|./node_modules/@mantine/core/esm/components/Avatar/AvatarGroup/AvatarGroup.mjs": 38783, "javascript/esm|./node_modules/@mantine/core/esm/components/Avatar/AvatarPlaceholderIcon.mjs": 84483, + "javascript/esm|./node_modules/@mantine/core/esm/components/Avatar/get-initials-color/get-initials-color.mjs": 161, + "javascript/esm|./node_modules/@mantine/core/esm/components/Avatar/get-initials/get-initials.mjs": 5101, "javascript/esm|./node_modules/@mantine/core/esm/components/BackgroundImage/BackgroundImage.mjs": 43301, "javascript/esm|./node_modules/@mantine/core/esm/components/BackgroundImage/BackgroundImage.module.css.mjs": 82490, "javascript/esm|./node_modules/@mantine/core/esm/components/Badge/Badge.mjs": 86885, @@ -3469,6 +3471,7 @@ 135, 139, 150, + 161, 162, 163, 168, @@ -3852,6 +3855,7 @@ 5044, 5054, 5066, + 5101, 5115, 5138, 5148, From 096e9039b05bc1ef8f2912996bb0dfe53e96e159 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:36:03 +0200 Subject: [PATCH 12/12] Updating yarn lockfile (#19897) Co-authored-by: Gary Bot --- graylog2-web-interface/yarn.lock | 242 +++++++++++++++++++------------ 1 file changed, 151 insertions(+), 91 deletions(-) diff --git a/graylog2-web-interface/yarn.lock b/graylog2-web-interface/yarn.lock index 7434665ded01..7cf21811a1b7 100644 --- a/graylog2-web-interface/yarn.lock +++ b/graylog2-web-interface/yarn.lock @@ -60,6 +60,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.7.tgz#d23bbea508c3883ba8251fb4164982c36ea577ed" integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== +"@babel/compat-data@^7.24.8": + version "7.24.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.9.tgz#53eee4e68f1c1d0282aa0eb05ddb02d033fc43a0" + integrity sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng== + "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.18.2": version "7.18.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.2.tgz#87b2fcd7cce9becaa7f5acebdc4f09f3dd19d876" @@ -220,6 +225,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz#b607c3161cd9d1744977d4f97139572fe778c271" + integrity sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw== + dependencies: + "@babel/compat-data" "^7.24.8" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz#2eaed36b3a1c11c53bdf80d53838b293c52f5b3b" @@ -386,6 +402,17 @@ "@babel/helper-split-export-declaration" "^7.24.7" "@babel/helper-validator-identifier" "^7.24.7" +"@babel/helper-module-transforms@^7.24.8": + version "7.24.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29" + integrity sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + "@babel/helper-optimise-call-expression@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" @@ -413,6 +440,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0" integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== +"@babel/helper-plugin-utils@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + "@babel/helper-remap-async-to-generator@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz#b3f0f203628522713849d49403f1a414468be4c7" @@ -549,6 +581,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6" integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw== +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + "@babel/helper-wrap-function@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz#52d893af7e42edca7c6d2c6764549826336aae1f" @@ -872,16 +909,16 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz#4ae6ef43a12492134138c1e45913f7c46c41b4bf" - integrity sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw== +"@babel/plugin-transform-classes@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz#ad23301fe5bc153ca4cf7fb572a9bc8b0b711cf7" + integrity sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA== dependencies: "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.8" "@babel/helper-environment-visitor" "^7.24.7" "@babel/helper-function-name" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.8" "@babel/helper-replace-supers" "^7.24.7" "@babel/helper-split-export-declaration" "^7.24.7" globals "^11.1.0" @@ -894,12 +931,12 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/template" "^7.24.7" -"@babel/plugin-transform-destructuring@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz#a097f25292defb6e6cc16d6333a4cfc1e3c72d9e" - integrity sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw== +"@babel/plugin-transform-destructuring@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz#c828e814dbe42a2718a838c2a2e16a408e055550" + integrity sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.8" "@babel/plugin-transform-dotall-regex@^7.24.7": version "7.24.7" @@ -1004,6 +1041,15 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/helper-simple-access" "^7.24.7" +"@babel/plugin-transform-modules-commonjs@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz#ab6421e564b717cb475d6fff70ae7f103536ea3c" + integrity sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA== + dependencies: + "@babel/helper-module-transforms" "^7.24.8" + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-simple-access" "^7.24.7" + "@babel/plugin-transform-modules-systemjs@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz#f8012316c5098f6e8dee6ecd58e2bc6f003d0ce7" @@ -1088,6 +1134,15 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" "@babel/plugin-syntax-optional-chaining" "^7.8.3" +"@babel/plugin-transform-optional-chaining@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" + integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-transform-parameters@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" @@ -1209,12 +1264,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-typeof-symbol@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz#f074be466580d47d6e6b27473a840c9f9ca08fb0" - integrity sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg== +"@babel/plugin-transform-typeof-symbol@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz#383dab37fb073f5bfe6e60c654caac309f92ba1c" + integrity sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.8" "@babel/plugin-transform-typescript@^7.24.7": version "7.24.7" @@ -1257,15 +1312,15 @@ "@babel/helper-create-regexp-features-plugin" "^7.24.7" "@babel/helper-plugin-utils" "^7.24.7" -"@babel/preset-env@7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.7.tgz#ff067b4e30ba4a72f225f12f123173e77b987f37" - integrity sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ== +"@babel/preset-env@7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.8.tgz#e0db94d7f17d6f0e2564e8d29190bc8cdacec2d1" + integrity sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ== dependencies: - "@babel/compat-data" "^7.24.7" - "@babel/helper-compilation-targets" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" + "@babel/compat-data" "^7.24.8" + "@babel/helper-compilation-targets" "^7.24.8" + "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-validator-option" "^7.24.8" "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.7" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.7" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" @@ -1296,9 +1351,9 @@ "@babel/plugin-transform-block-scoping" "^7.24.7" "@babel/plugin-transform-class-properties" "^7.24.7" "@babel/plugin-transform-class-static-block" "^7.24.7" - "@babel/plugin-transform-classes" "^7.24.7" + "@babel/plugin-transform-classes" "^7.24.8" "@babel/plugin-transform-computed-properties" "^7.24.7" - "@babel/plugin-transform-destructuring" "^7.24.7" + "@babel/plugin-transform-destructuring" "^7.24.8" "@babel/plugin-transform-dotall-regex" "^7.24.7" "@babel/plugin-transform-duplicate-keys" "^7.24.7" "@babel/plugin-transform-dynamic-import" "^7.24.7" @@ -1311,7 +1366,7 @@ "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" "@babel/plugin-transform-member-expression-literals" "^7.24.7" "@babel/plugin-transform-modules-amd" "^7.24.7" - "@babel/plugin-transform-modules-commonjs" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.8" "@babel/plugin-transform-modules-systemjs" "^7.24.7" "@babel/plugin-transform-modules-umd" "^7.24.7" "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" @@ -1321,7 +1376,7 @@ "@babel/plugin-transform-object-rest-spread" "^7.24.7" "@babel/plugin-transform-object-super" "^7.24.7" "@babel/plugin-transform-optional-catch-binding" "^7.24.7" - "@babel/plugin-transform-optional-chaining" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.8" "@babel/plugin-transform-parameters" "^7.24.7" "@babel/plugin-transform-private-methods" "^7.24.7" "@babel/plugin-transform-private-property-in-object" "^7.24.7" @@ -1332,7 +1387,7 @@ "@babel/plugin-transform-spread" "^7.24.7" "@babel/plugin-transform-sticky-regex" "^7.24.7" "@babel/plugin-transform-template-literals" "^7.24.7" - "@babel/plugin-transform-typeof-symbol" "^7.24.7" + "@babel/plugin-transform-typeof-symbol" "^7.24.8" "@babel/plugin-transform-unicode-escapes" "^7.24.7" "@babel/plugin-transform-unicode-property-regex" "^7.24.7" "@babel/plugin-transform-unicode-regex" "^7.24.7" @@ -1341,7 +1396,7 @@ babel-plugin-polyfill-corejs2 "^0.4.10" babel-plugin-polyfill-corejs3 "^0.10.4" babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.31.0" + core-js-compat "^3.37.1" semver "^6.3.1" "@babel/preset-modules@0.1.6-no-external-plugins": @@ -4661,7 +4716,7 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/core" "^7.18.2" "@babel/plugin-syntax-dynamic-import" "7.8.3" "@babel/plugin-transform-runtime" "7.24.7" - "@babel/preset-env" "7.24.7" + "@babel/preset-env" "7.24.8" "@babel/preset-react" "7.24.7" "@babel/preset-typescript" "7.24.7" babel-plugin-styled-components "^2.0.7" @@ -4905,16 +4960,6 @@ browserslist@^4.21.10: node-releases "^2.0.13" update-browserslist-db "^1.0.11" -browserslist@^4.21.5: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - browserslist@^4.21.9: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" @@ -4945,6 +4990,16 @@ browserslist@^4.23.0: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +browserslist@^4.23.1: + version "4.23.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed" + integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== + dependencies: + caniuse-lite "^1.0.30001640" + electron-to-chromium "^1.4.820" + node-releases "^2.0.14" + update-browserslist-db "^1.1.0" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -5068,11 +5123,16 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001503, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001524, caniuse-lite@^1.0.30001565, caniuse-lite@^1.0.30001587: +caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001503, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001524, caniuse-lite@^1.0.30001565, caniuse-lite@^1.0.30001587: version "1.0.30001615" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001615.tgz" integrity sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ== +caniuse-lite@^1.0.30001640: + version "1.0.30001642" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz#6aa6610eb24067c246d30c57f055a9d0a7f8d05f" + integrity sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA== + canvas-fit@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/canvas-fit/-/canvas-fit-1.5.0.tgz#ae13be66ade42f5be0e487e345fce30a5e5b5e5f" @@ -5518,13 +5578,6 @@ copy-webpack-plugin@^12.0.1: schema-utils "^4.2.0" serialize-javascript "^6.0.2" -core-js-compat@^3.31.0: - version "3.31.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.0.tgz#4030847c0766cc0e803dcdfb30055d7ef2064bf1" - integrity sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw== - dependencies: - browserslist "^4.21.5" - core-js-compat@^3.36.1: version "3.36.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.36.1.tgz#1818695d72c99c25d621dca94e6883e190cea3c8" @@ -5532,6 +5585,13 @@ core-js-compat@^3.36.1: dependencies: browserslist "^4.23.0" +core-js-compat@^3.37.1: + version "3.37.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.37.1.tgz#c844310c7852f4bdf49b8d339730b97e17ff09ee" + integrity sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg== + dependencies: + browserslist "^4.23.0" + core-js@3: version "3.37.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9" @@ -6508,11 +6568,6 @@ electron-to-chromium@^1.4.118: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.132.tgz#b64599eb018221e52e2e4129de103b03a413c55d" integrity sha512-JYdZUw/1068NWN+SwXQ7w6Ue0bWYGihvSUNNQwurvcDV/SM7vSiGZ3NuFvFgoEiCs4kB8xs3cX2an3wB7d4TBw== -electron-to-chromium@^1.4.284: - version "1.4.287" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.287.tgz#d121f9675aa099fd23ddbcba423ea4340f768efe" - integrity sha512-Dj649q67z9oYp4dj7B80hdxb1ExIvy8KvrFqjCuGqFxUHk43b+VXQVFkD5zxAFmhvA6Mu9fou6ZQjJkMSXNFFg== - electron-to-chromium@^1.4.431: version "1.4.451" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.451.tgz#12b63ee5c82cbbc7b4ddd91e90f5a0dfc10de26e" @@ -6533,6 +6588,11 @@ electron-to-chromium@^1.4.668: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.728.tgz#ac54d9d1b38752b920ec737a48c83dec2bf45ea1" integrity sha512-Ud1v7hJJYIqehlUJGqR6PF1Ek8l80zWwxA6nGxigBsGJ9f9M2fciHyrIiNMerSHSH3p+0/Ia7jIlnDkt41h5cw== +electron-to-chromium@^1.4.820: + version "1.4.827" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz#76068ed1c71dd3963e1befc8ae815004b2da6a02" + integrity sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ== + element-size@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/element-size/-/element-size-1.1.1.tgz#64e5f159d97121631845bcbaecaf279c39b5e34e" @@ -7129,6 +7189,11 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -7214,13 +7279,13 @@ eslint-config-airbnb@19.0.4: eslint-config-airbnb "19.0.4" eslint-import-resolver-webpack "0.13.8" eslint-plugin-compat "4.2.0" - eslint-plugin-graylog "file:../../../../.cache/yarn/v6/npm-eslint-config-graylog-1.3.0-0a4acd8a-1b6f-48b0-a9c1-e0048a3ed0c0-1720527010063/node_modules/eslint-plugin-graylog" + eslint-plugin-graylog "file:../../../../.cache/yarn/v6/npm-eslint-config-graylog-1.3.0-aa7ad934-002c-4701-8817-e2dc0a6d8057-1721045390268/node_modules/eslint-plugin-graylog" eslint-plugin-import "2.25.3" eslint-plugin-jest "28.6.0" eslint-plugin-jest-dom "5.4.0" eslint-plugin-jest-formatting "3.1.0" eslint-plugin-jsx-a11y "6.9.0" - eslint-plugin-react "7.34.3" + eslint-plugin-react "7.34.4" eslint-plugin-react-hooks "4.6.2" eslint-plugin-testing-library "6.2.2" @@ -7340,10 +7405,10 @@ eslint-plugin-react-hooks@4.6.2: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== -eslint-plugin-react@7.34.3: - version "7.34.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz#9965f27bd1250a787b5d4cfcc765e5a5d58dcb7b" - integrity sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA== +eslint-plugin-react@7.34.4: + version "7.34.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.34.4.tgz#1f0dc313a0937db7ce15fd1f6c3d77e70f3e02fb" + integrity sha512-Np+jo9bUwJNxCsT12pXtrGhJgT3T44T1sHhn1Ssr42XFn8TES0267wPGo5nNrMHi8qkyimDAX2BUmkf9pSaVzA== dependencies: array-includes "^3.1.8" array.prototype.findlast "^1.2.5" @@ -7353,16 +7418,17 @@ eslint-plugin-react@7.34.3: doctrine "^2.1.0" es-iterator-helpers "^1.0.19" estraverse "^5.3.0" + hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" object.entries "^1.1.8" object.fromentries "^2.0.8" - object.hasown "^1.1.4" object.values "^1.2.0" prop-types "^15.8.1" resolve "^2.0.0-next.5" semver "^6.3.1" string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" eslint-plugin-testing-library@6.2.2: version "6.2.2" @@ -8682,13 +8748,13 @@ graphemer@^1.4.0: "@types/create-react-class" "15.6.8" "@types/jquery" "3.5.30" "@types/react" "18.3.3" - babel-preset-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-930a3410-32a5-44e9-81a0-3f1975bef1a1-1720527010001/node_modules/babel-preset-graylog" + babel-preset-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-fe65f8ae-8ea3-4ac2-b5dc-7ea4937a0738-1721045390149/node_modules/babel-preset-graylog" create-react-class "15.7.0" - eslint-config-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-930a3410-32a5-44e9-81a0-3f1975bef1a1-1720527010001/node_modules/eslint-config-graylog" + eslint-config-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-fe65f8ae-8ea3-4ac2-b5dc-7ea4937a0738-1721045390149/node_modules/eslint-config-graylog" formik "2.4.6" history "^5.3.0" html-webpack-plugin "^5.5.0" - jest-preset-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-930a3410-32a5-44e9-81a0-3f1975bef1a1-1720527010001/node_modules/jest-preset-graylog" + jest-preset-graylog "file:../../../../.cache/yarn/v6/npm-graylog-web-plugin-6.1.0-SNAPSHOT-fe65f8ae-8ea3-4ac2-b5dc-7ea4937a0738-1721045390149/node_modules/jest-preset-graylog" jquery "3.7.1" moment "2.30.1" moment-timezone "0.5.45" @@ -8701,7 +8767,7 @@ graphemer@^1.4.0: styled-components "6.1.1" typescript "5.5.3" use-query-params "^2.2.0" - webpack "5.92.1" + webpack "5.93.0" webpack-cli "5.1.4" webpack-merge "4.2.2" @@ -11756,11 +11822,6 @@ node-releases@^2.0.3: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== - nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -11995,15 +12056,6 @@ object.getownpropertydescriptors@^2.1.0: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -object.hasown@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.4.tgz#e270ae377e4c120cdcb7656ce66884a6218283dc" - integrity sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg== - dependencies: - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -14699,6 +14751,14 @@ string.prototype.matchall@^4.0.11: set-function-name "^2.0.2" side-channel "^1.0.6" +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trim@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" @@ -15751,14 +15811,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-browserslist-db@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" @@ -15775,6 +15827,14 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + update-diff@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/update-diff/-/update-diff-1.1.0.tgz#f510182d81ee819fb82c3a6b22b62bbdeda7808f" @@ -16155,10 +16215,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.92.1: - version "5.92.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.92.1.tgz#eca5c1725b9e189cffbd86e8b6c3c7400efc5788" - integrity sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA== +webpack@5.93.0: + version "5.93.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.93.0.tgz#2e89ec7035579bdfba9760d26c63ac5c3462a5e5" + integrity sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.5"