diff --git a/.drone.yml b/.drone.yml index aefdfb0010..ee27692df4 100644 --- a/.drone.yml +++ b/.drone.yml @@ -148,7 +148,7 @@ services: MINIO_ROOT_PASSWORD: minioadmin command: [ server, /data ] - name: pgsql - image: postgres:16-alpine + image: postgres:17-alpine environment: POSTGRES_USER: openbas POSTGRES_PASSWORD: openbas @@ -160,7 +160,7 @@ services: MINIO_ROOT_PASSWORD: minioadmin command: [ server, /data ] - name: pgsql-e2e - image: postgres:16-alpine + image: postgres:17-alpine environment: POSTGRES_USER: openbas POSTGRES_PASSWORD: openbas diff --git a/openbas-api/pom.xml b/openbas-api/pom.xml index 4f03e32341..d02c462cd9 100644 --- a/openbas-api/pom.xml +++ b/openbas-api/pom.xml @@ -6,7 +6,7 @@ io.openbas openbas-platform - 1.11.4 + 1.11.5 openbas-api @@ -22,7 +22,7 @@ 1.4 9.2.1 5.4.0 - 1.46.0 + 1.47.0 1.27.0-alpha @@ -48,12 +48,12 @@ io.openbas openbas-framework - 1.11.4 + 1.11.5 com.rabbitmq amqp-client - 5.24.0 + 5.25.0 org.springframework.boot diff --git a/openbas-api/src/main/java/io/openbas/aop/UserRoleDescription.java b/openbas-api/src/main/java/io/openbas/aop/UserRoleDescription.java new file mode 100644 index 0000000000..def3d2fce6 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/aop/UserRoleDescription.java @@ -0,0 +1,12 @@ +package io.openbas.aop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface UserRoleDescription { + boolean needAuthenticated() default true; +} diff --git a/openbas-api/src/main/java/io/openbas/execution/ExecutionExecutorService.java b/openbas-api/src/main/java/io/openbas/execution/ExecutionExecutorService.java index 4d104ee217..0d3aacf1e3 100644 --- a/openbas-api/src/main/java/io/openbas/execution/ExecutionExecutorService.java +++ b/openbas-api/src/main/java/io/openbas/execution/ExecutionExecutorService.java @@ -36,8 +36,7 @@ public class ExecutionExecutorService { private final OpenBASExecutorContextService openBASExecutorContextService; private final InjectStatusRepository injectStatusRepository; - public ExecutableInject launchExecutorContext(ExecutableInject executableInject, Inject inject) - throws InterruptedException { + public void launchExecutorContext(Inject inject) { // First, get the assets of this injects List assets = Stream.concat( @@ -76,8 +75,6 @@ public ExecutableInject launchExecutorContext(ExecutableInject executableInject, if (!atLeastOneExecution.get()) { throw new ExecutionExecutorException("No asset executed"); } - - return executableInject; } private void launchExecutorContextForAsset(Inject inject, Asset asset) { diff --git a/openbas-api/src/main/java/io/openbas/executors/Executor.java b/openbas-api/src/main/java/io/openbas/executors/Executor.java index c0cbd2110e..a2c31f9596 100644 --- a/openbas-api/src/main/java/io/openbas/executors/Executor.java +++ b/openbas-api/src/main/java/io/openbas/executors/Executor.java @@ -1,27 +1,26 @@ package io.openbas.executors; +import static io.openbas.database.model.ExecutionStatus.EXECUTING; import static io.openbas.utils.InjectionUtils.isInInjectableRange; import com.fasterxml.jackson.databind.ObjectMapper; import io.openbas.asset.QueueService; import io.openbas.database.model.*; -import io.openbas.database.model.InjectStatus; import io.openbas.database.model.Injector; -import io.openbas.database.repository.InjectRepository; import io.openbas.database.repository.InjectStatusRepository; import io.openbas.database.repository.InjectorRepository; import io.openbas.execution.ExecutableInject; import io.openbas.execution.ExecutionExecutorService; import io.openbas.rest.inject.service.InjectStatusService; import jakarta.annotation.Resource; -import java.time.Instant; -import java.util.Optional; +import java.io.IOException; +import java.util.concurrent.TimeoutException; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; -@RequiredArgsConstructor @Component +@RequiredArgsConstructor public class Executor { @Resource protected ObjectMapper mapper; @@ -32,58 +31,71 @@ public class Executor { private final InjectorRepository injectorRepository; - private final InjectRepository injectRepository; - private final QueueService queueService; private final ExecutionExecutorService executionExecutorService; private final InjectStatusService injectStatusService; - private InjectStatus executeExternal(ExecutableInject executableInject, Inject inject) { - InjectorContract injectorContract = - inject - .getInjectorContract() - .orElseThrow( - () -> new UnsupportedOperationException("Inject does not have a contract")); + private InjectStatus executeExternal(ExecutableInject executableInject, Injector injector) + throws IOException, TimeoutException { + Inject inject = executableInject.getInjection().getInject(); + String jsonInject = mapper.writeValueAsString(executableInject); + InjectStatus injectStatus = this.injectStatusRepository.findByInject(inject).orElseThrow(); + queueService.publish(injector.getType(), jsonInject); + injectStatus.addInfoTrace( + "The inject has been published and is now waiting to be consumed.", + ExecutionTraceAction.EXECUTION); + return this.injectStatusRepository.save(injectStatus); + } - InjectStatus status = injectStatusRepository.findByInject(inject).orElse(new InjectStatus()); - status.setTrackingSentDate(Instant.now()); - status.setInject(inject); - try { - String jsonInject = mapper.writeValueAsString(executableInject); - status.setName(ExecutionStatus.PENDING); // FIXME: need to be test with HTTP Collector - status.addTrace( - ExecutionTraceStatus.INFO, - "The inject has been published and is now waiting to be consumed.", - ExecutionTraceAction.EXECUTION, - null); - queueService.publish(injectorContract.getInjector().getType(), jsonInject); - } catch (Exception e) { - status.setName(ExecutionStatus.ERROR); - status.setTrackingEndDate(Instant.now()); - status.addErrorTrace(e.getMessage(), ExecutionTraceAction.COMPLETE); - } finally { - return injectStatusRepository.save(status); - } + private InjectStatus executeInternal(ExecutableInject executableInject, Injector injector) { + Inject inject = executableInject.getInjection().getInject(); + io.openbas.executors.Injector executor = + this.context.getBean(injector.getType(), io.openbas.executors.Injector.class); + Execution execution = executor.executeInjection(executableInject); + // After execution, expectations are already created + // Injection status is filled after complete execution + // Report inject execution + InjectStatus injectStatus = this.injectStatusRepository.findByInject(inject).orElseThrow(); + InjectStatus completeStatus = injectStatusService.fromExecution(execution, injectStatus); + return injectStatusRepository.save(completeStatus); } - private InjectStatus executeInternal(ExecutableInject executableInject, Inject inject) { + public InjectStatus execute(ExecutableInject executableInject) + throws IOException, TimeoutException { + Inject inject = executableInject.getInjection().getInject(); InjectorContract injectorContract = inject .getInjectorContract() .orElseThrow( () -> new UnsupportedOperationException("Inject does not have a contract")); - io.openbas.executors.Injector executor = - this.context.getBean( - injectorContract.getInjector().getType(), io.openbas.executors.Injector.class); - Execution execution = executor.executeInjection(executableInject); - Inject executedInject = injectRepository.findById(inject.getId()).orElseThrow(); - InjectStatus completeStatus = injectStatusService.fromExecution(execution, executedInject); - return injectStatusRepository.save(completeStatus); + // Depending on injector type (internal or external) execution must be done differently + Injector injector = + injectorRepository + .findByType(injectorContract.getInjector().getType()) + .orElseThrow( + () -> + new IllegalStateException( + "Injector not found for type: " + + injectorContract.getInjector().getType())); + + // Status + InjectStatus updatedStatus = + this.injectStatusService.initializeInjectStatus(inject.getId(), EXECUTING); + inject.setStatus(updatedStatus); + if (Boolean.TRUE.equals(injectorContract.getNeedsExecutor())) { + this.executionExecutorService.launchExecutorContext(inject); + } + if (injector.isExternal()) { + return executeExternal(executableInject, injector); + } else { + return executeInternal(executableInject, injector); + } } - public InjectStatus execute(ExecutableInject executableInject) { + public InjectStatus directExecute(ExecutableInject executableInject) + throws IOException, TimeoutException { boolean isScheduledInject = !executableInject.isDirect(); // If empty content, inject must be rejected Inject inject = executableInject.getInjection().getInject(); @@ -95,39 +107,6 @@ public InjectStatus execute(ExecutableInject executableInject) { throw new UnsupportedOperationException("Inject is now too old for execution"); } - InjectorContract injectorContract = - inject - .getInjectorContract() - .orElseThrow( - () -> new UnsupportedOperationException("Inject does not have a contract")); - - // Depending on injector type (internal or external) execution must be done differently - Optional externalInjector = - injectorRepository.findByType(injectorContract.getInjector().getType()); - - return externalInjector - .map(Injector::isExternal) - .map( - isExternal -> { - ExecutableInject newExecutableInject = executableInject; - if (injectorContract.getNeedsExecutor()) { - try { - newExecutableInject = - this.executionExecutorService.launchExecutorContext(executableInject, inject); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - if (isExternal) { - return executeExternal(newExecutableInject, inject); - } else { - return executeInternal(newExecutableInject, inject); - } - }) - .orElseThrow( - () -> - new IllegalStateException( - "External injector not found for type: " - + injectorContract.getInjector().getType())); + return this.execute(executableInject); } } diff --git a/openbas-api/src/main/java/io/openbas/injectors/caldera/CalderaExecutor.java b/openbas-api/src/main/java/io/openbas/injectors/caldera/CalderaExecutor.java index 9abd5d0b00..355c04c54c 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/caldera/CalderaExecutor.java +++ b/openbas-api/src/main/java/io/openbas/injectors/caldera/CalderaExecutor.java @@ -1,5 +1,6 @@ package io.openbas.injectors.caldera; +import static io.openbas.database.model.Command.COMMAND_TYPE; import static io.openbas.database.model.ExecutionTraces.getNewErrorTrace; import static io.openbas.database.model.ExecutionTraces.getNewInfoTrace; import static io.openbas.database.model.InjectExpectationSignature.*; @@ -126,6 +127,9 @@ public ExecutionProcess process( } assets.forEach( (asset, aBoolean) -> { + if (!(asset instanceof Endpoint) || !((Endpoint) asset).getActive()) { + return; + } try { Endpoint executionEndpoint = this.findAndRegisterAssetForExecution( @@ -140,6 +144,12 @@ public ExecutionProcess process( contract, additionalFields); if (result.contains("complete")) { + execution.addTrace( + getNewInfoTrace( + "Request to execute the ability sent to Caldera", + ExecutionTraceAction.START, + ((Endpoint) asset).getAgents().getFirst(), + List.of())); ExploitResult exploitResult = this.calderaService.exploitResult( executionEndpoint.getAgents().getFirst().getExternalReference(), @@ -150,7 +160,7 @@ public ExecutionProcess process( exploitResult.getCommand(), ExecutionTraceAction.EXECUTION, ((Endpoint) asset).getAgents().getFirst(), - List.of())); + List.of(exploitResult.getLinkId()))); // Compute expectations boolean isInGroup = assets.get( @@ -252,8 +262,6 @@ public ExecutionProcess process( assetGroups.forEach( (assetGroup -> computeExpectationsForAssetGroup(expectations, content, assetGroup))); - String message = "Caldera executed the ability on " + asyncIds.size() + " asset(s)"; - execution.addTrace(getNewInfoTrace(message, ExecutionTraceAction.EXECUTION, asyncIds)); injectExpectationService.buildAndSaveInjectExpectations(injection, expectations); return new ExecutionProcess(true); } @@ -281,6 +289,9 @@ public StatusPayload getPayloadOutput(String externalId) { statusPayload.setPayloadCommandBlocks( Collections.singletonList(payloadCommandBlock)); }); + statusPayload.setName(ability.getName()); + statusPayload.setType(COMMAND_TYPE); + statusPayload.setDescription(ability.getDescription()); statusPayload.setExternalId(externalId); } diff --git a/openbas-api/src/main/java/io/openbas/injectors/caldera/service/CalderaResultCollectorService.java b/openbas-api/src/main/java/io/openbas/injectors/caldera/service/CalderaResultCollectorService.java index e6344db4f3..97b7cbd09e 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/caldera/service/CalderaResultCollectorService.java +++ b/openbas-api/src/main/java/io/openbas/injectors/caldera/service/CalderaResultCollectorService.java @@ -78,43 +78,60 @@ public void run() { } else if (resultStatus.getPaw() != null && resultStatus.isComplete() && resultStatus.isFail()) { - injectStatus.addMayBePreventedTrace( - "Failed result for linkID " - + entry.getKey() - + " (" - + resultStatus.getContent() - + ")", - ExecutionTraceAction.COMPLETE, - entry.getValue()); + injectStatus.addTrace( + new ExecutionTraces( + injectStatus, + ExecutionTraceStatus.MAYBE_PREVENTED, + List.of(), + "Failed result for linkID " + + entry.getKey() + + " (" + + resultStatus.getContent() + + ")", + ExecutionTraceAction.COMPLETE, + entry.getValue(), + resultStatus.getFinish())); } else if (resultStatus.getPaw() != null && resultStatus.isComplete() && !resultStatus.isFail()) { - injectStatus.addSuccess( - "Success result for linkID " - + entry.getKey() - + " (" - + resultStatus.getContent() - + ")", - ExecutionTraceAction.COMPLETE, - entry.getValue()); + injectStatus.addTrace( + new ExecutionTraces( + injectStatus, + ExecutionTraceStatus.SUCCESS, + List.of(), + "Success result for linkID " + + entry.getKey() + + " (" + + resultStatus.getContent() + + ")", + ExecutionTraceAction.COMPLETE, + entry.getValue(), + resultStatus.getFinish())); } else if (resultStatus.getPaw() != null && !resultStatus.isComplete() && injectStatus .getTrackingSentDate() .isBefore(Instant.now().minus(5L, ChronoUnit.MINUTES))) { - injectStatus.addMayBePreventedTrace( - "Timeout on linkID " + entry.getKey() + ", injection has failed", - ExecutionTraceAction.COMPLETE, - entry.getValue()); + + injectStatus.addTrace( + new ExecutionTraces( + injectStatus, + ExecutionTraceStatus.MAYBE_PREVENTED, + List.of(), + "Timeout on linkID " + entry.getKey() + ", injection has failed", + ExecutionTraceAction.COMPLETE, + entry.getValue(), + resultStatus.getFinish())); + log.log(Level.INFO, "Timeout on linkID " + entry.getKey() + ", injection has failed"); } } Inject relatedInject = injectStatus.getInject(); if (injectStatusService.isAllInjectAssetsExecuted(relatedInject)) { - injectStatusService.updateFinalInjectStatus(injectStatus, resultStatus.getFinish()); + injectStatusService.updateFinalInjectStatus(injectStatus); } injectRepository.save(relatedInject); diff --git a/openbas-api/src/main/java/io/openbas/injectors/challenge/ChallengeExecutor.java b/openbas-api/src/main/java/io/openbas/injectors/challenge/ChallengeExecutor.java index af94e8ffd2..850c4bcbd5 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/challenge/ChallengeExecutor.java +++ b/openbas-api/src/main/java/io/openbas/injectors/challenge/ChallengeExecutor.java @@ -63,6 +63,9 @@ public ExecutionProcess process( ChallengeContent content = contentConvert(injection, ChallengeContent.class); List challenges = fromIterable(challengeRepository.findAllById(content.getChallenges())); + if (challenges.isEmpty()) { + throw new UnsupportedOperationException("Inject needs at least one challenge"); + } String contract = injection .getInjection() diff --git a/openbas-api/src/main/java/io/openbas/injectors/channel/ChannelExecutor.java b/openbas-api/src/main/java/io/openbas/injectors/channel/ChannelExecutor.java index 755b083da5..0d4a7e1d59 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/channel/ChannelExecutor.java +++ b/openbas-api/src/main/java/io/openbas/injectors/channel/ChannelExecutor.java @@ -65,7 +65,9 @@ public ExecutionProcess process( try { ChannelContent content = contentConvert(injection, ChannelContent.class); List
articles = fromIterable(articleRepository.findAllById(content.getArticles())); - + if (articles.isEmpty()) { + throw new UnsupportedOperationException("Inject needs at least one article"); + } String contract = injection .getInjection() @@ -81,6 +83,7 @@ public ExecutionProcess process( articles.stream().map(Article::getName).collect(Collectors.joining(",")); String publishedMessage = "Articles (" + articleNames + ") marked as published"; execution.addTrace(getNewSuccessTrace(publishedMessage, ExecutionTraceAction.COMPLETE)); + Exercise exercise = injection.getInjection().getExercise(); // Send the publication message. if (content.isEmailing()) { diff --git a/openbas-api/src/main/java/io/openbas/injectors/email/service/EmailService.java b/openbas-api/src/main/java/io/openbas/injectors/email/service/EmailService.java index 189b7c1957..e0731496c6 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/email/service/EmailService.java +++ b/openbas-api/src/main/java/io/openbas/injectors/email/service/EmailService.java @@ -69,7 +69,7 @@ public void sendEmail( recipients.add(new InternetAddress(userContext.getUser().getEmail())); } mimeMessage.setRecipients(Message.RecipientType.TO, recipients.toArray(InternetAddress[]::new)); - this.sendEmailWithRetry(mimeMessage); + this.sendEmailWithRetry(execution, mimeMessage); String emails = usersContext.stream().map(c -> c.getUser().getEmail()).collect(joining(", ")); List userIds = usersContext.stream().map(c -> c.getUser().getId()).toList(); execution.addTrace( @@ -100,9 +100,9 @@ public void sendEmail( if (mustBeEncrypted) { MimeMessage encMessage = getEncryptedMimeMessage(userContext, from, replyTos, subject, email, mimeMessage); - this.sendEmailWithRetry(encMessage); + this.sendEmailWithRetry(execution, encMessage); } else { - this.sendEmailWithRetry(mimeMessage); + this.sendEmailWithRetry(execution, mimeMessage); } List userIds = List.of(userContext.getUser().getId()); execution.addTrace( @@ -227,17 +227,19 @@ private MimeMessage getEncryptedMimeMessage( return encMessage; } - private void sendEmailWithRetry(MimeMessage mimeMessage) throws Exception { + private void sendEmailWithRetry(Execution execution, MimeMessage mimeMessage) + throws InterruptedException { for (int i = 0; i < 3; i++) { try { emailSender.send(mimeMessage); - break; + return; } catch (Exception e) { - if (i == 2) { - throw e; - } + execution.addTrace( + getNewInfoTrace( + "Failed to send mail" + e.getMessage(), ExecutionTraceAction.EXECUTION)); Thread.sleep(2000); } } + throw new InterruptedException("Failed to send mail after 3 attempts"); } } diff --git a/openbas-api/src/main/java/io/openbas/injectors/manual/ManualContract.java b/openbas-api/src/main/java/io/openbas/injectors/manual/ManualContract.java index 6e0e09c63a..34fa0a0d70 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/manual/ManualContract.java +++ b/openbas-api/src/main/java/io/openbas/injectors/manual/ManualContract.java @@ -3,8 +3,10 @@ import static io.openbas.helper.SupportedLanguage.en; import static io.openbas.helper.SupportedLanguage.fr; import static io.openbas.injector_contract.Contract.manualContract; +import static io.openbas.injector_contract.ContractCardinality.Multiple; import static io.openbas.injector_contract.ContractDef.contractBuilder; -import static io.openbas.injector_contract.fields.ContractTextArea.textareaField; +import static io.openbas.injector_contract.fields.ContractExpectations.expectationsField; +import static io.openbas.injector_contract.fields.ContractTeam.teamField; import io.openbas.database.model.Endpoint; import io.openbas.helper.SupportedLanguage; @@ -24,6 +26,31 @@ public class ManualContract extends Contractor { public static final String MANUAL_DEFAULT = "d02e9132-b9d0-4daa-b3b1-4b9871f8472c"; + private final List contracts; + + private final ContractConfig config; + + public ManualContract() { + + ContractElement teams = teamField("teams", "Teams", Multiple); + ContractElement expectations = expectationsField("expectations", "Expectations"); + + Map label = Map.of(en, "Manual", fr, "Manuel"); + config = new ContractConfig(TYPE, label, "#009688", "#009688", "/img/manual.png", isExpose()); + + List instance = + contractBuilder().mandatoryOnCondition(teams, expectations).optional(expectations).build(); + contracts = + List.of( + manualContract( + config, + MANUAL_DEFAULT, + Map.of(en, "Manual", fr, "Manuel"), + instance, + List.of(Endpoint.PLATFORM_TYPE.Internal), + false)); + } + @Override public boolean isExpose() { return true; @@ -36,23 +63,12 @@ public String getType() { @Override public ContractConfig getConfig() { - Map label = Map.of(en, "Manual", fr, "Manuel"); - return new ContractConfig(TYPE, label, "#009688", "#009688", "/img/manual.png", isExpose()); + return config; } @Override public List contracts() { - ContractConfig contractConfig = getConfig(); - List instance = - contractBuilder().mandatory(textareaField("content", "Content")).build(); - return List.of( - manualContract( - contractConfig, - MANUAL_DEFAULT, - Map.of(en, "Manual", fr, "Manuel"), - instance, - List.of(Endpoint.PLATFORM_TYPE.Internal), - false)); + return contracts; } @Override diff --git a/openbas-api/src/main/java/io/openbas/injectors/manual/ManualExecutor.java b/openbas-api/src/main/java/io/openbas/injectors/manual/ManualExecutor.java index 8e4107f590..8960e61277 100644 --- a/openbas-api/src/main/java/io/openbas/injectors/manual/ManualExecutor.java +++ b/openbas-api/src/main/java/io/openbas/injectors/manual/ManualExecutor.java @@ -1,18 +1,48 @@ package io.openbas.injectors.manual; import io.openbas.database.model.Execution; +import io.openbas.database.model.ExecutionTraceAction; +import io.openbas.database.model.ExecutionTraces; import io.openbas.execution.ExecutableInject; import io.openbas.executors.Injector; +import io.openbas.injectors.manual.model.ManualContent; import io.openbas.model.ExecutionProcess; +import io.openbas.model.Expectation; +import io.openbas.model.expectation.ManualExpectation; +import io.openbas.service.InjectExpectationService; import jakarta.validation.constraints.NotNull; +import java.util.List; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @Component(ManualContract.TYPE) +@RequiredArgsConstructor public class ManualExecutor extends Injector { + private final InjectExpectationService injectExpectationService; + @Override public ExecutionProcess process( - @NotNull final Execution execution, @NotNull final ExecutableInject injection) { - throw new UnsupportedOperationException("Manual inject cannot be executed"); + @NotNull final Execution execution, @NotNull final ExecutableInject injection) + throws Exception { + + ManualContent content = contentConvert(injection, ManualContent.class); + + List expectations = + content.getExpectations().stream() + .flatMap( + (entry) -> + switch (entry.getType()) { + case MANUAL -> Stream.of((Expectation) new ManualExpectation(entry)); + default -> Stream.of(); + }) + .toList(); + + injectExpectationService.buildAndSaveInjectExpectations(injection, expectations); + execution.addTrace( + ExecutionTraces.getNewSuccessTrace( + "Manual inject execution", ExecutionTraceAction.COMPLETE)); + return new ExecutionProcess(false); } } diff --git a/openbas-api/src/main/java/io/openbas/injectors/manual/model/ManualContent.java b/openbas-api/src/main/java/io/openbas/injectors/manual/model/ManualContent.java new file mode 100644 index 0000000000..cb51fce24d --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/injectors/manual/model/ManualContent.java @@ -0,0 +1,15 @@ +package io.openbas.injectors.manual.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.openbas.model.inject.form.Expectation; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ManualContent { + @JsonProperty("expectations") + private List expectations = new ArrayList<>(); +} diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_53__Update_Commands_In_Inject_Status.java b/openbas-api/src/main/java/io/openbas/migration/V3_53__Update_Commands_In_Inject_Status.java index 5fcd2b5753..b28be0000d 100644 --- a/openbas-api/src/main/java/io/openbas/migration/V3_53__Update_Commands_In_Inject_Status.java +++ b/openbas-api/src/main/java/io/openbas/migration/V3_53__Update_Commands_In_Inject_Status.java @@ -64,6 +64,9 @@ public void migrate(Context context) throws Exception { null, null, null, + null, + null, + null, externalId, null, null, diff --git a/openbas-api/src/main/java/io/openbas/migration/V3_65__Update_Inject_Status_status_payload.java b/openbas-api/src/main/java/io/openbas/migration/V3_65__Update_Inject_Status_status_payload.java new file mode 100644 index 0000000000..4bb4ffc491 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/migration/V3_65__Update_Inject_Status_status_payload.java @@ -0,0 +1,37 @@ +package io.openbas.migration; + +import java.sql.Connection; +import java.sql.Statement; +import org.flywaydb.core.api.migration.BaseJavaMigration; +import org.flywaydb.core.api.migration.Context; +import org.springframework.stereotype.Component; + +@Component +public class V3_65__Update_Inject_Status_status_payload extends BaseJavaMigration { + + @Override + public void migrate(Context context) throws Exception { + Connection connection = context.getConnection(); + Statement statement = connection.createStatement(); + + String addParamsToStatusPayload = + "UPDATE injects_statuses " + + "SET status_payload_output = jsonb_set(" + + " jsonb_set(" + + " jsonb_set(status_payload_output::jsonb, '{payload_name}', 'null'::jsonb), " + + " '{payload_description}', 'null'::jsonb), " + + " '{payload_type}', 'null'::jsonb) " + + "WHERE status_payload_output IS NOT NULL;"; + + String updatePayloadCommandBlocks = + "UPDATE injects_statuses " + + "SET status_payload_output = jsonb_set(" + + " status_payload_output::jsonb," + + " '{payload_command_blocks}'," + + " '[]'::jsonb)" + + "WHERE status_payload_output->'payload_command_blocks' IS NULL;"; + + statement.executeUpdate(addParamsToStatusPayload); + statement.executeUpdate(updatePayloadCommandBlocks); + } +} diff --git a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/AgentStatusOutput.java b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/AgentStatusOutput.java new file mode 100644 index 0000000000..e07a9a9aca --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/AgentStatusOutput.java @@ -0,0 +1,51 @@ +package io.openbas.rest.atomic_testing.form; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@Schema(description = "Represents the output result details of an agent execution") +public class AgentStatusOutput { + + @JsonProperty("asset_id") + @Schema(description = "Endpoint ID") + @NotNull + private String assetId; + + @JsonProperty("agent_id") + @NotNull + private String agentId; + + @JsonProperty("agent_name") + private String agentName; + + @JsonProperty("agent_executor_name") + private String agentExecutorName; + + @JsonProperty("agent_executor_type") + private String agentExecutorType; + + @JsonProperty("tracking_sent_date") + private Instant trackingSentDate; + + @JsonProperty("tracking_end_date") + private Instant trackingEndDate; + + @JsonProperty("agent_status_name") + @Schema( + description = "Execution status of the agent", + example = "SUCCESS, ERROR, MAYBE_PREVENTED...") + private String statusName; + + @Builder.Default + @JsonProperty("agent_traces") + @Schema(description = "List of agent execution traces") + private List agentTraces = new ArrayList<>(); +} diff --git a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/ExecutionTracesOutput.java b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/ExecutionTracesOutput.java new file mode 100644 index 0000000000..f18c8ed897 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/ExecutionTracesOutput.java @@ -0,0 +1,39 @@ +package io.openbas.rest.atomic_testing.form; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.openbas.database.model.ExecutionTraceAction; +import io.openbas.database.model.ExecutionTraceStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@Schema(description = "Represents a single execution trace detail") +public class ExecutionTracesOutput { + @NotNull + @JsonProperty("execution_status") + @Schema( + description = "The status of the execution trace", + example = "SUCCESS, ERROR, COMMAND_NOT_FOUND, WARNING, COMMAND_CANNOT_BE_EXECUTED..") + private ExecutionTraceStatus status; + + @NotNull + @JsonProperty("execution_time") + private Instant time; + + @NotNull + @JsonProperty("execution_message") + @Schema(description = "A detailed message describing the execution") + private String message; + + @NotNull + @JsonProperty("execution_action") + @Schema( + description = "The action that created this execution trace", + example = + "START, PREREQUISITE_CHECK, PREREQUISITE_EXECUTION, EXECUTION, CLEANUP_EXECUTION or COMPLETE") + private ExecutionTraceAction action; +} diff --git a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/InjectStatusOutput.java b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/InjectStatusOutput.java index a96a8c5adb..d4aba3c4f1 100644 --- a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/InjectStatusOutput.java +++ b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/InjectStatusOutput.java @@ -4,18 +4,17 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openbas.database.model.ExecutionStatus; -import io.openbas.database.model.ExecutionTraces; import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.ArrayList; import java.util.List; import lombok.Builder; +import lombok.Data; import lombok.Getter; -import lombok.Setter; +import lombok.experimental.SuperBuilder; -@Setter -@Getter -@Builder +@Data +@SuperBuilder public class InjectStatusOutput { @JsonProperty("status_id") @@ -31,8 +30,12 @@ public String getName() { } @Builder.Default - @JsonProperty("status_traces") - private List traces = new ArrayList<>(); + @JsonProperty("status_main_traces") + private List traces = new ArrayList<>(); + + @Builder.Default + @JsonProperty("status_traces_by_agent") + private List tracesByAgent = new ArrayList<>(); @JsonProperty("tracking_sent_date") private Instant trackingSentDate; diff --git a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/StatusPayloadOutput.java b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/StatusPayloadOutput.java index fb06df5395..29bac1407e 100644 --- a/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/StatusPayloadOutput.java +++ b/openbas-api/src/main/java/io/openbas/rest/atomic_testing/form/StatusPayloadOutput.java @@ -59,7 +59,7 @@ public class StatusPayloadOutput { private Set tags; @JsonProperty("executable_file") - private Document executableFile; + private StatusPayloadDocument executableFile; @JsonProperty("executable_arch") @Enumerated(EnumType.STRING) @@ -67,7 +67,7 @@ public class StatusPayloadOutput { Payload.PAYLOAD_EXECUTION_ARCH.ALL_ARCHITECTURES; @JsonProperty("file_drop_file") - private Document fileDropFile; + private StatusPayloadDocument fileDropFile; @JsonProperty("dns_resolution_hostname") private String hostname; diff --git a/openbas-api/src/main/java/io/openbas/rest/channel/ChannelHelper.java b/openbas-api/src/main/java/io/openbas/rest/channel/ChannelHelper.java index f81f512376..602f677a16 100644 --- a/openbas-api/src/main/java/io/openbas/rest/channel/ChannelHelper.java +++ b/openbas-api/src/main/java/io/openbas/rest/channel/ChannelHelper.java @@ -39,9 +39,10 @@ public static List
enrichArticleWithVirtualPublication( .filter( inject -> inject - .getInjectorContract() - .map(contract -> contract.getId().equals(CHANNEL_PUBLISH)) - .orElse(false)) + .getInjectorContract() + .map(contract -> contract.getId().equals(CHANNEL_PUBLISH)) + .orElse(false) + && inject.getExercise() != null) .filter(inject -> inject.getContent() != null) .sorted(Comparator.comparing(Inject::getDependsDuration)) .flatMap(inject -> convertToVirtualArticles(inject, now, mapper)) diff --git a/openbas-api/src/main/java/io/openbas/rest/helper/RestBehavior.java b/openbas-api/src/main/java/io/openbas/rest/helper/RestBehavior.java index 9b2d7c84f3..78033babd4 100644 --- a/openbas-api/src/main/java/io/openbas/rest/helper/RestBehavior.java +++ b/openbas-api/src/main/java/io/openbas/rest/helper/RestBehavior.java @@ -12,6 +12,10 @@ import io.openbas.database.model.User; import io.openbas.database.repository.UserRepository; import io.openbas.rest.exception.*; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import jakarta.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @@ -94,6 +98,13 @@ public ValidationErrorBag handleBadRequestExceptions(ImportException ex) { @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(AuthenticationException.class) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content(schema = @Schema(implementation = ValidationErrorBag.class))), + }) public ValidationErrorBag handleValidationExceptions() { ValidationErrorBag bag = new ValidationErrorBag(HttpStatus.UNAUTHORIZED.value(), "AUTHENTIFICATION_FAILED"); @@ -107,17 +118,32 @@ public ValidationErrorBag handleValidationExceptions() { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(AccessDeniedException.class) - public ValidationErrorBag handleAccessDeniedExceptions() { + @ApiResponses( + value = { + @ApiResponse( + responseCode = "404", + description = "Resource not found", + content = @Content(schema = @Schema(implementation = ResponseEntity.class))), + }) + public ResponseEntity handleAccessDeniedExceptions() { // When the user does not have the appropriate access rights, return 404 Not Found. // This response indicates that the resource does not exist, preventing any information // disclosure // about the resource and reducing the risk of brute force attacks by not confirming its // existence - return new ValidationErrorBag(HttpStatus.NOT_FOUND.value(), "NOT_FOUND"); + return new ResponseEntity<>( + new ErrorMessage(HttpStatus.NOT_FOUND.getReasonPhrase()), HttpStatus.NOT_FOUND); } @ResponseStatus(HttpStatus.CONFLICT) @ExceptionHandler(DataIntegrityViolationException.class) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "409", + description = "Conflict", + content = @Content(schema = @Schema(implementation = ViolationErrorBag.class))), + }) public ViolationErrorBag handleIntegrityException(DataIntegrityViolationException e) { ViolationErrorBag errorBag = new ViolationErrorBag(); errorBag.setType(DataIntegrityViolationException.class.getSimpleName()); @@ -133,6 +159,13 @@ public ViolationErrorBag handleIntegrityException(DataIntegrityViolationExceptio } @ExceptionHandler(ElementNotFoundException.class) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "404", + description = "Resource not found", + content = @Content(schema = @Schema(implementation = ResponseEntity.class))), + }) public ResponseEntity handleElementNotFoundException(ElementNotFoundException ex) { ErrorMessage message = new ErrorMessage("Element not found: " + ex.getMessage()); log.warning("ElementNotFoundException: " + ex.getMessage()); diff --git a/openbas-api/src/main/java/io/openbas/rest/helper/UserRoleDescriptionCustomizer.java b/openbas-api/src/main/java/io/openbas/rest/helper/UserRoleDescriptionCustomizer.java new file mode 100644 index 0000000000..0647c73cb5 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/helper/UserRoleDescriptionCustomizer.java @@ -0,0 +1,89 @@ +package io.openbas.rest.helper; + +import io.openbas.aop.UserRoleDescription; +import io.openbas.database.model.User; +import io.swagger.v3.oas.models.Operation; +import org.apache.commons.lang3.StringUtils; +import org.springdoc.core.customizers.OperationCustomizer; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; + +@Component +public class UserRoleDescriptionCustomizer implements OperationCustomizer { + @Override + public Operation customize(Operation operation, HandlerMethod handlerMethod) { + UserRoleDescription annotation; + // We check if we have the annotation on the method as it will take priority on the class + if (handlerMethod.getMethodAnnotation(UserRoleDescription.class) != null) { + annotation = handlerMethod.getMethodAnnotation(UserRoleDescription.class); + } else { + // If not, we check if we have the annotation on the class + annotation = handlerMethod.getBeanType().getAnnotation(UserRoleDescription.class); + } + // If we found any annotation UserRoleDescription + if (annotation != null) { + // We get the Secured annotation + var securedAnnotation = handlerMethod.getMethodAnnotation(Secured.class); + String description = + operation.getDescription() == null ? "" : (operation.getDescription() + "
"); + // If we found a secured annotation + if (securedAnnotation != null) { + // We add the required role in the description + description += + "**Required role :** ***" + + String.join("*** or ***", securedAnnotation.value()) + + "***"; + } else if (annotation.needAuthenticated()) { + // If there are no secured annotation and we need to be authenticated + // Then we add all the existing role in the description + description += + "**Required role :** ***" + String.join("*** or ***", User.ALL_ROLES) + "***"; + } else { + // If no secured annotation and we don't need authentication, then we show that no roles are + // required + description += "**Required role :** none"; + } + + operation.setDescription(description + getSpecialRequirements(handlerMethod)); + } + return operation; + } + + private String getSpecialRequirements(HandlerMethod handlerMethod) { + String specialRequirement = StringUtils.EMPTY; + var preAuthorizeAnnotation = handlerMethod.getMethodAnnotation(PreAuthorize.class); + if (preAuthorizeAnnotation != null) { + specialRequirement += "
**Special Requirement :** "; + String preAuthorize = preAuthorizeAnnotation.value(); + if (preAuthorize.startsWith("isExercisePlanner") + || preAuthorize.startsWith("isSimulationPlanner")) { + specialRequirement += + "You need to be an admin or a planner of the simulation to call this endpoint"; + } else if (preAuthorize.startsWith("isExerciseObserver")) { + specialRequirement += + "You need to be an admin or an observer of the simulation to call this endpoint"; + } else if (preAuthorize.startsWith("isExercisePlayer")) { + specialRequirement += + "You need to be an admin or a player of the simulation to call this endpoint"; + } else if (preAuthorize.startsWith("isExerciseObserverOrPlayer")) { + specialRequirement += + "You need to be an admin, an observer or a player of the simulation to call this endpoint"; + } else if (preAuthorize.startsWith("isScenarioPlanner")) { + specialRequirement += + "You need to be an admin or a planner of the scenario to call this endpoint"; + } else if (preAuthorize.startsWith("isScenarioObserver")) { + specialRequirement += + "You need to be an admin or an observer of the scenario to call this endpoint"; + } else if (preAuthorize.startsWith("isPlanner")) { + specialRequirement += "You need to be an admin or a planner to call this endpoint"; + } else if (preAuthorize.startsWith("isObserver")) { + specialRequirement += "You need to be an admin or an observer to call this endpoint"; + } else if (preAuthorize.startsWith("isPlayer")) { + specialRequirement += "You need to be a player to call this endpoint"; + } + } + return specialRequirement; + } +} diff --git a/openbas-api/src/main/java/io/openbas/rest/helper/ValidationErrorBag.java b/openbas-api/src/main/java/io/openbas/rest/helper/ValidationErrorBag.java index fdacc1d291..c9299333c9 100644 --- a/openbas-api/src/main/java/io/openbas/rest/helper/ValidationErrorBag.java +++ b/openbas-api/src/main/java/io/openbas/rest/helper/ValidationErrorBag.java @@ -1,39 +1,35 @@ package io.openbas.rest.helper; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import java.util.Map; +import lombok.Data; +@Data class ValidationContent { + @Schema(description = "A list of errors") private List errors; public ValidationContent(String error) { this.errors = List.of(error); } - - public List getErrors() { - return errors; - } - - public void setErrors(List errors) { - this.errors = errors; - } } +@Data class ValidationError { + @Schema(description = "Map of errors by input") private Map children; - - public Map getChildren() { - return children; - } - - public void setChildren(Map children) { - this.children = children; - } } +@Data public class ValidationErrorBag { + @Schema(description = "Return code") private int code = 400; + + @Schema(description = "Return message") private String message = "Validation Failed"; + + @Schema(description = "Errors raised") private ValidationError errors; public ValidationErrorBag() { @@ -44,28 +40,4 @@ public ValidationErrorBag(int code, String message) { this.code = code; this.message = message; } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public ValidationError getErrors() { - return errors; - } - - public void setErrors(ValidationError errors) { - this.errors = errors; - } } diff --git a/openbas-api/src/main/java/io/openbas/rest/helper/ViolationErrorBag.java b/openbas-api/src/main/java/io/openbas/rest/helper/ViolationErrorBag.java index 19a4371391..38348e499b 100644 --- a/openbas-api/src/main/java/io/openbas/rest/helper/ViolationErrorBag.java +++ b/openbas-api/src/main/java/io/openbas/rest/helper/ViolationErrorBag.java @@ -1,34 +1,17 @@ package io.openbas.rest.helper; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data public class ViolationErrorBag { + @Schema(description = "The type of error") private String type; + @Schema(description = "The message of the error") private String message; + @Schema(description = "The error") private String error; - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } } diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/ExerciseInjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/ExerciseInjectApi.java index 46b7450d15..21c7a812c0 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/ExerciseInjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/ExerciseInjectApi.java @@ -6,9 +6,9 @@ import io.openbas.database.model.Base; import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectTestStatus; import io.openbas.rest.helper.RestBehavior; import io.openbas.rest.inject.output.InjectOutput; +import io.openbas.rest.inject.output.InjectTestStatusOutput; import io.openbas.service.InjectSearchService; import io.openbas.service.InjectTestStatusService; import io.openbas.utils.pagination.SearchPaginationInput; @@ -79,7 +79,7 @@ public Iterable exerciseInjectsSimple( } @PostMapping("/api/exercise/{exerciseId}/injects/test") - public Page findAllExerciseInjectTests( + public Page findAllExerciseInjectTests( @PathVariable @NotBlank String exerciseId, @RequestBody @Valid SearchPaginationInput searchPaginationInput) { return injectTestStatusService.findAllInjectTestsByExerciseId( diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java index 0afcc25a23..e2673145f8 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java @@ -44,6 +44,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.util.*; +import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.StreamSupport; import lombok.RequiredArgsConstructor; @@ -83,11 +84,11 @@ public class InjectApi extends RestBehavior { private final ExecutionContextService executionContextService; private final ScenarioService scenarioService; private final InjectService injectService; - private final ExecutableInjectService executableInjectService; private final InjectSearchService injectSearchService; private final InjectDuplicateService injectDuplicateService; private final TagRuleService tagRuleService; private final InjectStatusService injectStatusService; + private final ExecutableInjectService executableInjectService; // -- INJECTS -- @@ -123,11 +124,17 @@ public Inject injectExecutionCallback( return injectStatusService.handleInjectExecutionCallback(injectId, agentId, input); } - @GetMapping(INJECT_URI + "/{injectId}/executable-payload") + @Secured(ROLE_ADMIN) + @GetMapping(INJECT_URI + "/{injectId}/{agentId}/executable-payload") + @Operation( + summary = "Get the payload ready to be executed", + description = + "This endpoint is invoked by implants to retrieve a payload command that's pre-configured and ready for execution.") @Tracing(name = "Get payload ready to be executed", layer = "api", operation = "GET") - public Payload getExecutablePayloadInject(@PathVariable @NotBlank final String injectId) + public Payload getExecutablePayloadInject( + @PathVariable @NotBlank final String injectId, @PathVariable @NotBlank final String agentId) throws Exception { - return executableInjectService.getExecutablePayloadInject(injectId); + return executableInjectService.getExecutablePayloadAndUpdateInjectStatus(injectId, agentId); } // -- EXERCISES -- @@ -383,7 +390,12 @@ public InjectStatus executeInject( savedInject.getAssetGroups(), userInjectContexts); file.ifPresent(injection::addDirectAttachment); - return executor.execute(injection); + try { + return executor.directExecute(injection); + } catch (Exception e) { + log.log(Level.WARNING, e.getMessage(), e); + return injectStatusService.failInjectStatus(inject.getId(), e.getMessage()); + } } @Transactional(rollbackFor = Exception.class) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/ScenarioInjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/ScenarioInjectApi.java index 6693b3cf32..bfee0e20b0 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/ScenarioInjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/ScenarioInjectApi.java @@ -6,9 +6,9 @@ import io.openbas.database.model.Base; import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectTestStatus; import io.openbas.rest.helper.RestBehavior; import io.openbas.rest.inject.output.InjectOutput; +import io.openbas.rest.inject.output.InjectTestStatusOutput; import io.openbas.service.InjectSearchService; import io.openbas.service.InjectTestStatusService; import io.openbas.telemetry.Tracing; @@ -64,7 +64,7 @@ public Iterable scenarioInjectsSimple( } @PostMapping("/api/scenario/{scenarioId}/injects/test") - public Page findAllScenarioInjectTests( + public Page findAllScenarioInjectTests( @PathVariable @NotBlank String scenarioId, @RequestBody @Valid SearchPaginationInput searchPaginationInput) { return injectTestStatusService.findAllInjectTestsByScenarioId( diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/form/InjectExecutionInput.java b/openbas-api/src/main/java/io/openbas/rest/inject/form/InjectExecutionInput.java index 22826893bc..c469336037 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/form/InjectExecutionInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/form/InjectExecutionInput.java @@ -4,11 +4,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; -@Setter -@Getter +@Data public class InjectExecutionInput { @NotBlank(message = MANDATORY_MESSAGE) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/output/InjectTestStatusOutput.java b/openbas-api/src/main/java/io/openbas/rest/inject/output/InjectTestStatusOutput.java new file mode 100644 index 0000000000..4b87588aa0 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/inject/output/InjectTestStatusOutput.java @@ -0,0 +1,25 @@ +package io.openbas.rest.inject.output; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.openbas.rest.atomic_testing.form.InjectStatusOutput; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +@Setter +@Getter +@SuperBuilder +public class InjectTestStatusOutput extends InjectStatusOutput { + + @JsonProperty("inject_id") + @NotNull + private String injectId; + + @JsonProperty("inject_title") + @NotNull + private String injectTitle; + + @JsonProperty("inject_type") + private String injectType; +} diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/ExecutableInjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/ExecutableInjectService.java index 87daed2623..258c47b770 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/ExecutableInjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/ExecutableInjectService.java @@ -4,10 +4,10 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.openbas.database.model.*; -import io.openbas.database.repository.InjectRepository; import io.openbas.injectors.openbas.model.OpenBASImplantInjectContent; import io.openbas.injectors.openbas.util.OpenBASObfuscationMap; import io.openbas.rest.exception.ElementNotFoundException; +import io.openbas.rest.payload.service.PayloadService; import java.util.ArrayList; import java.util.Base64; import java.util.List; @@ -20,8 +20,9 @@ @Service public class ExecutableInjectService { - private final InjectRepository injectRepository; private final InjectService injectService; + private final InjectStatusService injectStatusService; + private final PayloadService payloadService; private static final Pattern argumentsRegex = Pattern.compile("#\\{([^#{}]+)}"); private static final Pattern cmdVariablesRegex = Pattern.compile("%(\\w+)%"); @@ -121,23 +122,40 @@ private String processAndEncodeCommand( return Base64.getEncoder().encodeToString(computedCommand.getBytes()); } - public Payload getExecutablePayloadInject(String injectId) throws Exception { - Inject inject = - this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); + public Payload getExecutablePayloadAndUpdateInjectStatus(String injectId, String agentId) + throws Exception { + Payload payloadToExecute = getExecutablePayloadInject(injectId); + this.injectStatusService.addStartImplantExecutionTraceByInject( + injectId, agentId, "Implant is up and starting execution"); + return payloadToExecute; + } + + private Payload getExecutablePayloadInject(String injectId) throws Exception { + Inject inject = injectService.inject(injectId); InjectorContract contract = - inject.getInjectorContract().orElseThrow(ElementNotFoundException::new); + inject + .getInjectorContract() + .orElseThrow(() -> new ElementNotFoundException("Inject contract not found")); OpenBASImplantInjectContent content = injectService.convertInjectContent(inject, OpenBASImplantInjectContent.class); String obfuscator = content.getObfuscator() != null ? content.getObfuscator() : "plain-text"; + if (contract.getPayload() == null) { + throw new ElementNotFoundException("Payload not found"); + } + Payload payloadToExecute = payloadService.generateDuplicatedPayload(contract.getPayload()); + // prerequisite + List prerequisiteList = new ArrayList<>(); contract .getPayload() .getPrerequisites() .forEach( prerequisite -> { + PayloadPrerequisite payload = new PayloadPrerequisite(); + payload.setExecutor(prerequisite.getExecutor()); if (hasText(prerequisite.getCheckCommand())) { - prerequisite.setCheckCommand( + payload.setCheckCommand( processAndEncodeCommand( prerequisite.getCheckCommand(), prerequisite.getExecutor(), @@ -146,7 +164,7 @@ public Payload getExecutablePayloadInject(String injectId) throws Exception { obfuscator)); } if (hasText(prerequisite.getGetCommand())) { - prerequisite.setGetCommand( + payload.setGetCommand( processAndEncodeCommand( prerequisite.getGetCommand(), prerequisite.getExecutor(), @@ -154,24 +172,26 @@ public Payload getExecutablePayloadInject(String injectId) throws Exception { inject.getContent(), obfuscator)); } + prerequisiteList.add(payload); }); + payloadToExecute.setPrerequisites(prerequisiteList); // cleanup if (contract.getPayload().getCleanupCommand() != null) { - contract - .getPayload() - .setCleanupCommand( - processAndEncodeCommand( - contract.getPayload().getCleanupCommand(), - contract.getPayload().getCleanupExecutor(), - contract.getPayload().getArguments(), - inject.getContent(), - obfuscator)); + payloadToExecute.setCleanupExecutor(contract.getPayload().getCleanupExecutor()); + payloadToExecute.setCleanupCommand( + processAndEncodeCommand( + contract.getPayload().getCleanupCommand(), + contract.getPayload().getCleanupExecutor(), + contract.getPayload().getArguments(), + inject.getContent(), + obfuscator)); } // Command if (contract.getPayload().getTypeEnum().equals(PayloadType.COMMAND)) { - Command payloadCommand = (Command) contract.getPayload(); + Command payloadCommand = (Command) payloadToExecute; + payloadCommand.setExecutor(((Command) contract.getPayload()).getExecutor()); payloadCommand.setContent( processAndEncodeCommand( payloadCommand.getContent(), @@ -182,6 +202,6 @@ public Payload getExecutablePayloadInject(String injectId) throws Exception { return payloadCommand; } - return contract.getPayload(); + return payloadToExecute; } } diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java index 79ac7456c8..559515b192 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectService.java @@ -61,7 +61,6 @@ public class InjectService { private final InjectStatusRepository injectStatusRepository; private final InjectMapper injectMapper; private final MethodSecurityExpressionHandler methodSecurityExpressionHandler; - private final InjectUtils injectUtils; @Resource protected ObjectMapper mapper; @@ -91,13 +90,8 @@ public void deleteAll(List injects) { } public Map resolveAllAssetsToExecute(@NotNull final Inject inject) { - Map assets = new HashMap<>(); - inject - .getAssets() - .forEach( - (asset -> { - assets.put(asset, false); - })); + Map assets = + inject.getAssets().stream().collect(Collectors.toMap(asset -> asset, asset -> false)); inject .getAssetGroups() .forEach( @@ -105,10 +99,7 @@ public Map resolveAllAssetsToExecute(@NotNull final Inject injec List assetsFromGroup = this.assetGroupService.assetsFromAssetGroup(assetGroup.getId()); // Verify asset validity - assetsFromGroup.forEach( - (asset) -> { - assets.put(asset, true); - }); + assetsFromGroup.forEach((asset) -> assets.put(asset, true)); })); return assets; } diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectStatusService.java b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectStatusService.java index dee4e3935c..ad55d96518 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectStatusService.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/service/InjectStatusService.java @@ -1,7 +1,5 @@ package io.openbas.rest.inject.service; -import static java.time.Instant.now; - import io.openbas.database.model.*; import io.openbas.database.model.InjectStatus; import io.openbas.database.repository.AgentRepository; @@ -39,13 +37,30 @@ public Inject updateInjectStatus(String injectId, InjectUpdateStatusInput input) // build status InjectStatus injectStatus = new InjectStatus(); injectStatus.setInject(inject); - injectStatus.setTrackingSentDate(now()); injectStatus.setName(ExecutionStatus.valueOf(input.getStatus())); // Save status for inject inject.setStatus(injectStatus); return injectRepository.save(inject); } + public void addStartImplantExecutionTraceByInject( + String injectId, String agentId, String message) { + InjectStatus injectStatus = + injectStatusRepository.findByInjectId(injectId).orElseThrow(ElementNotFoundException::new); + Agent agent = agentRepository.findById(agentId).orElseThrow(ElementNotFoundException::new); + ExecutionTraces trace = + new ExecutionTraces( + injectStatus, + ExecutionTraceStatus.INFO, + null, + message, + ExecutionTraceAction.START, + agent, + null); + injectStatus.addTrace(trace); + injectStatusRepository.save(injectStatus); + } + private ExecutionTraceStatus convertExecutionStatus(ExecutionStatus status) { return switch (status) { case SUCCESS -> ExecutionTraceStatus.SUCCESS; @@ -81,16 +96,14 @@ public boolean isAllInjectAssetsExecuted(Inject inject) { return assets.size() == totalCompleteTrace; } - public void updateFinalInjectStatus(InjectStatus injectStatus, Instant finishTime) { + public void updateFinalInjectStatus(InjectStatus injectStatus) { ExecutionStatus finalStatus = computeStatus( injectStatus.getTraces().stream() .filter(t -> ExecutionTraceAction.COMPLETE.equals(t.getAction())) .toList()); - injectStatus.addTrace( - ExecutionTraceStatus.INFO, "Process finished", ExecutionTraceAction.COMPLETE, null); - injectStatus.setTrackingEndDate(finishTime == null ? Instant.now() : finishTime); + injectStatus.setTrackingEndDate(Instant.now()); injectStatus.setName(finalStatus); injectStatus.getInject().setUpdatedAt(Instant.now()); } @@ -100,7 +113,7 @@ public ExecutionTraces createExecutionTrace( ExecutionTraceAction executionAction = convertExecutionAction(input.getAction()); ExecutionTraceStatus traceStatus = ExecutionTraceStatus.valueOf(input.getStatus()); return new ExecutionTraces( - injectStatus, traceStatus, null, input.getMessage(), executionAction, agent); + injectStatus, traceStatus, null, input.getMessage(), executionAction, agent, null); } private void computeExecutionTraceStatusIfNeeded( @@ -131,7 +144,7 @@ public Inject handleInjectExecutionCallback( if (executionTraces.getAction().equals(ExecutionTraceAction.COMPLETE) && (agentId == null || isAllInjectAssetsExecuted(inject))) { - updateFinalInjectStatus(injectStatus, now()); + updateFinalInjectStatus(injectStatus); } return injectRepository.save(inject); } @@ -171,11 +184,7 @@ public ExecutionStatus computeStatus(List traces) { return executionStatus; } - public InjectStatus fromExecution(Execution execution, Inject executedInject) { - InjectStatus injectStatus = executedInject.getStatus().orElse(new InjectStatus()); - injectStatus.setTrackingSentDate(Instant.now()); - injectStatus.setInject(executedInject); - + public InjectStatus fromExecution(Execution execution, InjectStatus injectStatus) { if (!execution.getTraces().isEmpty()) { List traces = execution.getTraces().stream().peek(t -> t.setInjectStatus(injectStatus)).toList(); @@ -185,7 +194,7 @@ public InjectStatus fromExecution(Execution execution, Inject executedInject) { if (execution.isAsync()) { injectStatus.setName(ExecutionStatus.PENDING); } else { - updateFinalInjectStatus(injectStatus, now()); + updateFinalInjectStatus(injectStatus); } return injectStatus; @@ -217,14 +226,9 @@ public InjectStatus failInjectStatus(@NotNull String injectId, @Nullable String @Transactional public InjectStatus initializeInjectStatus( - @NotNull String injectId, @NotNull ExecutionStatus status, @Nullable ExecutionTraces trace) { + @NotNull String injectId, @NotNull ExecutionStatus status) { Inject inject = this.injectRepository.findById(injectId).orElseThrow(); InjectStatus injectStatus = getOrInitializeInjectStatus(inject); - - if (trace != null) { - trace.setInjectStatus(injectStatus); - injectStatus.addTrace(trace); - } injectStatus.setName(status); injectStatus.setTrackingSentDate(Instant.now()); injectStatus.setPayloadOutput(injectUtils.getStatusPayloadFromInject(inject)); diff --git a/openbas-api/src/main/java/io/openbas/rest/inject_test_status/InjectTestStatusApi.java b/openbas-api/src/main/java/io/openbas/rest/inject_test_status/InjectTestStatusApi.java index ee86a7f4e8..b7391d6bc6 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject_test_status/InjectTestStatusApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject_test_status/InjectTestStatusApi.java @@ -4,10 +4,10 @@ import io.openbas.aop.LogExecutionTime; import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectTestStatus; import io.openbas.rest.exception.BadRequestException; import io.openbas.rest.helper.RestBehavior; import io.openbas.rest.inject.form.InjectBulkProcessingInput; +import io.openbas.rest.inject.output.InjectTestStatusOutput; import io.openbas.rest.inject.service.InjectService; import io.openbas.service.InjectTestStatusService; import io.openbas.telemetry.Tracing; @@ -32,13 +32,13 @@ public class InjectTestStatusApi extends RestBehavior { @Transactional(rollbackFor = Exception.class) @GetMapping("/api/injects/{injectId}/test") - public InjectTestStatus testInject(@PathVariable @NotBlank String injectId) { + public InjectTestStatusOutput testInject(@PathVariable @NotBlank String injectId) { return injectTestStatusService.testInject(injectId); } @Transactional(rollbackFor = Exception.class) @GetMapping("/api/injects/test/{testId}") - public InjectTestStatus findInjectTestStatus(@PathVariable @NotBlank String testId) { + public InjectTestStatusOutput findInjectTestStatus(@PathVariable @NotBlank String testId) { return injectTestStatusService.findInjectTestStatusById(testId); } @@ -55,7 +55,7 @@ public void deleteInjectTest(@PathVariable String testId) { @PostMapping("/api/injects/test") @LogExecutionTime @Tracing(name = "Bulk tests of injects", layer = "api", operation = "PUT") - public List bulkTestInject( + public List bulkTestInject( @RequestBody @Valid final InjectBulkProcessingInput input) { // Control and format inputs diff --git a/openbas-api/src/main/java/io/openbas/rest/payload/service/PayloadService.java b/openbas-api/src/main/java/io/openbas/rest/payload/service/PayloadService.java index f797807531..76214955e3 100644 --- a/openbas-api/src/main/java/io/openbas/rest/payload/service/PayloadService.java +++ b/openbas-api/src/main/java/io/openbas/rest/payload/service/PayloadService.java @@ -176,7 +176,7 @@ public Payload duplicate(@NotBlank final String payloadId) { return duplicated; } - private Payload generateDuplicatedPayload(Payload originalPayload) { + public Payload generateDuplicatedPayload(Payload originalPayload) { return switch (originalPayload.getTypeEnum()) { case PayloadType.COMMAND -> { Command originCommand = (Command) Hibernate.unproxy(originalPayload); diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java index 32c0df52f1..95d555b9e0 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/ScenarioApi.java @@ -10,6 +10,7 @@ import static java.time.temporal.ChronoUnit.MINUTES; import io.openbas.aop.LogExecutionTime; +import io.openbas.aop.UserRoleDescription; import io.openbas.database.model.*; import io.openbas.database.raw.RawPaginationScenario; import io.openbas.database.repository.*; @@ -26,6 +27,7 @@ import io.openbas.telemetry.Tracing; import io.openbas.utils.FilterUtilsJpa; import io.openbas.utils.pagination.SearchPaginationInput; +import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -51,6 +53,14 @@ @RestController @Secured(ROLE_USER) @RequiredArgsConstructor +@UserRoleDescription +@io.swagger.v3.oas.annotations.tags.Tag( + name = "Scenario management", + description = "Endpoints to manage scenarios", + externalDocs = + @ExternalDocumentation( + description = "Documentation about scenarios", + url = "https://docs.openbas.io/latest/usage/scenarios_and_simulations/")) public class ScenarioApi extends RestBehavior { public static final String SCENARIO_URI = "/api/scenarios"; @@ -65,6 +75,8 @@ public class ScenarioApi extends RestBehavior { private final TeamService teamService; @PostMapping(SCENARIO_URI) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The created scenario")}) + @Operation(summary = "Create scenario", description = "Create a scenario") public Scenario createScenario(@Valid @RequestBody final ScenarioInput input) { if (input == null) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Scenario input cannot be null"); @@ -76,17 +88,24 @@ public Scenario createScenario(@Valid @RequestBody final ScenarioInput input) { } @PostMapping(SCENARIO_URI + "/{scenarioId}") + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The newly created scenario")}) + @Operation(summary = "Duplicate scenario", description = "Duplicate a scenario") public Scenario duplicateScenario(@PathVariable @NotBlank final String scenarioId) { return scenarioService.getDuplicateScenario(scenarioId); } @GetMapping(SCENARIO_URI) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of scenarios")}) + @Operation(summary = "List scenarios", description = "List the scenarios") public List scenarios() { return this.scenarioService.scenarios(); } @LogExecutionTime @PostMapping(SCENARIO_URI + "/search") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of scenarios")}) + @Operation(summary = "Search scenarios", description = "Search the scenarios") @Tracing(name = "Get a page of scenarios", layer = "api", operation = "POST") public Page scenarios( @RequestBody @Valid final SearchPaginationInput searchPaginationInput) { @@ -94,12 +113,16 @@ public Page scenarios( } @GetMapping(SCENARIO_URI + "/{scenarioId}") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The scenario")}) + @Operation(summary = "Get scenario", description = "Get a scenario") @PreAuthorize("isScenarioObserver(#scenarioId)") public Scenario scenario(@PathVariable @NotBlank final String scenarioId) { return scenarioService.scenario(scenarioId); } @PutMapping(SCENARIO_URI + "/{scenarioId}") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The scenario")}) + @Operation(summary = "Update scenario", description = "Update a scenario") @PreAuthorize("isScenarioPlanner(#scenarioId)") public Scenario updateScenario( @PathVariable @NotBlank final String scenarioId, @@ -112,6 +135,8 @@ public Scenario updateScenario( } @DeleteMapping(SCENARIO_URI + "/{scenarioId}") + @ApiResponses(value = {@ApiResponse(responseCode = "200")}) + @Operation(summary = "Update scenario", description = "Update a scenario") @PreAuthorize("isScenarioPlanner(#scenarioId)") public void deleteScenario(@PathVariable @NotBlank final String scenarioId) { this.scenarioService.deleteScenario(scenarioId); diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioInput.java b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioInput.java index 0d07b2220e..b7b5b1655b 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioInput.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openbas.database.model.Scenario.SEVERITY; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Nullable; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; @@ -16,47 +17,60 @@ public class ScenarioInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("scenario_name") + @Schema(description = "Name of the scenario") private String name; @JsonProperty("scenario_description") + @Schema(description = "Description of the scenario") private String description; @JsonProperty("scenario_subtitle") + @Schema(description = "Subtitle of the scenario") private String subtitle; @Nullable @JsonProperty("scenario_category") + @Schema(description = "Category of the scenario") private String category; @Nullable @JsonProperty("scenario_main_focus") + @Schema(description = "Main focus of the scenario") private String mainFocus; @Nullable @JsonProperty("scenario_severity") + @Schema(description = "Severity of the scenario") private SEVERITY severity; @Nullable @JsonProperty("scenario_external_reference") + @Schema(description = "External reference of the scenario") private String externalReference; @Nullable @JsonProperty("scenario_external_url") + @Schema(description = "External url of the scenario") private String externalUrl; @JsonProperty("scenario_tags") + @Schema(description = "Tag IDs of the scenario") private List tagIds = new ArrayList<>(); @JsonProperty("scenario_mail_from") @Email + @Schema(description = "Sender of the mails of the scenario") private String from; @JsonProperty("scenario_mails_reply_to") + @Schema(description = "Reply to of the mails of the scenario") private List replyTos = new ArrayList<>(); @JsonProperty("scenario_message_header") + @Schema(description = "Header of the communications of the scenario") private String header; @JsonProperty("scenario_message_footer") + @Schema(description = "Footer of the communications of the scenario") private String footer; } diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioSimple.java b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioSimple.java index 1d5657bd99..c580e3727f 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioSimple.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/form/ScenarioSimple.java @@ -19,17 +19,21 @@ public class ScenarioSimple { @JsonProperty("scenario_id") + @Schema(description = "Id of the scenario") private String id; @JsonProperty("scenario_name") + @Schema(description = "Name of the scenario") private String name; @JsonProperty("scenario_subtitle") + @Schema(description = "Subtitle of the scenario") private String subtitle; @ArraySchema(schema = @Schema(type = "string")) @JsonSerialize(using = MultiIdSetDeserializer.class) @JsonProperty("scenario_tags") + @Schema(description = "List of tag IDs of the scenario") private Set tags = new HashSet<>(); public static ScenarioSimple fromScenario(@NotNull final Scenario scenario) { diff --git a/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java b/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java index 2ec3728f0f..80e519c2e6 100644 --- a/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/scenario/form/UpdateScenarioInput.java @@ -1,6 +1,7 @@ package io.openbas.rest.scenario.form; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.Getter; @@ -8,5 +9,6 @@ @Getter public class UpdateScenarioInput extends ScenarioInput { @JsonProperty("apply_tag_rule") + @Schema(description = "True if we want to apply tag rules") private boolean applyTagRule = false; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/PlatformSettingsApi.java b/openbas-api/src/main/java/io/openbas/rest/settings/PlatformSettingsApi.java index 6ba4900eaf..0b267841df 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/PlatformSettingsApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/PlatformSettingsApi.java @@ -2,6 +2,7 @@ import static io.openbas.database.model.User.ROLE_ADMIN; +import io.openbas.aop.UserRoleDescription; import io.openbas.rest.helper.RestBehavior; import io.openbas.rest.settings.form.PolicyInput; import io.openbas.rest.settings.form.SettingsEnterpriseEditionUpdateInput; @@ -10,6 +11,11 @@ import io.openbas.rest.settings.form.ThemeInput; import io.openbas.rest.settings.response.PlatformSettings; import io.openbas.service.PlatformSettingsService; +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; @@ -21,6 +27,14 @@ @RequestMapping("/api/settings") @RestController +@UserRoleDescription +@Tag( + name = "Settings management", + description = "Endpoints to manage settings", + externalDocs = + @ExternalDocumentation( + description = "Documentation about settings", + url = "https://docs.openbas.io/latest/administration/parameters/")) public class PlatformSettingsApi extends RestBehavior { private PlatformSettingsService platformSettingsService; @@ -31,12 +45,16 @@ public void setPlatformSettingsService(PlatformSettingsService platformSettingsS } @GetMapping() + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of settings")}) + @Operation(summary = "List settings", description = "Return the settings") public PlatformSettings settings() { return platformSettingsService.findSettings(); } @Secured(ROLE_ADMIN) @PutMapping() + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation(summary = "Update settings", description = "Update the settings") public PlatformSettings updateBasicConfigurationSettings( @Valid @RequestBody SettingsUpdateInput input) { return platformSettingsService.updateBasicConfigurationSettings(input); @@ -44,6 +62,8 @@ public PlatformSettings updateBasicConfigurationSettings( @Secured(ROLE_ADMIN) @PutMapping("/enterprise_edition") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation(summary = "Update EE settings", description = "Update the enterprise edition settings") public PlatformSettings updateSettingsEnterpriseEdition( @Valid @RequestBody SettingsEnterpriseEditionUpdateInput input) { return platformSettingsService.updateSettingsEnterpriseEdition(input); @@ -51,6 +71,8 @@ public PlatformSettings updateSettingsEnterpriseEdition( @Secured(ROLE_ADMIN) @PutMapping("/platform_whitemark") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation(summary = "Update Whitemark settings", description = "Update the whitemark settings") public PlatformSettings updateSettingsPlatformWhitemark( @Valid @RequestBody SettingsPlatformWhitemarkUpdateInput input) { return platformSettingsService.updateSettingsPlatformWhitemark(input); @@ -58,18 +80,26 @@ public PlatformSettings updateSettingsPlatformWhitemark( @Secured(ROLE_ADMIN) @PutMapping("/theme/light") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation( + summary = "Update light theme settings", + description = "Update the light theme settings") public PlatformSettings updateThemeLight(@Valid @RequestBody ThemeInput input) { return platformSettingsService.updateThemeLight(input); } @Secured(ROLE_ADMIN) @PutMapping("/theme/dark") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation(summary = "Update dark theme settings", description = "Update the dark theme settings") public PlatformSettings updateThemeDark(@Valid @RequestBody ThemeInput input) { return platformSettingsService.updateThemeDark(input); } @Secured(ROLE_ADMIN) @PutMapping("/policies") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated settings")}) + @Operation(summary = "Update policies settings", description = "Update the policies settings") public PlatformSettings updateSettingsPolicies(@Valid @RequestBody PolicyInput input) { return platformSettingsService.updateSettingsPolicies(input); } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/form/PolicyInput.java b/openbas-api/src/main/java/io/openbas/rest/settings/form/PolicyInput.java index 3eaad08bbb..96d1afe863 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/form/PolicyInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/form/PolicyInput.java @@ -1,6 +1,7 @@ package io.openbas.rest.settings.form; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -9,11 +10,14 @@ public class PolicyInput { @JsonProperty("platform_login_message") + @Schema(description = "Message to show at login") private String loginMessage; @JsonProperty("platform_consent_message") + @Schema(description = "Consent message to show at login") private String consentMessage; @JsonProperty("platform_consent_confirm_text") + @Schema(description = "Consent confirmation message") private String consentConfirmText; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsEnterpriseEditionUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsEnterpriseEditionUpdateInput.java index 223f09297f..ea15b7b71d 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsEnterpriseEditionUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsEnterpriseEditionUpdateInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -12,5 +13,6 @@ public class SettingsEnterpriseEditionUpdateInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("platform_enterprise_edition") + @Schema(description = "'true' if enterprise edition is activated") private String enterpriseEdition; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsPlatformWhitemarkUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsPlatformWhitemarkUpdateInput.java index 317eff612d..36ad7c7c02 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsPlatformWhitemarkUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsPlatformWhitemarkUpdateInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -12,5 +13,6 @@ public class SettingsPlatformWhitemarkUpdateInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("platform_whitemark") + @Schema(description = "The whitemark of the platform") private String platformWhitemark; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsUpdateInput.java index be37f5a01d..c96598768f 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/form/SettingsUpdateInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @@ -13,13 +14,16 @@ public class SettingsUpdateInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("platform_name") + @Schema(description = "Name of the platform") private String name; @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("platform_theme") + @Schema(description = "Theme of the platform") private String theme; @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("platform_lang") + @Schema(description = "Language of the platform") private String lang; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/form/ThemeInput.java b/openbas-api/src/main/java/io/openbas/rest/settings/form/ThemeInput.java index ea5eefc97a..aaffeec809 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/form/ThemeInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/form/ThemeInput.java @@ -1,6 +1,7 @@ package io.openbas.rest.settings.form; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @Setter @@ -10,29 +11,38 @@ public class ThemeInput { @JsonProperty("background_color") + @Schema(description = "Background color of the theme") private String backgroundColor; @JsonProperty("paper_color") + @Schema(description = "Paper color of the theme") private String paperColor; @JsonProperty("navigation_color") + @Schema(description = "Navigation color of the theme") private String NavigationColor; @JsonProperty("primary_color") + @Schema(description = "Primary color of the theme") private String primaryColor; @JsonProperty("secondary_color") + @Schema(description = "Secondary color of the theme") private String secondaryColor; @JsonProperty("accent_color") + @Schema(description = "Accent color of the theme") private String accentColor; @JsonProperty("logo_url") + @Schema(description = "Url of the logo") private String logoUrl; @JsonProperty("logo_url_collapsed") + @Schema(description = "'true' if the logo needs to be collapsed") private String logoUrlCollapsed; @JsonProperty("logo_login_url") + @Schema(description = "Url of the login logo") private String logoLoginUrl; } diff --git a/openbas-api/src/main/java/io/openbas/rest/settings/response/PlatformSettings.java b/openbas-api/src/main/java/io/openbas/rest/settings/response/PlatformSettings.java index 8bf925f15f..168f152383 100644 --- a/openbas-api/src/main/java/io/openbas/rest/settings/response/PlatformSettings.java +++ b/openbas-api/src/main/java/io/openbas/rest/settings/response/PlatformSettings.java @@ -6,6 +6,8 @@ import io.openbas.rest.settings.PreviewFeature; import io.openbas.rest.settings.form.PolicyInput; import io.openbas.rest.settings.form.ThemeInput; +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.HashMap; @@ -23,106 +25,146 @@ public class PlatformSettings { @JsonProperty("platform_name") + @Schema(description = "Name of the platform") private String platformName; @JsonProperty("platform_base_url") + @Schema(description = "Base URL of the platform") private String platformBaseUrl; @JsonProperty("platform_agent_url") + @Schema(description = "Agent URL of the platform") private String platformAgentUrl; @JsonProperty("platform_theme") + @Schema(description = "Theme of the platform") private String platformTheme; @JsonProperty("platform_lang") + @Schema(description = "Language of the platform") private String platformLang; @JsonProperty("platform_enterprise_edition") + @Schema(description = "'true' if the platform has Enterprise Edition activated") private String platformEnterpriseEdition; @JsonProperty("platform_whitemark") + @Schema(description = "'true' if the platform has the whitemark activated") private String platformWhitemark; @JsonProperty("platform_openid_providers") + @Schema(description = "List of OpenID providers") private List platformOpenIdProviders; @JsonProperty("platform_saml2_providers") + @Schema(description = "List of Saml2 providers") private List platformSaml2Providers; @JsonProperty("auth_openid_enable") + @Schema(description = "True if OpenID is enabled") private Boolean authOpenidEnable; @JsonProperty("auth_saml2_enable") + @Schema(description = "True if Saml2 is enabled") private Boolean authSaml2Enable; @JsonProperty("auth_local_enable") + @Schema(description = "True if local authentication is enabled") private Boolean authLocalEnable; @JsonProperty("map_tile_server_light") + @Schema(description = "URL of the server containing the map tile with light theme") private String mapTileServerLight; @JsonProperty("map_tile_server_dark") + @Schema(description = "URL of the server containing the map tile with dark theme") private String mapTileServerDark; @JsonProperty("xtm_opencti_enable") + @Schema(description = "True if connection with OpenCTI is enabled") private Boolean xtmOpenctiEnable; @JsonProperty("xtm_opencti_url") + @Schema(description = "Url of OpenCTI") private String xtmOpenctiUrl; @JsonProperty("platform_version") + @Schema(description = "Current version of the platform") private String platformVersion; @JsonProperty("postgre_version") + @Schema(description = "Current version of the PostgreSQL") private String postgreVersion; @JsonProperty("java_version") + @Schema(description = "Current version of Java") private String javaVersion; @JsonProperty("rabbitmq_version") + @Schema(description = "Current version of RabbitMQ") private String rabbitMQVersion; @JsonProperty("platform_ai_enabled") + @Schema(description = "True if AI is enabled for the platform") private Boolean aiEnabled; @JsonProperty("platform_ai_has_token") + @Schema(description = "True if we have an AI token") private Boolean aiHasToken; @JsonProperty("platform_ai_type") + @Schema( + description = "Type of AI (mistralai or openai)", + externalDocs = + @ExternalDocumentation( + description = "How to configure AI service", + url = + "https://docs.openbas.io/latest/deployment/configuration/?h=ai+type#ai-service")) private String aiType; @JsonProperty("platform_ai_model") + @Schema(description = "Chosen model of AI") private String aiModel; @JsonProperty("executor_caldera_enable") + @Schema(description = "'true' if the Caldera Executor is enabled") private Boolean executorCalderaEnable; @JsonProperty("executor_caldera_public_url") + @Schema(description = "Url of the Caldera Executor") private String executorCalderaPublicUrl; @JsonProperty("executor_tanium_enable") + @Schema(description = "'true' if the Tanium Executor is enabled") private Boolean executorTaniumEnable; // THEME @JsonProperty("platform_light_theme") + @Schema(description = "Definition of the light theme") private ThemeInput themeLight; @JsonProperty("platform_dark_theme") + @Schema(description = "Definition of the dark theme") private ThemeInput themeDark; // POLICIES @JsonProperty("platform_policies") + @Schema(description = "Policies of the platform") private PolicyInput policies; // FEATURE FLAG @JsonProperty("enabled_dev_features") + @Schema(description = "List of enabled dev features") private List enabledDevFeatures = new ArrayList<>(); // PLATFORM MESSAGE @JsonProperty("platform_banner_by_level") @Getter(NONE) + @Schema( + description = + "Map of the messages to display on the screen by their level (the level available are DEBUG, INFO, WARN, ERROR, FATAL)") private Map> platformBannerByLevel; public Map> getPlatformBannerByLevel() { @@ -138,32 +180,40 @@ public Map> getPlatformBannerByLevel() { // EXPECTATION @NotNull @JsonProperty("expectation_detection_expiration_time") + @Schema(description = "Time to wait before detection time has expired") private long detectionExpirationTime; @NotNull @JsonProperty("expectation_prevention_expiration_time") + @Schema(description = "Time to wait before prevention time has expired") private long preventionExpirationTime; @NotNull @JsonProperty("expectation_challenge_expiration_time") + @Schema(description = "Time to wait before challenge time has expired") private long challengeExpirationTime; @NotNull @JsonProperty("expectation_article_expiration_time") + @Schema(description = "Time to wait before article time has expired") private long articleExpirationTime; @NotNull @JsonProperty("expectation_manual_expiration_time") + @Schema(description = "Time to wait before manual expectation time has expired") private long manualExpirationTime; @NotNull @JsonProperty("expectation_manual_default_score_value") + @Schema(description = "Default score for manuel expectation") private int expectationDefaultScoreValue; // EMAIL CONFIG @JsonProperty("default_mailer") + @Schema(description = "Sender mail to use by default for injects") private String defaultMailer; @JsonProperty("default_reply_to") + @Schema(description = "Reply to mail to use by default for injects") private String defaultReplyTo; } diff --git a/openbas-api/src/main/java/io/openbas/rest/tag/TagApi.java b/openbas-api/src/main/java/io/openbas/rest/tag/TagApi.java index d27e501118..040e4e5083 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag/TagApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag/TagApi.java @@ -5,6 +5,7 @@ import static io.openbas.helper.StreamHelper.fromIterable; import static io.openbas.utils.pagination.PaginationUtils.buildPaginationJPA; +import io.openbas.aop.UserRoleDescription; import io.openbas.database.model.Tag; import io.openbas.database.repository.TagRepository; import io.openbas.rest.exception.ElementNotFoundException; @@ -13,6 +14,10 @@ import io.openbas.rest.tag.form.TagUpdateInput; import io.openbas.utils.FilterUtilsJpa; import io.openbas.utils.pagination.SearchPaginationInput; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import jakarta.transaction.Transactional; import jakarta.validation.Valid; import java.util.List; @@ -26,6 +31,10 @@ import org.springframework.web.bind.annotation.*; @RestController +@io.swagger.v3.oas.annotations.tags.Tag( + name = "Tags management", + description = "Endpoints to manage tags") +@UserRoleDescription public class TagApi extends RestBehavior { public static final String TAG_URI = "/api/tags"; @@ -37,11 +46,20 @@ public void setTagRepository(TagRepository tagRepository) { this.tagRepository = tagRepository; } + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "All the existing tags")}) + @Operation(description = "Get the list of tags", summary = "Get tags") @GetMapping("/api/tags") public Iterable tags() { return tagRepository.findAll(); } + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "All the existing tags corresponding to the search criteria") + }) + @Operation(description = "Search tags corresponding to the criteria", summary = "Search tags") @PostMapping("/api/tags/search") public Page tags(@RequestBody @Valid SearchPaginationInput searchPaginationInput) { return buildPaginationJPA( @@ -54,7 +72,11 @@ public Page tags(@RequestBody @Valid SearchPaginationInput searchPagination @Secured(ROLE_ADMIN) @PutMapping("/api/tags/{tagId}") @Transactional(rollbackOn = Exception.class) - public Tag updateTag(@PathVariable String tagId, @Valid @RequestBody TagUpdateInput input) { + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated tag")}) + @Operation(description = "Update a tag", summary = "Update tag") + public Tag updateTag( + @PathVariable @Schema(description = "ID of the tag") String tagId, + @Valid @RequestBody TagUpdateInput input) { Tag tag = tagRepository.findById(tagId).orElseThrow(ElementNotFoundException::new); tag.setUpdateAttributes(input); return tagRepository.save(tag); @@ -63,6 +85,8 @@ public Tag updateTag(@PathVariable String tagId, @Valid @RequestBody TagUpdateIn @Secured(ROLE_ADMIN) @PostMapping("/api/tags") @Transactional(rollbackOn = Exception.class) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The created tag")}) + @Operation(description = "Create a tag", summary = "Create tag") public Tag createTag(@Valid @RequestBody TagCreateInput input) { Tag tag = new Tag(); tag.setUpdateAttributes(input); @@ -72,6 +96,8 @@ public Tag createTag(@Valid @RequestBody TagCreateInput input) { @Secured(ROLE_ADMIN) @PostMapping("/api/tags/upsert") @Transactional(rollbackOn = Exception.class) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The upserted tag")}) + @Operation(description = "Upsert a tag", summary = "Upsert tag") public Tag upsertTag(@Valid @RequestBody TagCreateInput input) { Optional tag = tagRepository.findByName(input.getName()); if (tag.isPresent()) { @@ -85,15 +111,23 @@ public Tag upsertTag(@Valid @RequestBody TagCreateInput input) { @Secured(ROLE_ADMIN) @DeleteMapping("/api/tags/{tagId}") - public void deleteTag(@PathVariable String tagId) { + @ApiResponses(value = {@ApiResponse(responseCode = "200")}) + @Operation(description = "Delete a tag", summary = "Delete tag") + public void deleteTag(@PathVariable @Schema(description = "ID of the tag") String tagId) { tagRepository.deleteById(tagId); } // -- OPTION -- @GetMapping(TAG_URI + "/options") + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The list of tags corresponding")}) + @Operation( + description = "Get a list of tag IDs and labels corresponding to the text search", + summary = "Search tags by text") public List optionsByName( - @RequestParam(required = false) final String searchText) { + @RequestParam(required = false) @Schema(description = "Search text") + final String searchText) { return fromIterable( this.tagRepository.findAll(byName(searchText), Sort.by(Sort.Direction.ASC, "name"))) .stream() @@ -102,6 +136,11 @@ public List optionsByName( } @PostMapping(TAG_URI + "/options") + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The list of tags corresponding")}) + @Operation( + description = "Get a list of tag IDs and labels corresponding to a list of IDs", + summary = "Search tags by ids") public List optionsById(@RequestBody final List ids) { return fromIterable(this.tagRepository.findAllById(ids)).stream() .map(i -> new FilterUtilsJpa.Option(i.getId(), i.getName())) diff --git a/openbas-api/src/main/java/io/openbas/rest/tag/form/TagBaseInput.java b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagBaseInput.java new file mode 100644 index 0000000000..60a59ed763 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagBaseInput.java @@ -0,0 +1,24 @@ +package io.openbas.rest.tag.form; + +import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class TagBaseInput { + + @NotBlank(message = MANDATORY_MESSAGE) + @JsonProperty("tag_name") + @Schema(description = "Name of the tag") + private String name; + + @NotBlank(message = MANDATORY_MESSAGE) + @JsonProperty("tag_color") + @Schema(description = "Color of the tag") + private String color; +} diff --git a/openbas-api/src/main/java/io/openbas/rest/tag/form/TagCreateInput.java b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagCreateInput.java index b49de8c5ec..929536d56a 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag/form/TagCreateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagCreateInput.java @@ -1,21 +1,3 @@ package io.openbas.rest.tag.form; -import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class TagCreateInput { - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("tag_name") - private String name; - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("tag_color") - private String color; -} +public class TagCreateInput extends TagBaseInput {} diff --git a/openbas-api/src/main/java/io/openbas/rest/tag/form/TagUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagUpdateInput.java index daf7adc7ea..d10d8bc484 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag/form/TagUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag/form/TagUpdateInput.java @@ -1,33 +1,3 @@ package io.openbas.rest.tag.form; -import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; - -public class TagUpdateInput { - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("tag_name") - private String name; - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("tag_color") - private String color; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getColor() { - return color; - } - - public void setColor(String color) { - this.color = color; - } -} +public class TagUpdateInput extends TagBaseInput {} diff --git a/openbas-api/src/main/java/io/openbas/rest/tag_rule/TagRuleApi.java b/openbas-api/src/main/java/io/openbas/rest/tag_rule/TagRuleApi.java index fbcc55a3e5..62f0208601 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag_rule/TagRuleApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag_rule/TagRuleApi.java @@ -3,6 +3,7 @@ import static io.openbas.database.model.User.ROLE_ADMIN; import io.openbas.aop.LogExecutionTime; +import io.openbas.aop.UserRoleDescription; import io.openbas.rest.helper.RestBehavior; import io.openbas.rest.tag_rule.form.TagRuleInput; import io.openbas.rest.tag_rule.form.TagRuleMapper; @@ -10,8 +11,10 @@ import io.openbas.service.TagRuleService; import io.openbas.utils.pagination.SearchPaginationInput; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import java.util.List; @@ -21,6 +24,11 @@ import org.springframework.web.bind.annotation.*; @RestController +@UserRoleDescription +@Tag( + name = "Tag rules management", + description = + "Endpoints to manage TagRules. TagRules are used to automatically add tags to elements depending on rules") public class TagRuleApi extends RestBehavior { public static final String TAG_RULE_URI = "/api/tag-rules"; @@ -36,14 +44,18 @@ public TagRuleApi(TagRuleService tagRuleService, TagRuleMapper tagRuleMapper) { @LogExecutionTime @GetMapping(TagRuleApi.TAG_RULE_URI + "/{tagRuleId}") - @Operation(summary = "Get TagRule by Id") - public TagRuleOutput findTagRule(@PathVariable @NotBlank final String tagRuleId) { + @Operation(description = "Get TagRule by Id", summary = "Get TagRule") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The TagRule")}) + public TagRuleOutput findTagRule( + @PathVariable @NotBlank @Schema(description = "ID of the tag rule") final String tagRuleId) { return tagRuleService.findById(tagRuleId).map(tagRuleMapper::toTagRuleOutput).orElse(null); } @LogExecutionTime @GetMapping(TagRuleApi.TAG_RULE_URI) - @Operation(summary = "Get All TagRules") + @Operation(description = "Get All TagRules", summary = "Get TagRules") + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The list of all TagRules")}) public List tags() { return tagRuleService.findAll().stream().map(tagRuleMapper::toTagRuleOutput).toList(); } @@ -58,7 +70,8 @@ public List tags() { @ApiResponse(responseCode = "200", description = "TagRule deleted"), @ApiResponse(responseCode = "404", description = "TagRule not found") }) - public void deleteTagRule(@PathVariable @NotBlank final String tagRuleId) { + public void deleteTagRule( + @PathVariable @NotBlank @Schema(description = "ID of the tag rule") final String tagRuleId) { tagRuleService.deleteTagRule(tagRuleId); } @@ -85,10 +98,10 @@ public TagRuleOutput createTagRule(@Valid @RequestBody final TagRuleInput input) @ApiResponses( value = { @ApiResponse(responseCode = "200", description = "TagRule updated"), - @ApiResponse(responseCode = "404", description = "TagRule, Tag or Asset Group not found") + @ApiResponse(responseCode = "404", description = "TagRule, Tag or Asset Group not found") }) public TagRuleOutput updateTagRule( - @PathVariable @NotBlank final String tagRuleId, + @PathVariable @NotBlank @Schema(description = "ID of the tag rule") final String tagRuleId, @Valid @RequestBody final TagRuleInput input) { return tagRuleMapper.toTagRuleOutput( tagRuleService.updateTagRule(tagRuleId, input.getTagName(), input.getAssetGroups())); @@ -96,7 +109,15 @@ public TagRuleOutput updateTagRule( @LogExecutionTime @PostMapping(TagRuleApi.TAG_RULE_URI + "/search") - @Operation(summary = "Search TagRule") + @Operation( + description = "Search TagRules corresponding to search criteria", + summary = "Search TagRules") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The list of all TagRules corresponding to the search criteria") + }) public Page searchTagRules( @RequestBody @Valid SearchPaginationInput searchPaginationInput) { return tagRuleService.searchTagRule(searchPaginationInput).map(tagRuleMapper::toTagRuleOutput); diff --git a/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleInput.java b/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleInput.java index 4654fd76d8..95269922ee 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; @@ -18,8 +19,10 @@ public class TagRuleInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("tag_name") + @Schema(description = "Name of the tag") private String tagName; @JsonProperty("asset_groups") + @Schema(description = "Asset groups of the tag rule") private List assetGroups = new ArrayList<>(); } diff --git a/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleOutput.java b/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleOutput.java index ae3d50b651..f5846d3fe0 100644 --- a/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleOutput.java +++ b/openbas-api/src/main/java/io/openbas/rest/tag_rule/form/TagRuleOutput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import java.util.HashMap; import java.util.Map; @@ -16,12 +17,15 @@ public class TagRuleOutput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("tag_rule_id") + @Schema(description = "ID of the tag rule") private String id; @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("tag_name") + @Schema(description = "Name of the tag associated with the tag rule") private String tagName; @JsonProperty("asset_groups") + @Schema(description = "Asset groups of the tag rule") Map assetGroups = new HashMap<>(); } diff --git a/openbas-api/src/main/java/io/openbas/rest/team/TeamApi.java b/openbas-api/src/main/java/io/openbas/rest/team/TeamApi.java index c647acc0cf..11ac211dc0 100644 --- a/openbas-api/src/main/java/io/openbas/rest/team/TeamApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/team/TeamApi.java @@ -13,6 +13,7 @@ import static org.springframework.util.StringUtils.hasText; import io.openbas.aop.LogExecutionTime; +import io.openbas.aop.UserRoleDescription; import io.openbas.config.OpenBASPrincipal; import io.openbas.database.model.Organization; import io.openbas.database.model.Team; @@ -31,6 +32,12 @@ import io.openbas.service.TeamService; import io.openbas.telemetry.Tracing; import io.openbas.utils.pagination.SearchPaginationInput; +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.util.List; @@ -46,6 +53,15 @@ @RestController @Secured(ROLE_USER) @RequiredArgsConstructor +@UserRoleDescription +@Tag( + name = "Teams management", + description = "Endpoints to manage teams", + externalDocs = + @ExternalDocumentation( + description = "Documentation about teams", + url = + "https://docs.openbas.io/latest/usage/teams_and_players_and_organizations/#teams")) public class TeamApi extends RestBehavior { public static final String TEAM_URI = "/api/teams"; @@ -62,6 +78,8 @@ public class TeamApi extends RestBehavior { @GetMapping(TEAM_URI) @PreAuthorize("isObserver()") @Tracing(name = "Get teams", layer = "api", operation = "GET") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of teams")}) + @Operation(summary = "List teams", description = "Return the teams") public Iterable getTeams() { List teams; OpenBASPrincipal currentUser = currentUser(); @@ -90,6 +108,10 @@ public Iterable getTeams() { @PreAuthorize("isObserver()") @Transactional(readOnly = true) @Tracing(name = "Get a page of teams", layer = "api", operation = "POST") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of teams")}) + @Operation( + summary = "Search teams", + description = "Search the teams corresponding to the criteria") public Page searchTeams( @RequestBody @Valid SearchPaginationInput searchPaginationInput) { final Specification teamSpecification = contextual(false); @@ -101,25 +123,35 @@ public Page searchTeams( @PreAuthorize("isObserver()") @Transactional(readOnly = true) @Tracing(name = "Get a list of teams", layer = "api", operation = "POST") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of teams")}) + @Operation(description = "Find a list of teams based on their ids", summary = "Find teams") public List findTeams(@RequestBody @Valid @NotNull final List teamIds) { return this.teamService.find(fromIds(teamIds)); } @GetMapping("/api/teams/{teamId}") @PreAuthorize("isObserver()") - public Team getTeam(@PathVariable String teamId) { + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The team")}) + @Operation(description = "Get a team", summary = "Get team") + public Team getTeam(@PathVariable @Schema(description = "ID of the team") String teamId) { return teamRepository.findById(teamId).orElseThrow(ElementNotFoundException::new); } @GetMapping("/api/teams/{teamId}/players") @PreAuthorize("isObserver()") - public Iterable getTeamPlayers(@PathVariable String teamId) { + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The list of players of the team")}) + @Operation(description = "Get the list of players of a team", summary = "Get team's players") + public Iterable getTeamPlayers( + @PathVariable @Schema(description = "ID of the team") String teamId) { return teamRepository.findById(teamId).orElseThrow(ElementNotFoundException::new).getUsers(); } @PostMapping(TEAM_URI) @PreAuthorize("isPlanner()") @Transactional(rollbackFor = Exception.class) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The created team")}) + @Operation(description = "Create a new team", summary = "Create team") public Team createTeam(@Valid @RequestBody TeamCreateInput input) { isTeamAlreadyExists(input); Team team = new Team(); @@ -135,6 +167,9 @@ public Team createTeam(@Valid @RequestBody TeamCreateInput input) { @PostMapping("/api/teams/upsert") @PreAuthorize("isPlanner()") @Transactional(rollbackFor = Exception.class) + @ApiResponses( + value = {@ApiResponse(responseCode = "200", description = "The created/updated team")}) + @Operation(description = "Create a new team or update an existing team", summary = "Upsert team") public Team upsertTeam(@Valid @RequestBody TeamCreateInput input) { if (input.getContextual() && input.getExerciseIds().toArray().length > 1) { throw new UnsupportedOperationException( @@ -165,13 +200,19 @@ public Team upsertTeam(@Valid @RequestBody TeamCreateInput input) { @DeleteMapping("/api/teams/{teamId}") @PreAuthorize("isPlanner()") - public void deleteTeam(@PathVariable String teamId) { + @ApiResponses(value = {@ApiResponse(responseCode = "200")}) + @Operation(description = "Delete an existing team", summary = "Delete team") + public void deleteTeam(@PathVariable @Schema(description = "ID of the team") String teamId) { teamRepository.deleteById(teamId); } @PutMapping("/api/teams/{teamId}") @PreAuthorize("isPlanner()") - public Team updateTeam(@PathVariable String teamId, @Valid @RequestBody TeamUpdateInput input) { + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated team")}) + @Operation(description = "Update an existing team", summary = "Update team") + public Team updateTeam( + @PathVariable @Schema(description = "ID of the team") String teamId, + @Valid @RequestBody TeamUpdateInput input) { Team team = teamRepository.findById(teamId).orElseThrow(ElementNotFoundException::new); team.setUpdateAttributes(input); team.setUpdatedAt(now()); @@ -183,8 +224,13 @@ public Team updateTeam(@PathVariable String teamId, @Valid @RequestBody TeamUpda @PutMapping("/api/teams/{teamId}/players") @PreAuthorize("isPlanner()") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The updated team")}) + @Operation( + description = "Update the list of users of a team team", + summary = "Update team players") public Team updateTeamUsers( - @PathVariable String teamId, @Valid @RequestBody UpdateUsersTeamInput input) { + @PathVariable @Schema(description = "ID of the team") String teamId, + @Valid @RequestBody UpdateUsersTeamInput input) { Team team = teamRepository.findById(teamId).orElseThrow(ElementNotFoundException::new); Iterable teamUsers = userRepository.findAllById(input.getUserIds()); team.setUsers(fromIterable(teamUsers)); diff --git a/openbas-api/src/main/java/io/openbas/rest/team/form/TeamBaseInput.java b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamBaseInput.java new file mode 100644 index 0000000000..7866ea5b4c --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamBaseInput.java @@ -0,0 +1,31 @@ +package io.openbas.rest.team.form; + +import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +@Data +public class TeamBaseInput { + + @NotBlank(message = MANDATORY_MESSAGE) + @JsonProperty("team_name") + @Schema(description = "Name of the team") + private String name; + + @JsonProperty("team_description") + @Schema(description = "Description of the team") + private String description; + + @JsonProperty("team_organization") + @Schema(description = "ID of the organization of the team") + private String organizationId; + + @JsonProperty("team_tags") + @Schema(description = "IDs of the tags of the team") + private List tagIds = new ArrayList<>(); +} diff --git a/openbas-api/src/main/java/io/openbas/rest/team/form/TeamCreateInput.java b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamCreateInput.java index fc60836cfd..3f6a568c67 100644 --- a/openbas-api/src/main/java/io/openbas/rest/team/form/TeamCreateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamCreateInput.java @@ -1,35 +1,25 @@ package io.openbas.rest.team.form; -import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; - import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.ArrayList; import java.util.List; import lombok.Data; @Data -public class TeamCreateInput { - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("team_name") - private String name; - - @JsonProperty("team_description") - private String description; - - @JsonProperty("team_organization") - private String organizationId; - - @JsonProperty("team_tags") - private List tagIds = new ArrayList<>(); +public class TeamCreateInput extends TeamBaseInput { @JsonProperty("team_exercises") + @Schema(description = "Id of the simulations linked to the team") private List exerciseIds = new ArrayList<>(); @JsonProperty("team_scenarios") + @Schema(description = "Id of the scenarios linked to the team") private List scenarioIds = new ArrayList<>(); @JsonProperty("team_contextual") + @Schema( + description = + "True if the team is contextual (exists only in the scenario/simulation it is linked to)") private Boolean contextual = false; } diff --git a/openbas-api/src/main/java/io/openbas/rest/team/form/TeamUpdateInput.java b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamUpdateInput.java index c07cd6bdc7..221891cda4 100644 --- a/openbas-api/src/main/java/io/openbas/rest/team/form/TeamUpdateInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/team/form/TeamUpdateInput.java @@ -1,56 +1,3 @@ package io.openbas.rest.team.form; -import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import java.util.ArrayList; -import java.util.List; - -public class TeamUpdateInput { - - @NotBlank(message = MANDATORY_MESSAGE) - @JsonProperty("team_name") - private String name; - - @JsonProperty("team_description") - private String description; - - @JsonProperty("team_organization") - private String organizationId; - - @JsonProperty("team_tags") - private List tagIds = new ArrayList<>(); - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getOrganizationId() { - return organizationId; - } - - public void setOrganizationId(String organizationId) { - this.organizationId = organizationId; - } - - public List getTagIds() { - return tagIds; - } - - public void setTagIds(List tagIds) { - this.tagIds = tagIds; - } -} +public class TeamUpdateInput extends TeamBaseInput {} diff --git a/openbas-api/src/main/java/io/openbas/rest/team/form/UpdateUsersTeamInput.java b/openbas-api/src/main/java/io/openbas/rest/team/form/UpdateUsersTeamInput.java index 04c2bcd05d..f9a8b78bae 100644 --- a/openbas-api/src/main/java/io/openbas/rest/team/form/UpdateUsersTeamInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/team/form/UpdateUsersTeamInput.java @@ -1,18 +1,14 @@ package io.openbas.rest.team.form; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; +import lombok.Data; +@Data public class UpdateUsersTeamInput { @JsonProperty("team_users") + @Schema(description = "The list of users the team contains") private List userIds; - - public List getUserIds() { - return userIds; - } - - public void setUserIds(List userIds) { - this.userIds = userIds; - } } diff --git a/openbas-api/src/main/java/io/openbas/rest/team/output/TeamOutput.java b/openbas-api/src/main/java/io/openbas/rest/team/output/TeamOutput.java index d6003d1f5a..6c9f0c2560 100644 --- a/openbas-api/src/main/java/io/openbas/rest/team/output/TeamOutput.java +++ b/openbas-api/src/main/java/io/openbas/rest/team/output/TeamOutput.java @@ -15,43 +15,53 @@ public class TeamOutput { @JsonProperty("team_id") @NotBlank + @Schema(description = "ID of the team") private String id; @JsonProperty("team_name") @NotBlank + @Schema(description = "Name of the team") private String name; @JsonProperty("team_description") + @Schema(description = "Description of the team") private String description; - @Schema(description = "exercise ids") + @Schema(description = "Simulation ids linked to this team") @JsonProperty("team_exercises") @NotBlank private Set exercises; - @Schema(description = "scenario ids") + @Schema(description = "Scenario ids linked to this team") @JsonProperty("team_scenarios") @NotBlank private Set scenarios; @JsonProperty("team_contextual") + @Schema( + description = + "True if the team is contextual (exists only in the scenario/simulation it is linked to)") private Boolean contextual; @JsonProperty("team_tags") + @Schema(description = "List of tags of the team") private Set tags; - @Schema(description = "user ids") + @Schema(description = "User ids of the team") @JsonProperty("team_users") private Set users; @JsonProperty("team_organization") + @Schema(description = "Organization of the team") private String organization; @JsonProperty("team_updated_at") @NotNull + @Schema(description = "Update date of the team") private Instant updatedAt; @JsonProperty("team_users_number") + @Schema(description = "Number of users of the team") public long getUsersNumber() { return getUsers().size(); } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/UserApi.java b/openbas-api/src/main/java/io/openbas/rest/user/UserApi.java index bfaa960713..f29d4cf525 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/UserApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/UserApi.java @@ -5,6 +5,7 @@ import static io.openbas.helper.DatabaseHelper.updateRelation; import static io.openbas.helper.StreamHelper.iterableToSet; +import io.openbas.aop.UserRoleDescription; import io.openbas.config.SessionManager; import io.openbas.database.model.User; import io.openbas.database.raw.RawUser; @@ -25,6 +26,14 @@ import io.openbas.service.UserService; import io.openbas.telemetry.Tracing; import io.openbas.utils.pagination.SearchPaginationInput; +import io.swagger.v3.oas.annotations.ExternalDocumentation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -42,6 +51,14 @@ import org.springframework.web.bind.annotation.*; @RestController +@UserRoleDescription +@Tag( + name = "Users management", + description = "Endpoints to manage users", + externalDocs = + @ExternalDocumentation( + description = "Documentation about users", + url = "https://docs.openbas.io/latest/administration/users/")) public class UserApi extends RestBehavior { public static final String USER_URI = "/api/users"; @@ -85,7 +102,16 @@ public void setUserCriteriaBuilderService(UserCriteriaBuilderService userCriteri this.userCriteriaBuilderService = userCriteriaBuilderService; } + @Operation(description = "Endpoint to login", summary = "Endpoint to login") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Login successful", + content = @Content(schema = @Schema(implementation = User.class))), + }) @PostMapping("/api/login") + @UserRoleDescription(needAuthenticated = false) public User login(@Valid @RequestBody LoginUserInput input) { Optional optionalUser = userRepository.findByEmailIgnoreCase(input.getLogin()); if (optionalUser.isPresent()) { @@ -98,6 +124,12 @@ public User login(@Valid @RequestBody LoginUserInput input) { throw new BadCredentialsException("Invalid credential."); } + @Operation(description = "Reset the password", summary = "Password reset") + @ApiResponses( + value = { + @ApiResponse(responseCode = "200", description = "Mail to reset the password sent"), + @ApiResponse(responseCode = "400", description = "The user was not found") + }) @PostMapping("/api/reset") public ResponseEntity passwordReset(@Valid @RequestBody ResetUserInput input) { Optional optionalUser = userRepository.findByEmailIgnoreCase(input.getLogin()); @@ -133,9 +165,18 @@ public ResponseEntity passwordReset(@Valid @RequestBody ResetUserInput input) return ResponseEntity.badRequest().build(); } + @Operation(description = "Change the password", summary = "Password change") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "The password was changed", + content = @Content(schema = @Schema(implementation = User.class))), + }) @PostMapping("/api/reset/{token}") public User changePasswordReset( - @PathVariable String token, @Valid @RequestBody ChangePasswordInput input) + @PathVariable @Schema(description = "Token generated during reset") String token, + @Valid @RequestBody ChangePasswordInput input) throws InputValidationException { String userId = resetTokenMap.get(token); if (userId != null) { @@ -154,35 +195,59 @@ public User changePasswordReset( throw new AccessDeniedException("Invalid credentials"); } + @Operation( + description = "Validate that the reset token does exist", + summary = "Check reset token") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "Mail to reset the password sent", + content = @Content(schema = @Schema(implementation = Boolean.class))), + }) @GetMapping("/api/reset/{token}") - public boolean validatePasswordResetToken(@PathVariable String token) { + public boolean validatePasswordResetToken( + @PathVariable @Schema(description = "Token generated during reset") String token) { return resetTokenMap.get(token) != null; } + @Operation(description = "List all the users", summary = "List users") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of users")}) @Secured(ROLE_ADMIN) @GetMapping("/api/users") public List users() { return userRepository.rawAll(); } + @Operation( + description = "Search the users corresponding to the criteria", + summary = "Search users") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of users")}) @PostMapping(USER_URI + "/search") public Page users( @RequestBody @Valid final SearchPaginationInput searchPaginationInput) { return this.userCriteriaBuilderService.userPagination(searchPaginationInput); } + @Operation(description = "Find a list of users based on their ids", summary = "Find users") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The list of users")}) @PostMapping(USER_URI + "/find") @Transactional(readOnly = true) @Tracing(name = "Find users", layer = "api", operation = "POST") - public List findUsers(@RequestBody @Valid @NotNull final List userIds) { + public List findUsers( + @RequestBody @Valid @NotNull @Parameter(description = "List of ids") + final List userIds) { return this.userCriteriaBuilderService.find(fromIds(userIds)); } @Secured(ROLE_ADMIN) @PutMapping("/api/users/{userId}/password") @Transactional(rollbackFor = Exception.class) + @Operation(description = "Change the password of a user", summary = "Change password") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The modified user")}) public User changePassword( - @PathVariable String userId, @Valid @RequestBody ChangePasswordInput input) { + @PathVariable @Schema(description = "ID of the user") String userId, + @Valid @RequestBody ChangePasswordInput input) { User user = userRepository.findById(userId).orElseThrow(ElementNotFoundException::new); user.setPassword(userService.encodeUserPassword(input.getPassword())); return userRepository.save(user); @@ -191,6 +256,8 @@ public User changePassword( @Secured(ROLE_ADMIN) @PostMapping("/api/users") @Transactional(rollbackFor = Exception.class) + @Operation(description = "Create a new user", summary = "Create user") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The new user")}) public User createUser(@Valid @RequestBody CreateUserInput input) { return userService.createUser(input, 1); } @@ -198,7 +265,11 @@ public User createUser(@Valid @RequestBody CreateUserInput input) { @Secured(ROLE_ADMIN) @PutMapping("/api/users/{userId}") @Transactional(rollbackFor = Exception.class) - public User updateUser(@PathVariable String userId, @Valid @RequestBody UpdateUserInput input) { + @Operation(description = "Update a user", summary = "Update user") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The modified user")}) + public User updateUser( + @PathVariable @Schema(description = "ID of the user") String userId, + @Valid @RequestBody UpdateUserInput input) { User user = userRepository.findById(userId).orElseThrow(ElementNotFoundException::new); user.setUpdateAttributes(input); user.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds()))); @@ -212,7 +283,9 @@ public User updateUser(@PathVariable String userId, @Valid @RequestBody UpdateUs @Secured(ROLE_ADMIN) @DeleteMapping("/api/users/{userId}") @Transactional(rollbackFor = Exception.class) - public void deleteUser(@PathVariable String userId) { + @Operation(description = "Delete a user", summary = "Delete user") + @ApiResponses(value = {@ApiResponse(responseCode = "200")}) + public void deleteUser(@PathVariable @Schema(description = "ID of the user") String userId) { sessionManager.invalidateUserSession(userId); userRepository.deleteById(userId); } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/form/login/LoginUserInput.java b/openbas-api/src/main/java/io/openbas/rest/user/form/login/LoginUserInput.java index a2c61a49cd..93190b6158 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/form/login/LoginUserInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/form/login/LoginUserInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.*; @@ -14,9 +15,11 @@ public class LoginUserInput { @NotBlank(message = MANDATORY_MESSAGE) + @Schema(description = "The identifier of the user") private String login; @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty + @Schema(description = "The password of the user") private String password; } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/form/user/ChangePasswordInput.java b/openbas-api/src/main/java/io/openbas/rest/user/form/user/ChangePasswordInput.java index 3f5c12ef36..c2277cc380 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/form/user/ChangePasswordInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/form/user/ChangePasswordInput.java @@ -3,31 +3,20 @@ import static io.openbas.config.AppConfig.MANDATORY_MESSAGE; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import lombok.Data; +@Data public class ChangePasswordInput { @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("password") + @Schema(description = "The new password") private String password; @NotBlank(message = MANDATORY_MESSAGE) @JsonProperty("password_validation") + @Schema(description = "The new password again to validate it's been typed well") private String passwordValidation; - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getPasswordValidation() { - return passwordValidation; - } - - public void setPasswordValidation(String passwordValidation) { - this.passwordValidation = passwordValidation; - } } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/form/user/CreateUserInput.java b/openbas-api/src/main/java/io/openbas/rest/user/form/user/CreateUserInput.java index 6a87e73b48..e0f5702dd9 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/form/user/CreateUserInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/form/user/CreateUserInput.java @@ -3,6 +3,7 @@ import static io.openbas.config.AppConfig.EMAIL_FORMAT; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; @@ -17,23 +18,30 @@ public class CreateUserInput { @Email(message = EMAIL_FORMAT) @NotBlank @JsonProperty("user_email") + @Schema(description = "The email of the user") private String email; @JsonProperty("user_admin") + @Schema(description = "True if the user is admin") private boolean admin; @JsonProperty("user_firstname") + @Schema(description = "First name of the user") private String firstname; @JsonProperty("user_lastname") + @Schema(description = "Last name of the user") private String lastname; @JsonProperty("user_organization") + @Schema(description = "Organization of the user") private String organizationId; @JsonProperty("user_plain_password") + @Schema(description = "Password of the user as plain text") private String password; @JsonProperty("user_tags") + @Schema(description = "Tags of the user") private List tagIds = new ArrayList<>(); } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/form/user/UpdateUserInput.java b/openbas-api/src/main/java/io/openbas/rest/user/form/user/UpdateUserInput.java index bfd76e6e0a..b0613ae762 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/form/user/UpdateUserInput.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/form/user/UpdateUserInput.java @@ -4,6 +4,7 @@ import static io.openbas.config.AppConfig.PHONE_FORMAT; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Pattern; import java.util.ArrayList; @@ -17,31 +18,40 @@ public class UpdateUserInput { @Email(message = EMAIL_FORMAT) @JsonProperty("user_email") + @Schema(description = "The email of the user") private String email; @JsonProperty("user_admin") + @Schema(description = "True if the user is admin") private boolean admin; @JsonProperty("user_firstname") + @Schema(description = "First name of the user") private String firstname; @JsonProperty("user_lastname") + @Schema(description = "Last name of the user") private String lastname; @JsonProperty("user_organization") + @Schema(description = "Organization of the user") private String organizationId; @JsonProperty("user_pgp_key") + @Schema(description = "PGP key of the user") private String pgpKey; @JsonProperty("user_phone") + @Schema(description = "Phone of the user") @Pattern(regexp = "^\\+[\\d\\s\\-.()]+$", message = PHONE_FORMAT) private String phone; @JsonProperty("user_phone2") + @Schema(description = "Secondary phone of the user") @Pattern(regexp = "^\\+[\\d\\s\\-.()]+$", message = PHONE_FORMAT) private String phone2; @JsonProperty("user_tags") + @Schema(description = "Tags of the user") private List tagIds = new ArrayList<>(); } diff --git a/openbas-api/src/main/java/io/openbas/rest/user/form/user/UserOutput.java b/openbas-api/src/main/java/io/openbas/rest/user/form/user/UserOutput.java index a4f2306a7c..12c39acf20 100644 --- a/openbas-api/src/main/java/io/openbas/rest/user/form/user/UserOutput.java +++ b/openbas-api/src/main/java/io/openbas/rest/user/form/user/UserOutput.java @@ -1,6 +1,7 @@ package io.openbas.rest.user.form.user; import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import java.util.Set; import lombok.Builder; @@ -12,24 +13,31 @@ public class UserOutput { @JsonProperty("user_id") @NotBlank + @Schema(description = "User ID") private String id; @JsonProperty("user_firstname") + @Schema(description = "First name of the user") private String firstname; @JsonProperty("user_lastname") + @Schema(description = "Last name of the user") private String lastname; @JsonProperty("user_email") @NotBlank + @Schema(description = "Email of the user") private String email; @JsonProperty("user_admin") + @Schema(description = "True if the user is admin") private boolean admin; @JsonProperty("user_organization_name") + @Schema(description = "Organization of the user") private String organizationName; @JsonProperty("user_tags") + @Schema(description = "Tags of the user") private Set tags; } diff --git a/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java b/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java index a85b5abd2c..13fddfdd86 100644 --- a/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java +++ b/openbas-api/src/main/java/io/openbas/scheduler/jobs/InjectsExecutionJob.java @@ -5,20 +5,24 @@ import static java.util.stream.Collectors.groupingBy; import com.fasterxml.jackson.databind.ObjectMapper; -import io.openbas.asset.QueueService; import io.openbas.database.model.*; -import io.openbas.database.model.InjectStatus; -import io.openbas.database.repository.*; +import io.openbas.database.repository.ExerciseRepository; +import io.openbas.database.repository.InjectDependenciesRepository; +import io.openbas.database.repository.InjectExpectationRepository; +import io.openbas.database.repository.InjectStatusRepository; import io.openbas.execution.ExecutableInject; -import io.openbas.execution.ExecutionExecutorService; import io.openbas.helper.InjectHelper; import io.openbas.rest.inject.service.InjectStatusService; +import io.openbas.scheduler.jobs.exception.ErrorMessagesPreExecutionException; import jakarta.annotation.Resource; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import java.util.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; @@ -26,8 +30,6 @@ import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -40,17 +42,13 @@ public class InjectsExecutionJob implements Job { private static final Logger LOGGER = Logger.getLogger(InjectsExecutionJob.class.getName()); - private final ApplicationContext context; private final InjectHelper injectHelper; - private final InjectRepository injectRepository; - private final InjectorRepository injectorRepository; private final InjectStatusRepository injectStatusRepository; private final ExerciseRepository exerciseRepository; - private final QueueService queueService; - private final ExecutionExecutorService executionExecutorService; private final InjectDependenciesRepository injectDependenciesRepository; private final InjectExpectationRepository injectExpectationRepository; private final InjectStatusService injectStatusService; + private final io.openbas.executors.Executor executor; private final List executionStatusesNotReady = List.of( @@ -64,13 +62,6 @@ public class InjectsExecutionJob implements Job { @Resource protected ObjectMapper mapper; - @PersistenceContext private EntityManager entityManager; - - @Autowired - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - public void handleAutoStartExercises() { List exercises = exerciseRepository.findAllShouldBeInRunningState(now()); exerciseRepository.saveAll( @@ -97,114 +88,20 @@ public void handleAutoClosingExercises() { .toList()); } - private void executeExternal(ExecutableInject executableInject) { - Inject inject = executableInject.getInjection().getInject(); - inject - .getInjectorContract() - .ifPresent( - injectorContract -> { - Injection source = executableInject.getInjection(); - try { - Inject executingInject = injectRepository.findById(source.getId()).orElseThrow(); - String jsonInject = mapper.writeValueAsString(executableInject); - queueService.publish(injectorContract.getInjector().getType(), jsonInject); - InjectStatus injectRunningStatus = executingInject.getStatus().orElseThrow(); - injectRunningStatus.setName(ExecutionStatus.PENDING); - injectStatusRepository.save(injectRunningStatus); - } catch (Exception e) { - injectStatusService.failInjectStatus(source.getId(), e.getMessage()); - } - }); - } - - private void executeInternal(ExecutableInject executableInject) { - Injection source = executableInject.getInjection(); - // Execute - source - .getInject() - .getInjectorContract() - .ifPresent( - injectorContract -> { - io.openbas.executors.Injector executor = - context.getBean( - injectorContract.getInjector().getType(), - io.openbas.executors.Injector.class); - Execution execution = executor.executeInjection(executableInject); - // After execution, expectations are already created - // Injection status is filled after complete execution - // Report inject execution - Inject executedInject = injectRepository.findById(source.getId()).orElseThrow(); - InjectStatus completeStatus = - injectStatusService.fromExecution(execution, executedInject); - executedInject.setUpdatedAt(now()); - executedInject.setStatus(completeStatus); - injectRepository.save(executedInject); - }); - } - - private void executeInject(ExecutableInject executableInject) { + private void executeInject(ExecutableInject executableInject) + throws IOException, TimeoutException, ErrorMessagesPreExecutionException { // Depending on injector type (internal or external) execution must be done differently Inject inject = executableInject.getInjection().getInject(); - // We are now checking if we depend on another inject and if it did not failed - Optional> errorMessages = Optional.empty(); if (ofNullable(executableInject.getExerciseId()).isPresent()) { - errorMessages = getErrorMessagesPreExecution(executableInject.getExerciseId(), inject); + checkErrorMessagesPreExecution(executableInject.getExerciseId(), inject); } - if (errorMessages != null && errorMessages.isPresent()) { - InjectStatus finalStatus = injectStatusService.failInjectStatus(inject.getId(), null); - errorMessages - .get() - .forEach(errorMsg -> finalStatus.addErrorTrace(errorMsg, ExecutionTraceAction.COMPLETE)); - injectStatusRepository.save(finalStatus); - } else { - setInjectStatusAndExecuteInject(executableInject, inject); + if (!inject.isReady()) { + throw new UnsupportedOperationException( + "The inject is not ready to be executed (missing mandatory fields)"); } - } - - private void setInjectStatusAndExecuteInject(ExecutableInject executableInject, Inject inject) { - inject - .getInjectorContract() - .ifPresentOrElse( - injectorContract -> { - if (!inject.isReady()) { - injectStatusService.failInjectStatus( - inject.getId(), - "The inject is not ready to be executed (missing mandatory fields)"); - return; - } - - Injector externalInjector = - injectorRepository - .findByType(injectorContract.getInjector().getType()) - .orElseThrow(); - LOGGER.log(Level.INFO, "Executing inject " + inject.getInject().getTitle()); - // Executor logics - ExecutableInject newExecutableInject = executableInject; - - InjectStatus injectStatus = - injectStatusService.initializeInjectStatus( - inject.getId(), ExecutionStatus.EXECUTING, null); - if (Boolean.TRUE.equals(injectorContract.getNeedsExecutor())) { - // Status - inject.setStatus(injectStatus); - try { - newExecutableInject = - this.executionExecutorService.launchExecutorContext(executableInject, inject); - } catch (Exception e) { - injectStatusService.failInjectStatus(inject.getId(), e.getMessage()); - return; - } - } - if (externalInjector.isExternal()) { - executeExternal(newExecutableInject); - } else { - executeInternal(newExecutableInject); - } - }, - () -> - injectStatusService.failInjectStatus( - inject.getId(), "Inject does not have a contract")); + LOGGER.log(Level.INFO, "Executing inject " + inject.getInject().getTitle()); + this.executor.execute(executableInject); } /** @@ -214,7 +111,8 @@ private void setInjectStatusAndExecuteInject(ExecutableInject executableInject, * @param inject the inject to check * @return an optional of list of error message */ - private Optional> getErrorMessagesPreExecution(String exerciseId, Inject inject) { + private void checkErrorMessagesPreExecution(String exerciseId, Inject inject) + throws ErrorMessagesPreExecutionException { List injectDependencies = injectDependenciesRepository.findParents(List.of(inject.getId())); if (!injectDependencies.isEmpty()) { @@ -226,7 +124,7 @@ private Optional> getErrorMessagesPreExecution(String exerciseId, I Map mapCondition = getStringBooleanMap(parents, exerciseId, injectDependencies); - List results = null; + List errorMessages = new ArrayList<>(); for (InjectDependency injectDependency : injectDependencies) { String expressionToEvaluate = injectDependency.getInjectDependencyCondition().toString(); @@ -245,20 +143,20 @@ private Optional> getErrorMessagesPreExecution(String exerciseId, I Expression exp = parser.parseExpression(expressionToEvaluate); boolean canBeExecuted = Boolean.TRUE.equals(exp.getValue(mapCondition, Boolean.class)); if (!canBeExecuted) { - if (results == null) { - results = new ArrayList<>(); - results.add( + if (errorMessages.isEmpty()) { + errorMessages.add( "This inject depends on other injects expectations that are not met. The following conditions were not as expected : "); } - results.addAll( + errorMessages.addAll( labelFromCondition( injectDependency.getCompositeId().getInjectParent(), injectDependency.getInjectDependencyCondition())); } } - return results == null ? Optional.empty() : Optional.of(results); + if (!errorMessages.isEmpty()) { + throw new ErrorMessagesPreExecutionException(errorMessages); + } } - return Optional.empty(); } /** @@ -271,18 +169,13 @@ private Optional> getErrorMessagesPreExecution(String exerciseId, I */ private @NotNull Map getStringBooleanMap( List parents, String exerciseId, List injectDependencies) { - Map mapCondition = new HashMap<>(); - - injectDependencies.forEach( - injectDependency -> { - injectDependency - .getInjectDependencyCondition() - .getConditions() - .forEach( - condition -> { - mapCondition.put(condition.getKey(), false); - }); - }); + Map mapCondition = + injectDependencies.stream() + .flatMap( + injectDependency -> + injectDependency.getInjectDependencyCondition().getConditions().stream()) + .collect( + Collectors.toMap(InjectDependencyConditions.Condition::getKey, condition -> false)); parents.forEach( parent -> { @@ -354,7 +247,16 @@ public void execute(JobExecutionContext jobExecutionContext) throws JobExecution byExercises.forEach( (exercise, executableInjects) -> { // Execute each inject for the exercise in order. - executableInjects.forEach(this::executeInject); + executableInjects.forEach( + executableInject -> { + try { + this.executeInject(executableInject); + } catch (Exception e) { + Inject inject = executableInject.getInjection().getInject(); + LOGGER.log(Level.WARNING, e.getMessage(), e); + injectStatusService.failInjectStatus(inject.getId(), e.getMessage()); + } + }); // Update the exercise if (!exercise.equals("atomic")) { updateExercise(exercise); diff --git a/openbas-api/src/main/java/io/openbas/scheduler/jobs/exception/ErrorMessagesPreExecutionException.java b/openbas-api/src/main/java/io/openbas/scheduler/jobs/exception/ErrorMessagesPreExecutionException.java new file mode 100644 index 0000000000..664e6e9be5 --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/scheduler/jobs/exception/ErrorMessagesPreExecutionException.java @@ -0,0 +1,17 @@ +package io.openbas.scheduler.jobs.exception; + +import java.util.List; + +public class ErrorMessagesPreExecutionException extends Exception { + + public ErrorMessagesPreExecutionException(List messages) { + super(formatMessages(messages)); + } + + private static String formatMessages(List messages) { + if (messages == null || messages.isEmpty()) { + return "An unknown error occurred before execution."; + } + return String.join("; ", messages); + } +} diff --git a/openbas-api/src/main/java/io/openbas/service/AssetGroupService.java b/openbas-api/src/main/java/io/openbas/service/AssetGroupService.java index 7de2d00250..5cd85f6846 100644 --- a/openbas-api/src/main/java/io/openbas/service/AssetGroupService.java +++ b/openbas-api/src/main/java/io/openbas/service/AssetGroupService.java @@ -81,9 +81,19 @@ public void deleteAssetGroup(@NotBlank final String assetGroupId) { @Transactional(readOnly = true) public List assetsFromAssetGroup(@NotBlank final String assetGroupId) { AssetGroup assetGroup = this.assetGroup(assetGroupId); - return Stream.concat(assetGroup.getAssets().stream(), assetGroup.getDynamicAssets().stream()) - .distinct() - .collect(Collectors.toList()); + List assets = new ArrayList<>(); + List assetIds = new ArrayList<>(); + Stream.concat(assetGroup.getAssets().stream(), assetGroup.getDynamicAssets().stream()) + .forEach( + asset -> { + // We have to call getId() because some assets are returned null because of Hibernate + // unproxy + if (!assetIds.contains(asset.getId())) { + assets.add(asset); + assetIds.add(asset.getId()); + } + }); + return assets; } private List computeDynamicAssets(@NotNull final List assetGroups) { diff --git a/openbas-api/src/main/java/io/openbas/service/InjectImportService.java b/openbas-api/src/main/java/io/openbas/service/InjectImportService.java index 83debf33d2..4ddc07e0ab 100644 --- a/openbas-api/src/main/java/io/openbas/service/InjectImportService.java +++ b/openbas-api/src/main/java/io/openbas/service/InjectImportService.java @@ -14,6 +14,7 @@ import io.openbas.rest.scenario.response.ImportMessage; import io.openbas.rest.scenario.response.ImportPostSummary; import io.openbas.rest.scenario.response.ImportTestSummary; +import io.openbas.service.utils.InjectImportUtils; import io.openbas.utils.InjectUtils; import java.io.IOException; import java.io.InputStream; @@ -39,7 +40,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.java.Log; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.logging.log4j.util.Strings; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellReference; @@ -492,7 +492,9 @@ private ImportRow importRow( Matcher matcher = mapPatternByInjectImport .get(injectImporter.getId()) - .matcher(getValueAsString(row, importMapper.getInjectTypeColumn())); + .matcher( + InjectImportUtils.getValueAsString( + row, importMapper.getInjectTypeColumn())); return matcher.find(); }) .toList(); @@ -565,7 +567,7 @@ private ImportRow importRow( if (triggerTimeRuleAttribute.getColumns() != null) { dateAsString = Arrays.stream(triggerTimeRuleAttribute.getColumns().split("\\+")) - .map(column -> getDateAsStringFromCell(row, column, timePattern)) + .map(column -> InjectImportUtils.getDateAsStringFromCell(row, column, timePattern)) .collect(Collectors.joining()); } if (dateAsString.isBlank()) { @@ -584,7 +586,7 @@ private ImportRow importRow( injectTime.setUnformattedDate(dateAsString); injectTime.setLinkedInject(inject); - Temporal dateTime = getInjectDate(injectTime, timePattern); + Temporal dateTime = InjectImportUtils.getInjectDate(injectTime, timePattern); if (dateTime == null) { injectTime.setRelativeDay(relativeDays); @@ -758,7 +760,7 @@ private void setAttributeValue( if (valueCell == null) { setter.accept(ruleAttribute.getDefaultValue()); } else { - String cellValue = getValueAsString(row, ruleAttribute.getColumns()); + String cellValue = InjectImportUtils.getValueAsString(row, ruleAttribute.getColumns()); setter.accept(cellValue.isBlank() ? ruleAttribute.getDefaultValue() : cellValue); } } @@ -806,9 +808,8 @@ private List addFields( String columnValue = Strings.EMPTY; if (ruleAttribute.getColumns() != null) { columnValue = - Arrays.stream(ruleAttribute.getColumns().split("\\+")) - .map(column -> getValueAsString(row, column)) - .collect(Collectors.joining()); + InjectImportUtils.extractAndConvertStringColumnValue( + row, ruleAttribute, mapFieldByKey); } if (columnValue.isBlank()) { inject.getContent().put(ruleAttribute.getDefaultValue(), columnValue); @@ -830,7 +831,7 @@ private List addFields( columnValues = Arrays.stream( Arrays.stream(ruleAttribute.getColumns().split("\\+")) - .map(column -> getValueAsString(row, column)) + .map(column -> InjectImportUtils.getValueAsString(row, column)) .collect(Collectors.joining(",")) .split(",")) .toList(); @@ -908,7 +909,7 @@ private List addFields( == CellType.NUMERIC)) { Double columnValueExpectation = columns.stream() - .map(column -> getValueAsDouble(row, column)) + .map(column -> InjectImportUtils.getValueAsDouble(row, column)) .reduce(0.0, Double::sum); expectation.get().setExpectedScore(columnValueExpectation.doubleValue()); } else { @@ -939,7 +940,7 @@ private List addFields( if (ruleAttribute.getColumns() != null) { String columnValueExpectation = Arrays.stream(ruleAttribute.getColumns().split("\\+")) - .map(column -> getValueAsString(row, column)) + .map(column -> InjectImportUtils.getValueAsString(row, column)) .collect(Collectors.joining()); expectation .get() @@ -954,7 +955,7 @@ private List addFields( if (ruleAttribute.getColumns() != null) { String columnValueExpectation = Arrays.stream(ruleAttribute.getColumns().split("\\+")) - .map(column -> getValueAsString(row, column)) + .map(column -> InjectImportUtils.getValueAsString(row, column)) .collect(Collectors.joining()); expectation .get() @@ -975,36 +976,6 @@ private List addFields( return emptyList(); } - private Temporal getInjectDate(InjectTime injectTime, String timePattern) { - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME; - if (timePattern != null && !timePattern.isEmpty()) { - dateTimeFormatter = DateTimeFormatter.ofPattern(timePattern); - try { - return LocalDateTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); - } catch (DateTimeParseException firstException) { - try { - return LocalTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); - } catch (DateTimeParseException exception) { - // This is a "probably" a relative date - } - } - } else { - try { - return LocalDateTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); - } catch (DateTimeParseException firstException) { - // The date is not in ISO_DATE_TIME. Trying just the ISO_TIME - dateTimeFormatter = DateTimeFormatter.ISO_TIME; - try { - return LocalDateTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); - } catch (DateTimeParseException secondException) { - // Neither ISO_DATE_TIME nor ISO_TIME - } - } - } - injectTime.setFormatter(dateTimeFormatter); - return null; - } - private List updateInjectDates(Map mapInstantByRowIndex) { List importMessages = new ArrayList<>(); // First of all, are there any absolute date @@ -1195,50 +1166,4 @@ private void processDateToAbsolute(Map mapInstantByRowIndex - earliestInstant.getEpochSecond()); })); } - - private String getDateAsStringFromCell(Row row, String cellColumn, String timePattern) { - if (cellColumn != null - && !cellColumn.isBlank() - && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { - Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); - if (cell.getCellType() == CellType.STRING) { - return cell.getStringCellValue(); - } else if (cell.getCellType() == CellType.NUMERIC) { - if (timePattern == null || timePattern.isEmpty()) { - return cell.getDateCellValue().toString(); - } else { - return DateFormatUtils.format(cell.getDateCellValue(), timePattern); - } - } - } - return ""; - } - - private String getValueAsString(Row row, String cellColumn) { - if (cellColumn != null - && !cellColumn.isBlank() - && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { - Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); - if (cell.getCellType() == CellType.STRING) { - return cell.getStringCellValue(); - } else if (cell.getCellType() == CellType.NUMERIC) { - return Double.valueOf(cell.getNumericCellValue()).toString(); - } - } - return ""; - } - - private Double getValueAsDouble(Row row, String cellColumn) { - if (cellColumn != null - && !cellColumn.isBlank() - && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { - Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); - if (cell.getCellType() == CellType.STRING) { - return Double.valueOf(cell.getStringCellValue()); - } else if (cell.getCellType() == CellType.NUMERIC) { - return cell.getNumericCellValue(); - } - } - return 0.0; - } } diff --git a/openbas-api/src/main/java/io/openbas/service/InjectTestStatusService.java b/openbas-api/src/main/java/io/openbas/service/InjectTestStatusService.java index 339908b400..36d9dcf78c 100644 --- a/openbas-api/src/main/java/io/openbas/service/InjectTestStatusService.java +++ b/openbas-api/src/main/java/io/openbas/service/InjectTestStatusService.java @@ -3,10 +3,7 @@ import static io.openbas.config.SessionHelper.currentUser; import static io.openbas.utils.pagination.PaginationUtils.buildPaginationJPA; -import io.openbas.database.model.Execution; -import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectTestStatus; -import io.openbas.database.model.User; +import io.openbas.database.model.*; import io.openbas.database.repository.InjectRepository; import io.openbas.database.repository.InjectTestStatusRepository; import io.openbas.database.repository.UserRepository; @@ -16,6 +13,8 @@ import io.openbas.execution.ExecutionContextService; import io.openbas.executors.Injector; import io.openbas.rest.exception.BadRequestException; +import io.openbas.rest.inject.output.InjectTestStatusOutput; +import io.openbas.utils.InjectMapper; import io.openbas.utils.pagination.SearchPaginationInput; import jakarta.persistence.EntityNotFoundException; import java.util.ArrayList; @@ -39,13 +38,14 @@ public class InjectTestStatusService { private final InjectRepository injectRepository; private final ExecutionContextService executionContextService; private final InjectTestStatusRepository injectTestStatusRepository; + private final InjectMapper injectMapper; @Autowired public void setContext(ApplicationContext context) { this.context = context; } - public InjectTestStatus testInject(String injectId) { + public InjectTestStatusOutput testInject(String injectId) { Inject inject = this.injectRepository .findById(injectId) @@ -60,7 +60,8 @@ public InjectTestStatus testInject(String injectId) { .findById(currentUser().getId()) .orElseThrow(() -> new EntityNotFoundException("User not found")); - return testInject(inject, user); + InjectTestStatus injectStatus = testInject(inject, user); + return injectMapper.toInjectTestStatusOutput(injectStatus); } /** @@ -69,7 +70,8 @@ public InjectTestStatus testInject(String injectId) { * @param searchSpecifications the criteria to search injects to test * @return the list of inject test status */ - public List bulkTestInjects(final Specification searchSpecifications) { + public List bulkTestInjects( + final Specification searchSpecifications) { List searchResult = this.injectRepository.findAll(searchSpecifications); if (searchResult.isEmpty()) { throw new BadRequestException("No inject ID is testable"); @@ -81,33 +83,36 @@ public List bulkTestInjects(final Specification search List results = new ArrayList<>(); searchResult.forEach(inject -> results.add(testInject(inject, user))); - return results; + return results.stream().map(injectMapper::toInjectTestStatusOutput).toList(); } - public Page findAllInjectTestsByExerciseId( + public Page findAllInjectTestsByExerciseId( String exerciseId, SearchPaginationInput searchPaginationInput) { return buildPaginationJPA( - (Specification specification, Pageable pageable) -> - injectTestStatusRepository.findAll( - InjectTestSpecification.findInjectTestInExercise(exerciseId).and(specification), - pageable), - searchPaginationInput, - InjectTestStatus.class); + (Specification specification, Pageable pageable) -> + injectTestStatusRepository.findAll( + InjectTestSpecification.findInjectTestInExercise(exerciseId).and(specification), + pageable), + searchPaginationInput, + InjectTestStatus.class) + .map(injectMapper::toInjectTestStatusOutput); } - public Page findAllInjectTestsByScenarioId( + public Page findAllInjectTestsByScenarioId( String scenarioId, SearchPaginationInput searchPaginationInput) { return buildPaginationJPA( - (Specification specification, Pageable pageable) -> - injectTestStatusRepository.findAll( - InjectTestSpecification.findInjectTestInScenario(scenarioId).and(specification), - pageable), - searchPaginationInput, - InjectTestStatus.class); + (Specification specification, Pageable pageable) -> + injectTestStatusRepository.findAll( + InjectTestSpecification.findInjectTestInScenario(scenarioId).and(specification), + pageable), + searchPaginationInput, + InjectTestStatus.class) + .map(injectMapper::toInjectTestStatusOutput); } - public InjectTestStatus findInjectTestStatusById(String testId) { - return injectTestStatusRepository.findById(testId).orElseThrow(); + public InjectTestStatusOutput findInjectTestStatusById(String testId) { + return injectMapper.toInjectTestStatusOutput( + injectTestStatusRepository.findById(testId).orElseThrow()); } // -- PRIVATE -- diff --git a/openbas-api/src/main/java/io/openbas/service/utils/InjectImportUtils.java b/openbas-api/src/main/java/io/openbas/service/utils/InjectImportUtils.java new file mode 100644 index 0000000000..0f1819db1d --- /dev/null +++ b/openbas-api/src/main/java/io/openbas/service/utils/InjectImportUtils.java @@ -0,0 +1,150 @@ +package io.openbas.service.utils; + +import com.fasterxml.jackson.databind.JsonNode; +import io.openbas.database.model.RuleAttribute; +import io.openbas.service.InjectTime; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.Temporal; +import java.util.*; +import java.util.stream.Collectors; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.util.CellReference; + +public class InjectImportUtils { + + /** + * Returns the date as string from an excel cell + * + * @param row the row + * @param cellColumn the column + * @param timePattern the pattern to use to convert the date + * @return the date as string + */ + public static String getDateAsStringFromCell(Row row, String cellColumn, String timePattern) { + if (cellColumn != null + && !cellColumn.isBlank() + && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { + Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); + if (cell.getCellType() == CellType.STRING) { + return cell.getStringCellValue(); + } else if (cell.getCellType() == CellType.NUMERIC) { + if (timePattern == null || timePattern.isEmpty()) { + return cell.getDateCellValue().toString(); + } else { + return DateFormatUtils.format(cell.getDateCellValue(), timePattern); + } + } + } + return ""; + } + + /** + * Get the value of a cell as a string + * + * @param row the row + * @param cellColumn the column + * @return the value of the cell as string + */ + public static String getValueAsString(Row row, String cellColumn) { + if (cellColumn != null + && !cellColumn.isBlank() + && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { + Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); + if (cell.getCellType() == CellType.STRING) { + return cell.getStringCellValue(); + } else if (cell.getCellType() == CellType.NUMERIC) { + return Double.valueOf(cell.getNumericCellValue()).toString(); + } + } + return ""; + } + + /** + * Get the value of a cell as a double + * + * @param row the row + * @param cellColumn the column + * @return the value of the cell as a double + */ + public static Double getValueAsDouble(Row row, String cellColumn) { + if (cellColumn != null + && !cellColumn.isBlank() + && row.getCell(CellReference.convertColStringToIndex(cellColumn)) != null) { + Cell cell = row.getCell(CellReference.convertColStringToIndex(cellColumn)); + if (cell.getCellType() == CellType.STRING) { + return Double.valueOf(cell.getStringCellValue()); + } else if (cell.getCellType() == CellType.NUMERIC) { + return cell.getNumericCellValue(); + } + } + return 0.0; + } + + /** + * Extract the value as string and convert it to HTML if need be + * + * @param row the row + * @param ruleAttribute the rule to use to extract the value + * @param mapFieldByKey the map of the fields organized by the name of the field + * @return the value as string + */ + public static String extractAndConvertStringColumnValue( + Row row, RuleAttribute ruleAttribute, Map mapFieldByKey) { + String columnValue = + Arrays.stream(ruleAttribute.getColumns().split("\\+")) + .map(column -> getValueAsString(row, column)) + .collect(Collectors.joining()); + + // Given that richText fields are editable using CKEditor which expects HTML, + // we're converting return line into
. + // TODO : convert properly the whole cell into HTML including formatting (bold, ...) + if (mapFieldByKey.get(ruleAttribute.getName()).get("richText") != null + && mapFieldByKey.get(ruleAttribute.getName()).get("richText").asBoolean()) { + columnValue = columnValue.replaceAll("\n", "
"); + } + return columnValue; + } + + /** + * Returns a date out of an InjectTime object with a time pattern + * + * @param injectTime the object representing a date in the cells + * @param timePattern a pattern to use to find out what value it is + * @return the date + */ + public static Temporal getInjectDate(InjectTime injectTime, String timePattern) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME; + if (timePattern != null && !timePattern.isEmpty()) { + dateTimeFormatter = DateTimeFormatter.ofPattern(timePattern); + try { + return LocalDateTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); + } catch (DateTimeParseException firstException) { + try { + return LocalTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); + } catch (DateTimeParseException exception) { + // This is a "probably" a relative date + } + } + } else { + try { + return LocalDateTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); + } catch (DateTimeParseException firstException) { + // The date is not in ISO_DATE_TIME. Trying just the ISO_TIME + dateTimeFormatter = DateTimeFormatter.ISO_TIME; + try { + return LocalTime.parse(injectTime.getUnformattedDate(), dateTimeFormatter); + } catch (DateTimeParseException secondException) { + // Neither ISO_DATE_TIME nor ISO_TIME + } + } + } + injectTime.setFormatter(dateTimeFormatter); + return null; + } +} diff --git a/openbas-api/src/main/java/io/openbas/utils/InjectMapper.java b/openbas-api/src/main/java/io/openbas/utils/InjectMapper.java index d866c3191c..0f3bdb4ed6 100644 --- a/openbas-api/src/main/java/io/openbas/utils/InjectMapper.java +++ b/openbas-api/src/main/java/io/openbas/utils/InjectMapper.java @@ -2,10 +2,9 @@ import io.openbas.database.model.*; import io.openbas.rest.atomic_testing.form.*; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import io.openbas.rest.inject.output.InjectTestStatusOutput; +import java.util.*; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; @@ -97,23 +96,93 @@ private PayloadSimple toPayloadSimple(Optional payload) { } // -- STATUS to STATUSIMPLE -- + private T buildInjectStatusOutput( + T output, BaseInjectStatus status, List executionTraces) { + output.setId(status.getId()); + output.setName(status.getName().name()); + output.setTraces( + toExecutionTracesOutput( + executionTraces.stream().filter(trace -> trace.getAgent() == null).toList())); + output.setTracesByAgent( + groupTracesByAgent( + executionTraces.stream().filter(trace -> trace.getAgent() != null).toList())); + output.setTrackingSentDate(status.getTrackingSentDate()); + output.setTrackingEndDate(status.getTrackingEndDate()); + return output; + } + public InjectStatusOutput toInjectStatusOutput(Optional injectStatus) { return injectStatus .map( status -> - InjectStatusOutput.builder() - .id(status.getId()) - .name( - Optional.ofNullable(status.getName()) - .map(ExecutionStatus::name) - .orElse(null)) - .traces(status.getTraces()) - .trackingSentDate(status.getTrackingSentDate()) - .trackingEndDate(status.getTrackingEndDate()) - .build()) + this.buildInjectStatusOutput( + InjectStatusOutput.builder().build(), status, status.getTraces())) .orElseGet(() -> InjectStatusOutput.builder().build()); } + public InjectTestStatusOutput toInjectTestStatusOutput(InjectTestStatus injectTestStatus) { + InjectTestStatusOutput output = InjectTestStatusOutput.builder().build(); + buildInjectStatusOutput(output, injectTestStatus, injectTestStatus.getTraces()); + + output.setInjectId(injectTestStatus.getInject().getId()); + output.setInjectType( + injectTestStatus + .getInject() + .getInjectorContract() + .map(InjectorContract::getInjector) + .map(Injector::getType) + .orElse(null)); + output.setInjectTitle(injectTestStatus.getInject().getTitle()); + + return output; + } + + public List toExecutionTracesOutput(List traces) { + return traces.stream() + .map( + trace -> + ExecutionTracesOutput.builder() + .status(trace.getStatus()) + .time(trace.getTime()) + .message(trace.getMessage()) + .action(trace.getAction()) + .build()) + .toList(); + } + + private List groupTracesByAgent(List traces) { + return traces.stream() + .collect(Collectors.groupingBy(ExecutionTraces::getAgent)) + .entrySet() + .stream() + .map( + entry -> { + ExecutionTraces finalTrace = + entry.getValue().stream() + .filter(t -> t.getAction() == ExecutionTraceAction.COMPLETE) + .findFirst() + .orElse(null); + Agent agent = entry.getKey(); + return AgentStatusOutput.builder() + .assetId(agent.getAsset().getId()) + .agentId(agent.getId()) + .agentExecutorName(agent.getExecutor().getName()) + .agentExecutorType(agent.getExecutor().getType()) + .agentName(agent.getExecutedByUser()) + .statusName(finalTrace != null ? finalTrace.getStatus().name() : null) + .trackingEndDate(finalTrace != null ? finalTrace.getTime() : null) + .trackingSentDate( + entry.getValue().stream() + .filter(t -> t.getAction() == ExecutionTraceAction.START) + .findFirst() + .map(ExecutionTraces::getTime) + .orElse(null)) + .agentTraces(toExecutionTracesOutput(entry.getValue())) + .build(); + }) + .toList(); + } + // -- EXPECTATIONS to EXPECTATIONSIMPLE public List toInjectExpectationSimples( List expectations) { diff --git a/openbas-api/src/main/java/io/openbas/utils/InjectUtils.java b/openbas-api/src/main/java/io/openbas/utils/InjectUtils.java index 469b555348..5d819b8da9 100644 --- a/openbas-api/src/main/java/io/openbas/utils/InjectUtils.java +++ b/openbas-api/src/main/java/io/openbas/utils/InjectUtils.java @@ -5,6 +5,7 @@ import static io.openbas.database.model.Executable.EXECUTABLE_TYPE; import static io.openbas.database.model.FileDrop.FILE_DROP_TYPE; import static io.openbas.database.model.NetworkTraffic.NETWORK_TRAFFIC_TYPE; +import static java.util.Collections.emptyList; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -55,6 +56,9 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { payloadCommandBlock.setCleanupCommand(List.of(payloadCommand.getCleanupCommand())); } return new StatusPayload( + payloadCommand.getName(), + payloadCommand.getDescription(), + COMMAND_TYPE, null, null, null, @@ -75,6 +79,9 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { Payload payload = injectorContract.getPayload(); Executable payloadExecutable = (Executable) Hibernate.unproxy(payload); return new StatusPayload( + payloadExecutable.getName(), + payloadExecutable.getDescription(), + EXECUTABLE_TYPE, null, null, null, @@ -86,7 +93,7 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { null, null, null, - null, + emptyList(), null); } else if (injectorContract.getPayload() != null && FILE_DROP_TYPE.equals(injectorContract.getPayload().getType())) { @@ -94,6 +101,9 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { Payload payload = injectorContract.getPayload(); FileDrop payloadFileDrop = (FileDrop) Hibernate.unproxy(payload); return new StatusPayload( + payloadFileDrop.getName(), + payloadFileDrop.getDescription(), + FILE_DROP_TYPE, null, null, null, @@ -105,7 +115,7 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { null, null, null, - null, + emptyList(), null); } else if (injectorContract.getPayload() != null && DNS_RESOLUTION_TYPE.equals(injectorContract.getPayload().getType())) { @@ -113,6 +123,9 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { Payload payload = injectorContract.getPayload(); DnsResolution payloadDnsResolution = (DnsResolution) Hibernate.unproxy(payload); return new StatusPayload( + payloadDnsResolution.getName(), + payloadDnsResolution.getDescription(), + DNS_RESOLUTION_TYPE, null, null, null, @@ -124,7 +137,7 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { null, null, null, - null, + emptyList(), null); } else if (injectorContract.getPayload() != null && NETWORK_TRAFFIC_TYPE.equals(injectorContract.getPayload().getType())) { @@ -132,6 +145,9 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { Payload payload = injectorContract.getPayload(); NetworkTraffic payloadNetworkTraffic = (NetworkTraffic) Hibernate.unproxy(payload); return new StatusPayload( + payloadNetworkTraffic.getName(), + payloadNetworkTraffic.getDescription(), + NETWORK_TRAFFIC_TYPE, payloadNetworkTraffic.getProtocol(), payloadNetworkTraffic.getPortDst(), payloadNetworkTraffic.getPortSrc(), @@ -143,7 +159,7 @@ public StatusPayload getStatusPayloadFromInject(final Inject inject) { null, null, null, - null, + emptyList(), null); } else { try { diff --git a/openbas-api/src/main/java/io/openbas/utils/PayloadMapper.java b/openbas-api/src/main/java/io/openbas/utils/PayloadMapper.java index 834dc355a5..7f52377603 100644 --- a/openbas-api/src/main/java/io/openbas/utils/PayloadMapper.java +++ b/openbas-api/src/main/java/io/openbas/utils/PayloadMapper.java @@ -10,110 +10,199 @@ import io.openbas.database.model.*; import io.openbas.rest.atomic_testing.form.AttackPatternSimple; import io.openbas.rest.atomic_testing.form.StatusPayloadOutput; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; +import lombok.RequiredArgsConstructor; +import lombok.extern.java.Log; import org.hibernate.Hibernate; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; +@RequiredArgsConstructor @Component +@Log public class PayloadMapper { + private final ApplicationContext context; + public StatusPayloadOutput getStatusPayloadOutputFromInject(Optional inject) { + + if (inject.isEmpty()) return StatusPayloadOutput.builder().build(); + + Inject injectObj = inject.get(); + Optional injectorContractOpt = injectObj.getInjectorContract(); + if (injectorContractOpt.isEmpty()) return StatusPayloadOutput.builder().build(); + + InjectorContract injectorContract = injectorContractOpt.get(); StatusPayloadOutput.StatusPayloadOutputBuilder statusPayloadOutputBuilder = StatusPayloadOutput.builder(); - StatusPayloadOutput result = statusPayloadOutputBuilder.build(); - if (inject.isPresent()) { - Optional injectorContractOpt = inject.get().getInjectorContract(); - if (injectorContractOpt.isPresent()) { - InjectorContract injectorContract = injectorContractOpt.get(); - - if (ofNullable(inject.get().getContent()) - .map(c -> c.has("obfuscator")) - .orElse(Boolean.FALSE)) { - String obfuscator = inject.get().getContent().findValue("obfuscator").asText(); - statusPayloadOutputBuilder.obfuscator(obfuscator); - } - - if (inject.get().getStatus().isEmpty()) { - Payload payload = injectorContract.getPayload(); - statusPayloadOutputBuilder - .arguments(payload.getArguments()) - .prerequisites(payload.getPrerequisites()) - .externalId(payload.getExternalId()) - .cleanupExecutor(payload.getCleanupExecutor()) - .name(injectorContract.getPayload().getName()) - .type(injectorContract.getPayload().getType()) - .collectorType(injectorContract.getPayload().getCollectorType()) - .description(injectorContract.getPayload().getDescription()) - .platforms(injectorContract.getPayload().getPlatforms()) - .attackPatterns(toAttackPatternSimples(injectorContract.getAttackPatterns())) - .executableArch(injectorContract.getArch()); - if (COMMAND_TYPE.equals(injectorContract.getPayload().getType())) { - Command payloadCommand = (Command) Hibernate.unproxy(payload); - List cleanupCommands = new ArrayList<>(); - if (payloadCommand.getCleanupCommand() != null) { - cleanupCommands.add(payloadCommand.getCleanupCommand()); - } - List payloadCommandBlocks = new ArrayList<>(); - PayloadCommandBlock payloadCommandBlock = - new PayloadCommandBlock( - payloadCommand.getExecutor(), payloadCommand.getContent(), cleanupCommands); - payloadCommandBlocks.add(payloadCommandBlock); - statusPayloadOutputBuilder.payloadCommandBlocks(payloadCommandBlocks); - } else if (EXECUTABLE_TYPE.equals(injectorContract.getPayload().getType())) { - Executable payloadExecutable = (Executable) Hibernate.unproxy(payload); - statusPayloadOutputBuilder.executableFile(payloadExecutable.getExecutableFile()); - } else if (FILE_DROP_TYPE.equals(injectorContract.getPayload().getType())) { - FileDrop payloadFileDrop = (FileDrop) Hibernate.unproxy(payload); - statusPayloadOutputBuilder.fileDropFile(payloadFileDrop.getFileDropFile()); - } else if (DNS_RESOLUTION_TYPE.equals(injectorContract.getPayload().getType())) { - DnsResolution payloadDnsResolution = (DnsResolution) Hibernate.unproxy(payload); - statusPayloadOutputBuilder.hostname(payloadDnsResolution.getHostname()); - } else if (NETWORK_TRAFFIC_TYPE.equals(injectorContract.getPayload().getType())) { - NetworkTraffic payloadNetworkTraffic = (NetworkTraffic) Hibernate.unproxy(payload); - statusPayloadOutputBuilder - .protocol(payloadNetworkTraffic.getProtocol()) - .portSrc(payloadNetworkTraffic.getPortSrc()) - .portDst(payloadNetworkTraffic.getPortDst()) - .ipSrc(payloadNetworkTraffic.getIpSrc()) - .ipDst(payloadNetworkTraffic.getIpDst()); - } - result = statusPayloadOutputBuilder.build(); - } else if (inject.get().getStatus().isPresent() - && inject.get().getStatus().get().getPayloadOutput() != null) { - // Commands lines saved because inject has been executed - StatusPayload statusPayload = inject.get().getStatus().get().getPayloadOutput(); - statusPayloadOutputBuilder - .cleanupExecutor(statusPayload.getCleanupExecutor()) - .payloadCommandBlocks(statusPayload.getPayloadCommandBlocks()) - .arguments(statusPayload.getArguments()) - .prerequisites(statusPayload.getPrerequisites()) - .externalId(statusPayload.getExternalId()) - .executableFile(statusPayload.getExecutableFile()) - .fileDropFile(statusPayload.getFileDropFile()) - .hostname(statusPayload.getHostname()) - .ipSrc(statusPayload.getIpSrc()) - .ipDst(statusPayload.getIpDst()) - .portSrc(statusPayload.getPortSrc()) - .portDst(statusPayload.getPortDst()) - .protocol(statusPayload.getProtocol()) - .name(injectorContract.getPayload().getName()) - .type(injectorContract.getPayload().getType()) - .collectorType(injectorContract.getPayload().getCollectorType()) - .description(injectorContract.getPayload().getDescription()) - .platforms(injectorContract.getPayload().getPlatforms()) - .attackPatterns(toAttackPatternSimples(injectorContract.getAttackPatterns())) - .executableArch(injectorContract.getArch()); - result = statusPayloadOutputBuilder.build(); - - } else { - return null; - } + + if (ofNullable(inject.get().getContent()).map(c -> c.has("obfuscator")).orElse(Boolean.FALSE)) { + String obfuscator = inject.get().getContent().findValue("obfuscator").asText(); + statusPayloadOutputBuilder.obfuscator(obfuscator); + } + + Optional injectStatusOpt = injectObj.getStatus(); + Payload payload = injectorContract.getPayload(); + + // Handle the case when inject has not been executed yet or no payload output exists + if (injectStatusOpt.isEmpty() || injectStatusOpt.get().getPayloadOutput() == null) { + if (payload != null) { + populatePayloadDetails(statusPayloadOutputBuilder, payload, injectorContract); + + // Handle different payload types + processPayloadType(statusPayloadOutputBuilder, payload); + return statusPayloadOutputBuilder.build(); + } else { + return fetchPayloadFromExecutor(statusPayloadOutputBuilder, injectorContract); } } - return result; + + // If inject has been executed, reuse the previous status + return injectStatusOpt + .map(InjectStatus::getPayloadOutput) + .map( + statusPayload -> + populateExecutedPayload( + statusPayloadOutputBuilder, statusPayload, injectorContract)) + .orElse(StatusPayloadOutput.builder().build()); + } + + private void populatePayloadDetails( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, + Payload payload, + InjectorContract injectorContract) { + builder + .arguments(payload.getArguments()) + .prerequisites(payload.getPrerequisites()) + .externalId(payload.getExternalId()) + .cleanupExecutor(payload.getCleanupExecutor()) + .name(payload.getName()) + .type(payload.getType()) + .collectorType(payload.getCollectorType()) + .description(payload.getDescription()) + .platforms(payload.getPlatforms()) + .attackPatterns(toAttackPatternSimples(injectorContract.getAttackPatterns())) + .executableArch(injectorContract.getArch()); + } + + private void processPayloadType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, Payload payload) { + switch (payload.getType()) { + case COMMAND_TYPE: + handleCommandType(builder, (Command) Hibernate.unproxy(payload)); + break; + case EXECUTABLE_TYPE: + handleExecutableType(builder, (Executable) Hibernate.unproxy(payload)); + break; + case FILE_DROP_TYPE: + handleFileDropType(builder, (FileDrop) Hibernate.unproxy(payload)); + break; + case DNS_RESOLUTION_TYPE: + handleDnsResolutionType(builder, (DnsResolution) Hibernate.unproxy(payload)); + break; + case NETWORK_TRAFFIC_TYPE: + handleNetworkTrafficType(builder, (NetworkTraffic) Hibernate.unproxy(payload)); + break; + default: + break; + } + } + + private void handleCommandType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, Command payloadCommand) { + List cleanupCommands = new ArrayList<>(); + if (payloadCommand.getCleanupCommand() != null) { + cleanupCommands.add(payloadCommand.getCleanupCommand()); + } + + PayloadCommandBlock commandBlock = + new PayloadCommandBlock( + payloadCommand.getExecutor(), payloadCommand.getContent(), cleanupCommands); + builder.payloadCommandBlocks(Collections.singletonList(commandBlock)); + } + + private void handleExecutableType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, Executable payloadExecutable) { + builder.executableFile(new StatusPayloadDocument(payloadExecutable.getExecutableFile())); + } + + private void handleFileDropType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, FileDrop payloadFileDrop) { + builder.fileDropFile(new StatusPayloadDocument(payloadFileDrop.getFileDropFile())); + } + + private void handleDnsResolutionType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, DnsResolution payloadDnsResolution) { + builder.hostname(payloadDnsResolution.getHostname()); + } + + private void handleNetworkTrafficType( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, + NetworkTraffic payloadNetworkTraffic) { + builder + .protocol(payloadNetworkTraffic.getProtocol()) + .portSrc(payloadNetworkTraffic.getPortSrc()) + .portDst(payloadNetworkTraffic.getPortDst()) + .ipSrc(payloadNetworkTraffic.getIpSrc()) + .ipDst(payloadNetworkTraffic.getIpDst()); + } + + private StatusPayloadOutput fetchPayloadFromExecutor( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, InjectorContract injectorContract) { + try { + // Inject comes from Caldera ability and tomorrow from other(s) Executor(s) + io.openbas.executors.Injector executor = + context.getBean( + injectorContract.getInjector().getType(), io.openbas.executors.Injector.class); + StatusPayload statusPayload = executor.getPayloadOutput(injectorContract.getId()); + return builder + .externalId(statusPayload.getExternalId()) + .name(statusPayload.getName()) + .type(statusPayload.getType()) + .description(statusPayload.getDescription()) + .platforms(injectorContract.getPlatforms()) + .attackPatterns(toAttackPatternSimples(injectorContract.getAttackPatterns())) + .executableArch(injectorContract.getArch()) + .payloadCommandBlocks(statusPayload.getPayloadCommandBlocks()) + .build(); + } catch (NoSuchBeanDefinitionException e) { + log.info("No executor found for this injector: " + injectorContract.getInjector().getType()); + return StatusPayloadOutput.builder().build(); + } + } + + private StatusPayloadOutput populateExecutedPayload( + StatusPayloadOutput.StatusPayloadOutputBuilder builder, + StatusPayload statusPayload, + InjectorContract injectorContract) { + builder + .cleanupExecutor(statusPayload.getCleanupExecutor()) + .payloadCommandBlocks(statusPayload.getPayloadCommandBlocks()) + .arguments(statusPayload.getArguments()) + .prerequisites(statusPayload.getPrerequisites()) + .externalId(statusPayload.getExternalId()) + .executableFile(statusPayload.getExecutableFile()) + .fileDropFile(statusPayload.getFileDropFile()) + .hostname(statusPayload.getHostname()) + .ipSrc(statusPayload.getIpSrc()) + .ipDst(statusPayload.getIpDst()) + .portSrc(statusPayload.getPortSrc()) + .portDst(statusPayload.getPortDst()) + .protocol(statusPayload.getProtocol()) + .attackPatterns(toAttackPatternSimples(injectorContract.getAttackPatterns())) + .executableArch(injectorContract.getArch()) + .name(statusPayload.getName()) + .type(statusPayload.getType()) + .description(statusPayload.getDescription()) + .platforms(injectorContract.getPlatforms()); + + Payload payload = injectorContract.getPayload(); + if (payload != null) { + builder.collectorType(payload.getCollectorType()); + } + + return builder.build(); } public List toAttackPatternSimples(List attackPatterns) { diff --git a/openbas-api/src/test/java/io/openbas/injects/manual/ManualExecutorTest.java b/openbas-api/src/test/java/io/openbas/injects/manual/ManualExecutorTest.java index a486a40f59..92c8ae6144 100644 --- a/openbas-api/src/test/java/io/openbas/injects/manual/ManualExecutorTest.java +++ b/openbas-api/src/test/java/io/openbas/injects/manual/ManualExecutorTest.java @@ -1,25 +1,70 @@ package io.openbas.injects.manual; +import static org.mockito.Mockito.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.openbas.database.model.Execution; +import io.openbas.database.model.Inject; +import io.openbas.database.model.InjectExpectation; +import io.openbas.database.model.Injection; +import io.openbas.execution.ExecutableInject; import io.openbas.injectors.manual.ManualExecutor; -import org.junit.jupiter.api.Assertions; +import io.openbas.injectors.manual.model.ManualContent; +import io.openbas.model.expectation.ManualExpectation; +import io.openbas.model.inject.form.Expectation; +import io.openbas.service.InjectExpectationService; +import java.time.Instant; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; +import org.mockito.InjectMocks; +import org.mockito.Mock; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.util.ReflectionTestUtils; @SpringBootTest public class ManualExecutorTest { - @Autowired private ManualExecutor manualExecutor; + @Mock InjectExpectationService injectExpectationService; + + @Mock ObjectMapper mapper; + + @InjectMocks private ManualExecutor manualExecutor; + + @BeforeEach + void setUp() { + ReflectionTestUtils.setField(manualExecutor, "mapper", mapper); + } @Test - void process() { - UnsupportedOperationException error = null; - try { - this.manualExecutor.process(null, null); - } catch (UnsupportedOperationException e) { - error = e; - } - Assertions.assertNotNull(error); - Assertions.assertEquals("Manual inject cannot be executed", error.getMessage()); + void process() throws Exception { + + // mock input + Expectation expectation = new Expectation(); + expectation.setExpectationGroup(false); + expectation.setName("Expectation 1"); + expectation.setDescription("Expectation 1"); + expectation.setType(InjectExpectation.EXPECTATION_TYPE.MANUAL); + expectation.setScore(80D); + expectation.setExpirationTime(Instant.now().toEpochMilli()); + ManualContent manualContent = new ManualContent(); + manualContent.setExpectations(List.of(expectation)); + Execution execution = mock(Execution.class); + ExecutableInject executableInject = mock(ExecutableInject.class); + Injection injection = mock(Injection.class); + Inject inject = mock(Inject.class); + ObjectNode content = mock(ObjectNode.class); + when(inject.getContent()).thenReturn(content); + when(injection.getInject()).thenReturn(inject); + when(executableInject.getInjection()).thenReturn(injection); + when(mapper.treeToValue(content, ManualContent.class)).thenReturn(manualContent); + + this.manualExecutor.process(execution, executableInject); + + // verify that the expectations are saved + verify(injectExpectationService) + .buildAndSaveInjectExpectations( + executableInject, List.of(new ManualExpectation(expectation))); } } diff --git a/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java b/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java index 178b5f7775..2279630660 100644 --- a/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/InjectApiTest.java @@ -11,7 +11,6 @@ import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -21,34 +20,31 @@ import com.jayway.jsonpath.JsonPath; import io.openbas.IntegrationTest; import io.openbas.database.model.*; -import io.openbas.database.model.InjectorContract; import io.openbas.database.repository.*; import io.openbas.execution.ExecutableInject; import io.openbas.executors.Executor; import io.openbas.rest.exercise.service.ExerciseService; -import io.openbas.rest.inject.form.DirectInjectInput; -import io.openbas.rest.inject.form.InjectBulkProcessingInput; -import io.openbas.rest.inject.form.InjectInput; +import io.openbas.rest.inject.form.*; +import io.openbas.rest.inject.service.InjectStatusService; import io.openbas.service.ScenarioService; -import io.openbas.utils.fixtures.InjectExpectationFixture; -import io.openbas.utils.fixtures.InjectFixture; -import io.openbas.utils.fixtures.InjectorContractFixture; -import io.openbas.utils.fixtures.PayloadFixture; +import io.openbas.utils.fixtures.*; +import io.openbas.utils.fixtures.composers.AgentComposer; +import io.openbas.utils.fixtures.composers.EndpointComposer; +import io.openbas.utils.fixtures.composers.InjectComposer; +import io.openbas.utils.fixtures.composers.InjectStatusComposer; +import io.openbas.utils.mockUser.WithMockAdminUser; import io.openbas.utils.mockUser.WithMockObserverUser; import io.openbas.utils.mockUser.WithMockPlannerUser; import jakarta.annotation.Resource; import jakarta.mail.Session; import jakarta.mail.internet.MimeMessage; -import jakarta.servlet.ServletException; +import jakarta.transaction.Transactional; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -81,6 +77,12 @@ class InjectApiTest extends IntegrationTest { @Autowired private MockMvc mvc; @Autowired private ScenarioService scenarioService; @Autowired private ExerciseService exerciseService; + @SpyBean private InjectStatusService injectStatusService; + + @Autowired private AgentComposer agentComposer; + @Autowired private EndpointComposer endpointComposer; + @Autowired private InjectComposer injectComposer; + @Autowired private InjectStatusComposer injectStatusComposer; @Autowired private ExerciseRepository exerciseRepository; @SpyBean private Executor executor; @@ -507,18 +509,17 @@ void executeEmailInjectForExerciseWithNoContentTest() throws Exception { new MockMultipartFile( "input", null, "application/json", objectMapper.writeValueAsString(input).getBytes()); - // -- ASSERT - Exception exception = - assertThrows( - ServletException.class, - () -> - mvc.perform( - multipart(EXERCISE_URI + "/" + EXERCISE.getId() + "/inject").file(inputJson))); - - String expectedMessage = "Inject is empty"; - String actualMessage = exception.getMessage(); + // -- EXECUTION -- + String response = + mvc.perform(multipart(EXERCISE_URI + "/" + EXERCISE.getId() + "/inject").file(inputJson)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); - assertTrue(actualMessage.contains(expectedMessage)); + // -- ASSERT -- + assertNotNull(response); + assertTrue(JsonPath.read(response, "$.status_traces").toString().contains("Inject is empty")); } // -- BULK DELETE -- @@ -636,9 +637,10 @@ void deleteInjectsForExerciseTest() throws Exception { } @Nested - @WithMockPlannerUser + @WithMockAdminUser @DisplayName("Retrieving executable payloads injects") class RetrievingExecutablePayloadInject { + @DisplayName("Get encoded command payload with arguments") @Test void getExecutablePayloadInjectWithArguments() throws Exception { @@ -663,11 +665,14 @@ void getExecutablePayloadInjectWithArguments() throws Exception { InjectFixture.createInjectCommandPayload(PAYLOAD_INJECTOR_CONTRACT, payloadArguments); Inject injectSaved = injectRepository.save(inject); + doNothing() + .when(injectStatusService) + .addStartImplantExecutionTraceByInject(any(), any(), any()); // -- EXECUTE -- String response = mvc.perform( - get(INJECT_URI + "/" + injectSaved.getId() + "/executable-payload") + get(INJECT_URI + "/" + injectSaved.getId() + "/fakeId/executable-payload") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().is2xxSuccessful()) .andReturn() @@ -714,11 +719,14 @@ void getExecutableObfuscatePayloadInject() throws Exception { InjectFixture.createInjectCommandPayload(PAYLOAD_INJECTOR_CONTRACT_2, payloadArguments); Inject injectSaved = injectRepository.save(inject); + doNothing() + .when(injectStatusService) + .addStartImplantExecutionTraceByInject(any(), any(), any()); // -- EXECUTE -- String response = mvc.perform( - get(INJECT_URI + "/" + injectSaved.getId() + "/executable-payload") + get(INJECT_URI + "/" + injectSaved.getId() + "/fakeagentID/executable-payload") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().is2xxSuccessful()) .andReturn() @@ -737,4 +745,210 @@ void getExecutableObfuscatePayloadInject() throws Exception { assertEquals(expectedCmdEncoded, JsonPath.read(response, "$.command_content")); } } + + @Nested + @Transactional + @WithMockAdminUser + @DisplayName("Inject Execution Callback Handling (simulating a request from an implant)") + class handleInjectExecutionCallback { + + private Inject getPendingInjectWithAssets() { + return injectComposer + .forInject(InjectFixture.getDefaultInject()) + .withEndpoint( + endpointComposer + .forEndpoint(EndpointFixture.createEndpoint()) + .withAgent(agentComposer.forAgent(AgentFixture.createDefaultAgent()))) + .withEndpoint( + endpointComposer + .forEndpoint(EndpointFixture.createEndpoint()) + .withAgent(agentComposer.forAgent(AgentFixture.createDefaultAgent()))) + .withInjectStatus( + injectStatusComposer.forInjectStatus(InjectStatusFixture.createDefaultInjectStatus())) + .persist() + .get(); + } + + private void performCallbackRequest(String agentId, String injectId, InjectExecutionInput input) + throws Exception { + mvc.perform( + post(INJECT_URI + "/execution/" + agentId + "/callback/" + injectId) + .content(asJsonString(input)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getResponse() + .getContentAsString(); + } + + @Nested + @DisplayName("Action Handling:") + class ActionHandlingTest { + @DisplayName("Should add trace when process is not finished") + @Test + void shouldAddTraceWhenProcessNotFinished() throws Exception { + // -- PREPARE -- + InjectExecutionInput input = new InjectExecutionInput(); + String logMessage = "First log received"; + input.setMessage(logMessage); + input.setAction(InjectExecutionAction.command_execution); + input.setStatus("SUCCESS"); + Inject inject = getPendingInjectWithAssets(); + + // -- EXECUTE -- + String agentId = ((Endpoint) inject.getAssets().getFirst()).getAgents().getFirst().getId(); + performCallbackRequest(agentId, inject.getId(), input); + + // -- ASSERT -- + Inject injectSaved = injectRepository.findById(inject.getId()).orElseThrow(); + InjectStatus injectStatusSaved = injectSaved.getStatus().orElseThrow(); + assertEquals(ExecutionStatus.PENDING, injectStatusSaved.getName()); + assertEquals(1, injectStatusSaved.getTraces().size()); + assertEquals( + ExecutionTraceStatus.SUCCESS, injectStatusSaved.getTraces().getFirst().getStatus()); + assertEquals( + ExecutionTraceAction.EXECUTION, injectStatusSaved.getTraces().getFirst().getAction()); + assertEquals(logMessage, injectStatusSaved.getTraces().getFirst().getMessage()); + } + + @DisplayName( + "Should add trace and compute agent status when one of two agents finishes execution") + @Test + void shouldAddTraceAndComputeAgentStatusWhenOneAgentFinishes() throws Exception { + // -- PREPARE -- + InjectExecutionInput input = new InjectExecutionInput(); + input.setMessage("First log received"); + input.setAction(InjectExecutionAction.command_execution); + input.setStatus("COMMAND_NOT_FOUND"); + Inject inject = getPendingInjectWithAssets(); + + // -- EXECUTE -- + String agentId = ((Endpoint) inject.getAssets().getFirst()).getAgents().getFirst().getId(); + performCallbackRequest(agentId, inject.getId(), input); + + InjectExecutionInput input2 = new InjectExecutionInput(); + String lastLogMessage = "Complete log received"; + input2.setMessage(lastLogMessage); + input2.setAction(InjectExecutionAction.complete); + input2.setStatus("INFO"); + performCallbackRequest(agentId, inject.getId(), input2); + + // -- ASSERT -- + Inject injectSaved = injectRepository.findById(inject.getId()).orElseThrow(); + InjectStatus injectStatusSaved = injectSaved.getStatus().orElseThrow(); + // Check inject status + assertEquals(ExecutionStatus.PENDING, injectStatusSaved.getName()); + assertEquals(2, injectStatusSaved.getTraces().size()); + // The status of the complete trace should be ERROR + List completeTraces = + injectStatusSaved.getTraces().stream() + .filter(t -> ExecutionTraceAction.COMPLETE.equals(t.getAction())) + .toList(); + assertEquals(1, completeTraces.size()); + assertEquals( + ExecutionTraceStatus.ERROR, completeTraces.stream().findFirst().get().getStatus()); + } + + @DisplayName( + "Should add trace, compute agent status, and update inject status when all agents finish execution") + @Test + void shouldAddTraceComputeAgentStatusAndUpdateInjectStatusWhenAllAgentsFinish() + throws Exception { + // -- PREPARE -- + InjectExecutionInput input = new InjectExecutionInput(); + input.setMessage("First log received"); + input.setAction(InjectExecutionAction.command_execution); + input.setStatus("COMMAND_NOT_FOUND"); + Inject inject = getPendingInjectWithAssets(); + + // -- EXECUTE -- + String firstAgentId = + ((Endpoint) inject.getAssets().getFirst()).getAgents().getFirst().getId(); + String secondAgentId = + ((Endpoint) inject.getAssets().getFirst()).getAgents().getLast().getId(); + performCallbackRequest(firstAgentId, inject.getId(), input); + input.setStatus("SUCCESS"); + performCallbackRequest(secondAgentId, inject.getId(), input); + + InjectExecutionInput input2 = new InjectExecutionInput(); + String lastLogMessage = "Complete log received"; + input2.setMessage(lastLogMessage); + input2.setAction(InjectExecutionAction.complete); + input2.setStatus("INFO"); + performCallbackRequest(firstAgentId, inject.getId(), input2); + performCallbackRequest(secondAgentId, inject.getId(), input2); + + // -- ASSERT -- + Inject injectSaved = injectRepository.findById(inject.getId()).orElseThrow(); + InjectStatus injectStatusSaved = injectSaved.getStatus().orElseThrow(); + // Check inject status + assertEquals(ExecutionStatus.PARTIAL, injectStatusSaved.getName()); + } + } + + @Nested + @DisplayName("Agent Status Computation") + class AgentStatusComputationTest { + + private void testAgentStatusFunction( + String inputTraceStatus1, + String inputTraceStatus2, + ExecutionTraceStatus expectedAgentStatus) + throws Exception { + // -- PREPARE -- + InjectExecutionInput input = new InjectExecutionInput(); + input.setMessage("First log received"); + input.setAction(InjectExecutionAction.command_execution); + input.setStatus(inputTraceStatus1); + Inject inject = getPendingInjectWithAssets(); + + // -- EXECUTE -- + String firstAgentId = + ((Endpoint) inject.getAssets().getFirst()).getAgents().getFirst().getId(); + performCallbackRequest(firstAgentId, inject.getId(), input); + input.setStatus(inputTraceStatus2); + performCallbackRequest(firstAgentId, inject.getId(), input); + // send complete trace + input.setAction(InjectExecutionAction.complete); + input.setStatus("INFO"); + performCallbackRequest(firstAgentId, inject.getId(), input); + + // -- ASSERT -- + Inject injectSaved = injectRepository.findById(inject.getId()).orElseThrow(); + InjectStatus injectStatusSaved = injectSaved.getStatus().orElseThrow(); + List completeTraces = + injectStatusSaved.getTraces().stream() + .filter(t -> ExecutionTraceAction.COMPLETE.equals(t.getAction())) + .toList(); + assertEquals(1, completeTraces.size()); + assertEquals(expectedAgentStatus, completeTraces.stream().findFirst().get().getStatus()); + } + + @Test + @DisplayName("Should compute agent status as ERROR") + void shouldComputeAgentStatusAsError() throws Exception { + testAgentStatusFunction("COMMAND_NOT_FOUND", "ERROR", ExecutionTraceStatus.ERROR); + } + + @Test + @DisplayName("Should compute agent status as SUCCESS") + void shouldComputeAgentStatusAsSuccess() throws Exception { + testAgentStatusFunction("SUCCESS", "WARNING", ExecutionTraceStatus.SUCCESS); + } + + @Test + @DisplayName("Should compute agent status as PARTIAL") + void shouldComputeAgentStatusAsPartial() throws Exception { + testAgentStatusFunction("SUCCESS", "COMMAND_NOT_FOUND", ExecutionTraceStatus.PARTIAL); + } + + @Test + @DisplayName("Should compute agent status as MAYBE_PREVENTED") + void shouldComputeAgentStatusAsMayBePrevented() throws Exception { + testAgentStatusFunction( + "COMMAND_CANNOT_BE_EXECUTED", "MAYBE_PREVENTED", ExecutionTraceStatus.MAYBE_PREVENTED); + } + } + } } diff --git a/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java b/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java index bfdfe072ef..104dc2e6b8 100644 --- a/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java +++ b/openbas-api/src/test/java/io/openbas/rest/inject/service/InjectServiceTest.java @@ -608,7 +608,7 @@ void given_valid_input_initializeInjectStatus_SHOULD_save_the_injectstatus() { when(injectUtils.getStatusPayloadFromInject(inject)).thenReturn(statusPayload); when(injectRepository.findById(injectId)).thenReturn(Optional.of(inject)); - injectStatusService.initializeInjectStatus(injectId, executionStatus, null); + injectStatusService.initializeInjectStatus(injectId, executionStatus); ArgumentCaptor statusCaptor = ArgumentCaptor.forClass(InjectStatus.class); verify(injectStatusRepository).save(statusCaptor.capture()); diff --git a/openbas-api/src/test/java/io/openbas/service/InjectImportServiceTest.java b/openbas-api/src/test/java/io/openbas/service/InjectImportServiceTest.java new file mode 100644 index 0000000000..49903a899f --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/service/InjectImportServiceTest.java @@ -0,0 +1,302 @@ +package io.openbas.service; + +import static org.junit.jupiter.api.Assertions.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.openbas.database.model.RuleAttribute; +import io.openbas.service.utils.InjectImportUtils; +import io.openbas.utils.mockMapper.MockMapperUtils; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.temporal.Temporal; +import java.util.Date; +import java.util.Map; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.jupiter.api.*; + +public class InjectImportServiceTest { + private Row row; + private Cell cell; + private ObjectNode json; + private Workbook workbook; + + @BeforeEach + void before() throws Exception { + workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet(); + row = sheet.createRow(0); + cell = row.createCell(0); + + json = + new ObjectMapper() + .readValue( + """ + { + "key":"Test", + "richText":true + } + """, + ObjectNode.class); + } + + @AfterEach + void after() throws Exception { + workbook.close(); + } + + // -- INJECT IMPORT -- + + @DisplayName("Test get a date cell as string") + @Test + void testGetDateAsString() throws Exception { + // -- PREPARE -- + Date date = Date.from(LocalDateTime.of(2025, 1, 1, 12, 0).toInstant(ZoneOffset.UTC)); + cell.setCellValue(date); + // -- EXECUTE -- + String result = InjectImportUtils.getDateAsStringFromCell(row, "A", null); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(date.toString(), result); + } + + @DisplayName("Test get a date cell as string with a specific time pattern") + @Test + void testGetDateAsStringWithTimePattern() throws Exception { + // -- PREPARE -- + Date date = Date.from(LocalDateTime.of(2025, 1, 2, 12, 0).toInstant(ZoneOffset.UTC)); + cell.setCellValue(date); + // -- EXECUTE -- + String result = InjectImportUtils.getDateAsStringFromCell(row, "A", "DD/MM/YY HH:mm:ss"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(new SimpleDateFormat("dd/MM/yy HH:mm:ss").format(date), result); + } + + @DisplayName("Test get a date cell as string when no column specified") + @Test + void testGetDateAsStringWhenNoColumn() throws Exception { + // -- PREPARE -- + cell.setCellValue(Date.from(LocalDateTime.of(2025, 1, 1, 12, 0).toInstant(ZoneOffset.UTC))); + // -- EXECUTE -- + String result = InjectImportUtils.getDateAsStringFromCell(row, "", null); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("", result); + } + + @DisplayName("Test get a date cell as string when it's already plain text") + @Test + void testGetDateAsStringWhenAlreadyString() throws Exception { + // -- PREPARE -- + cell.setCellValue("J+1"); + // -- EXECUTE -- + String result = InjectImportUtils.getDateAsStringFromCell(row, "A", null); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("J+1", result); + } + + @DisplayName("Test get a string cell as string") + @Test + void testGetCellValueAsString() throws Exception { + // -- PREPARE -- + cell.setCellValue("A value"); + // -- EXECUTE -- + String result = InjectImportUtils.getValueAsString(row, "A"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("A value", result); + } + + @DisplayName("Test get a string cell as string when no column specified") + @Test + void testGetCellValueAsStringWhenNoColumn() throws Exception { + // -- PREPARE -- + cell.setCellValue("A value"); + // -- EXECUTE -- + String result = InjectImportUtils.getValueAsString(row, ""); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("", result); + } + + @DisplayName("Test get a numeric cell as string") + @Test + void testGetCellValueAsStringWhenAlreadyString() throws Exception { + // -- PREPARE -- + cell.setCellValue(10.0); + // -- EXECUTE -- + String result = InjectImportUtils.getValueAsString(row, "A"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("10.0", result); + } + + @DisplayName("Test get a double cell as string") + @Test + void testGetCellDoubleAsString() throws Exception { + // -- PREPARE -- + cell.setCellValue("10.0"); + // -- EXECUTE -- + Double result = InjectImportUtils.getValueAsDouble(row, "A"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(10.0, result); + } + + @DisplayName("Test get a double cell as string when no column specified") + @Test + void testGetCellDoubleAsStringWhenNoColumn() throws Exception { + // -- PREPARE -- + cell.setCellValue("A value"); + // -- EXECUTE -- + Double result = InjectImportUtils.getValueAsDouble(row, ""); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(0.0, result); + } + + @DisplayName("Test get a double cell when it's already a double") + @Test + void testGetCellDoubleAsStringWhenAlreadyString() throws Exception { + // -- PREPARE -- + cell.setCellValue(10.0); + // -- EXECUTE -- + Double result = InjectImportUtils.getValueAsDouble(row, "A"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(10.0, result); + } + + @DisplayName("Test get a string cell and convert it to HTML") + @Test + void testExtractAndConvertCellAsHTML() throws Exception { + // -- PREPARE -- + cell.setCellValue("Test\nTest"); + RuleAttribute ruleAttribute = MockMapperUtils.createRuleAttribute(); + ruleAttribute.setColumns("A"); + // -- EXECUTE -- + String result = + InjectImportUtils.extractAndConvertStringColumnValue( + row, ruleAttribute, Map.of("Test", json)); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("Test
Test", result); + } + + @DisplayName("Test get a string cell and keep it as plain text") + @Test + void testExtractWithoutConvertingCellAsHTML() throws Exception { + // -- PREPARE -- + cell.setCellValue("Test\nTest"); + RuleAttribute ruleAttribute = MockMapperUtils.createRuleAttribute(); + ruleAttribute.setColumns("A"); + json.put("richText", false); + // -- EXECUTE -- + String result = + InjectImportUtils.extractAndConvertStringColumnValue( + row, ruleAttribute, Map.of("Test", json)); + + // -- ASSERT -- + assertNotNull(result); + assertEquals("Test\nTest", result); + } + + @DisplayName("Test get inject date without pattern but with an ISO_DATE_TIME format") + @Test + void testGetInjectDateWithoutPattern() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate(LocalDateTime.of(2025, 1, 1, 12, 0, 0).toString()); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, null); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(LocalDateTime.of(2025, 1, 1, 12, 0, 0), result); + } + + @DisplayName("Test get inject time without pattern but with an ISO_TIME format") + @Test + void testGetInjectTimeWithoutPattern() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate(LocalTime.of(12, 0, 0).format(DateTimeFormatter.ISO_TIME)); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, null); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(LocalTime.of(12, 0, 0), result); + } + + @DisplayName("Test get inject time without pattern and in an unknown format") + @Test + void testGetInjectTimeUndetected() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate("13 heures et demi"); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, null); + + // -- ASSERT -- + assertNull(result); + } + + @DisplayName("Test get inject date and time with a specified pattern") + @Test + void testGetInjectDateTimeWithPattern() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate("25/01/20 13h05:52"); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, "yy/MM/dd HH'h'mm:ss"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(LocalDateTime.of(2025, 1, 20, 13, 5, 52), result); + } + + @DisplayName("Test get inject time with a specified pattern") + @Test + void testGetInjectTimeWithPattern() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate("13h05:52"); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, "HH'h'mm:ss"); + + // -- ASSERT -- + assertNotNull(result); + assertEquals(LocalTime.of(13, 5, 52), result); + } + + @DisplayName("Test get inject time with a specified pattern that does not match") + @Test + void testGetInjectTimeUndetectedWithTimePattern() throws Exception { + // -- PREPARE -- + InjectTime injectTime = new InjectTime(); + injectTime.setUnformattedDate("13 heures et demi"); + // -- EXECUTE -- + Temporal result = InjectImportUtils.getInjectDate(injectTime, "HH'h'mm:ss"); + + // -- ASSERT -- + assertNull(result); + } +} diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/AgentFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/AgentFixture.java index 8083207ab0..2f6e5505db 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/AgentFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/AgentFixture.java @@ -6,13 +6,18 @@ public class AgentFixture { - public static Agent createAgent(Asset asset, String externalReference) { + public static Agent createDefaultAgent() { Agent agent = new Agent(); agent.setExecutedByUser(Agent.ADMIN_SYSTEM_WINDOWS); agent.setPrivilege(Agent.PRIVILEGE.admin); agent.setDeploymentMode(Agent.DEPLOYMENT_MODE.service); - agent.setAsset(asset); agent.setLastSeen(Instant.now()); + return agent; + } + + public static Agent createAgent(Asset asset, String externalReference) { + Agent agent = createDefaultAgent(); + agent.setAsset(asset); agent.setExternalReference(externalReference); return agent; } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/InjectStatusFixture.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/InjectStatusFixture.java index 977bf186bd..d853e9fd13 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/InjectStatusFixture.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/InjectStatusFixture.java @@ -1,5 +1,7 @@ package io.openbas.utils.fixtures; +import static io.openbas.database.model.Command.COMMAND_TYPE; + import io.openbas.database.model.ExecutionStatus; import io.openbas.database.model.InjectStatus; import io.openbas.database.model.PayloadCommandBlock; @@ -12,9 +14,12 @@ public class InjectStatusFixture { public static InjectStatus createDefaultInjectStatus() { InjectStatus injectStatus = new InjectStatus(); injectStatus.setTrackingSentDate(Instant.now()); - injectStatus.setName(ExecutionStatus.SUCCESS); + injectStatus.setName(ExecutionStatus.PENDING); injectStatus.setPayloadOutput( new StatusPayload( + null, + null, + COMMAND_TYPE, null, null, null, diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/AgentComposer.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/AgentComposer.java new file mode 100644 index 0000000000..70e783ccad --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/AgentComposer.java @@ -0,0 +1,41 @@ +package io.openbas.utils.fixtures.composers; + +import io.openbas.database.model.Agent; +import io.openbas.database.repository.AgentRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AgentComposer extends ComposerBase { + @Autowired private AgentRepository agentRepository; + + public class Composer extends InnerComposerBase { + private final Agent agent; + + public Composer(Agent agent) { + this.agent = agent; + } + + @Override + public AgentComposer.Composer persist() { + agentRepository.save(agent); + return this; + } + + @Override + public AgentComposer.Composer delete() { + agentRepository.delete(agent); + return this; + } + + @Override + public Agent get() { + return this.agent; + } + } + + public AgentComposer.Composer forAgent(Agent agent) { + generatedItems.add(agent); + return new AgentComposer.Composer(agent); + } +} diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/EndpointComposer.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/EndpointComposer.java new file mode 100644 index 0000000000..f91c68d81b --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/EndpointComposer.java @@ -0,0 +1,55 @@ +package io.openbas.utils.fixtures.composers; + +import io.openbas.database.model.Agent; +import io.openbas.database.model.Endpoint; +import io.openbas.database.repository.EndpointRepository; +import java.util.ArrayList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class EndpointComposer extends ComposerBase { + @Autowired private EndpointRepository endpointRepository; + + public class Composer extends InnerComposerBase { + private final Endpoint endpoint; + private final List agentComposers = new ArrayList<>(); + + public Composer(Endpoint endpoint) { + this.endpoint = endpoint; + } + + public Composer withAgent(AgentComposer.Composer agentComposer) { + agentComposers.add(agentComposer); + List agents = endpoint.getAgents(); + Agent newAgent = agentComposer.get(); + newAgent.setAsset(this.endpoint); + agents.add(newAgent); + this.endpoint.setAgents(agents); + return this; + } + + @Override + public Composer persist() { + endpointRepository.save(endpoint); + return this; + } + + @Override + public Composer delete() { + endpointRepository.delete(endpoint); + return this; + } + + @Override + public Endpoint get() { + return this.endpoint; + } + } + + public EndpointComposer.Composer forEndpoint(Endpoint endpoint) { + generatedItems.add(endpoint); + return new EndpointComposer.Composer(endpoint); + } +} diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectComposer.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectComposer.java index efd0d8e961..d5a7baf6de 100644 --- a/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectComposer.java +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectComposer.java @@ -1,15 +1,14 @@ package io.openbas.utils.fixtures.composers; import com.fasterxml.jackson.databind.ObjectMapper; -import io.openbas.database.model.Inject; -import io.openbas.database.model.InjectorContract; -import io.openbas.database.model.Tag; +import io.openbas.database.model.*; import io.openbas.database.repository.InjectRepository; import io.openbas.database.repository.InjectorContractRepository; import io.openbas.injectors.challenge.ChallengeContract; import io.openbas.injectors.challenge.model.ChallengeContent; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -25,6 +24,8 @@ public class Composer extends InnerComposerBase { private final Inject inject; private final List challengeComposers = new ArrayList<>(); private final List tagComposers = new ArrayList<>(); + private final List endpointComposers = new ArrayList<>(); + private Optional injectStatusComposers = Optional.empty(); public Composer(Inject inject) { this.inject = inject; @@ -52,8 +53,25 @@ public Composer withId(String id) { return this; } + public Composer withInjectStatus(InjectStatusComposer.Composer injectStatus) { + injectStatusComposers = Optional.of(injectStatus); + injectStatus.get().setInject(this.inject); + this.inject.setStatus(injectStatus.get()); + return this; + } + + public Composer withEndpoint(EndpointComposer.Composer endpointComposer) { + endpointComposers.add(endpointComposer); + List assets = inject.getAssets(); + assets.add(endpointComposer.get()); + this.inject.setAssets(assets); + return this; + } + @Override public Composer persist() { + endpointComposers.forEach(EndpointComposer.Composer::persist); + injectStatusComposers.ifPresent(InjectStatusComposer.Composer::persist); tagComposers.forEach(TagComposer.Composer::persist); challengeComposers.forEach(ChallengeComposer.Composer::persist); // replace the inject content if applicable, after persisting the challenges @@ -70,6 +88,8 @@ public Composer delete() { injectRepository.delete(inject); challengeComposers.forEach(ChallengeComposer.Composer::delete); tagComposers.forEach(TagComposer.Composer::delete); + endpointComposers.forEach(EndpointComposer.Composer::delete); + injectStatusComposers.ifPresent(InjectStatusComposer.Composer::delete); return this; } diff --git a/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectStatusComposer.java b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectStatusComposer.java new file mode 100644 index 0000000000..9d9bc780fe --- /dev/null +++ b/openbas-api/src/test/java/io/openbas/utils/fixtures/composers/InjectStatusComposer.java @@ -0,0 +1,41 @@ +package io.openbas.utils.fixtures.composers; + +import io.openbas.database.model.InjectStatus; +import io.openbas.database.repository.InjectStatusRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class InjectStatusComposer extends ComposerBase { + @Autowired private InjectStatusRepository injectStatusRepository; + + public class Composer extends InnerComposerBase { + private final InjectStatus injectStatus; + + public Composer(InjectStatus injectStatus) { + this.injectStatus = injectStatus; + } + + @Override + public InjectStatusComposer.Composer persist() { + injectStatusRepository.save(injectStatus); + return this; + } + + @Override + public InjectStatusComposer.Composer delete() { + injectStatusRepository.delete(injectStatus); + return this; + } + + @Override + public InjectStatus get() { + return this.injectStatus; + } + } + + public InjectStatusComposer.Composer forInjectStatus(InjectStatus injectStatus) { + generatedItems.add(injectStatus); + return new InjectStatusComposer.Composer(injectStatus); + } +} diff --git a/openbas-api/src/test/java/io/openbas/utils/mockMapper/MockMapperUtils.java b/openbas-api/src/test/java/io/openbas/utils/mockMapper/MockMapperUtils.java index f4e214772a..be5f9b7490 100644 --- a/openbas-api/src/test/java/io/openbas/utils/mockMapper/MockMapperUtils.java +++ b/openbas-api/src/test/java/io/openbas/utils/mockMapper/MockMapperUtils.java @@ -24,7 +24,7 @@ public static ImportMapper createImportMapper() { return importMapper; } - private static InjectImporter createInjectImporter() { + public static InjectImporter createInjectImporter() { InjectImporter injectImporter = new InjectImporter(); injectImporter.setId(UUID.randomUUID().toString()); injectImporter.setImportTypeValue("Test"); @@ -37,7 +37,7 @@ private static InjectImporter createInjectImporter() { return injectImporter; } - private static RuleAttribute createRuleAttribute() { + public static RuleAttribute createRuleAttribute() { RuleAttribute ruleAttribute = new RuleAttribute(); ruleAttribute.setColumns("Test"); ruleAttribute.setName("Test"); diff --git a/openbas-dev/docker-compose.yml b/openbas-dev/docker-compose.yml index c13fe3a4a4..1ce49826d1 100644 --- a/openbas-dev/docker-compose.yml +++ b/openbas-dev/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: openbas-dev-pgsql: container_name: openbas-dev-pgsql - image: postgres:16-alpine + image: postgres:17-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} @@ -12,7 +12,7 @@ services: restart: unless-stopped openbas-test-pgsql: container_name: openbas-test-pgsql - image: postgres:16-alpine + image: postgres:17-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} diff --git a/openbas-framework/pom.xml b/openbas-framework/pom.xml index 123b9baca0..2620d5243e 100644 --- a/openbas-framework/pom.xml +++ b/openbas-framework/pom.xml @@ -6,7 +6,7 @@ io.openbas openbas-platform - 1.11.4 + 1.11.5 openbas-framework @@ -17,12 +17,12 @@ io.openbas openbas-model - 1.11.4 + 1.11.5 com.rabbitmq amqp-client - 5.24.0 + 5.25.0 org.springframework.boot diff --git a/openbas-framework/src/main/java/io/openbas/injector_contract/ContractDef.java b/openbas-framework/src/main/java/io/openbas/injector_contract/ContractDef.java index 77b9eba267..237e139f61 100644 --- a/openbas-framework/src/main/java/io/openbas/injector_contract/ContractDef.java +++ b/openbas-framework/src/main/java/io/openbas/injector_contract/ContractDef.java @@ -43,6 +43,21 @@ public ContractDef optional(ContractElement element) { return this; } + /** + * Add a field that will be mandatory if another field is set + * + * @param element element to be mandatory + * @param conditionalElement if this field is set the element will be mandatory + * @return + */ + public ContractDef mandatoryOnCondition( + ContractElement element, ContractElement conditionalElement) { + element.setMandatoryConditionField(conditionalElement.getKey()); + element.setMandatory(false); + this.fields.add(element); + return this; + } + public List build() { return this.fields; } diff --git a/openbas-framework/src/main/java/io/openbas/injector_contract/fields/ContractElement.java b/openbas-framework/src/main/java/io/openbas/injector_contract/fields/ContractElement.java index 0c997f490c..95c142c903 100644 --- a/openbas-framework/src/main/java/io/openbas/injector_contract/fields/ContractElement.java +++ b/openbas-framework/src/main/java/io/openbas/injector_contract/fields/ContractElement.java @@ -21,6 +21,8 @@ public abstract class ContractElement { private List mandatoryGroups; + private String mandatoryConditionField; + private List linkedFields = new ArrayList<>(); private List linkedValues = new ArrayList<>(); diff --git a/openbas-framework/src/main/java/io/openbas/model/expectation/ManualExpectation.java b/openbas-framework/src/main/java/io/openbas/model/expectation/ManualExpectation.java index 3221a57a56..1f197e7a96 100644 --- a/openbas-framework/src/main/java/io/openbas/model/expectation/ManualExpectation.java +++ b/openbas-framework/src/main/java/io/openbas/model/expectation/ManualExpectation.java @@ -10,11 +10,13 @@ import jakarta.validation.constraints.NotNull; import java.util.Objects; import javax.annotation.Nullable; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @Getter @Setter +@EqualsAndHashCode public class ManualExpectation implements Expectation { private Double score; diff --git a/openbas-front/.yarn/releases/yarn-4.6.0.cjs b/openbas-front/.yarn/releases/yarn-4.6.0.cjs old mode 100755 new mode 100644 diff --git a/openbas-front/package.json b/openbas-front/package.json index 52fdde92b2..150b2aad88 100644 --- a/openbas-front/package.json +++ b/openbas-front/package.json @@ -1,6 +1,6 @@ { "name": "openbas-front", - "version": "1.11.4", + "version": "1.11.5", "private": true, "main": "src/index.tsx", "license": "Apache-2.0", @@ -17,18 +17,16 @@ "@mui/icons-material": "6.4.1", "@mui/lab": "6.0.0-beta.24", "@mui/material": "6.4.1", - "@mui/styles": "6.4.1", "@mui/system": "6.4.1", "@mui/utils": "6.4.1", "@mui/x-date-pickers": "7.24.0", "@redux-devtools/extension": "3.3.0", "@uiw/react-md-editor": "4.0.5", "@xyflow/react": "12.4.2", - "apexcharts": "4.3.0", + "apexcharts": "4.4.0", "axios": "1.7.9", "ckeditor5": "44.1.0", "classcat": "5.0.5", - "classnames": "2.5.1", "cronstrue": "2.54.0", "d3-hierarchy": "3.1.2", "date-fns": "4.1.0", @@ -36,14 +34,14 @@ "elkjs": "0.9.3", "final-form": "4.20.10", "final-form-arrays": "3.1.0", - "html-react-parser": "5.2.0", + "html-react-parser": "5.2.2", "html-to-image": "1.11.11", "http-proxy-middleware": "3.0.3", "js-file-download": "0.4.12", "leaflet": "1.9.4", - "mdi-material-ui": "7.9.2", + "mdi-material-ui": "7.9.3", "moment": "2.30.1", - "moment-timezone": "0.5.45", + "moment-timezone": "0.5.47", "normalizr": "3.6.2", "pdfmake": "0.2.13", "prop-types": "15.8.1", @@ -57,12 +55,12 @@ "react-dropzone": "14.3.5", "react-final-form": "6.5.9", "react-final-form-arrays": "3.1.4", - "react-hook-form": "7.54.1", - "react-intl": "7.1.0", + "react-hook-form": "7.54.2", + "react-intl": "7.1.6", "react-leaflet": "4.2.1", "react-markdown": "9.0.1", "react-redux": "9.2.0", - "react-router": "7.1.1", + "react-router": "7.1.5", "react-syntax-highlighter": "15.6.1", "redux": "5.0.1", "redux-thunk": "3.1.0", @@ -71,14 +69,15 @@ "remark-parse": "11.0.0", "rxjs": "7.8.1", "seamless-immutable": "7.1.4", - "usehooks-ts": "3.1.0", - "uuid": "11.0.3", + "tss-react": "4.9.15", + "usehooks-ts": "3.1.1", + "uuid": "11.0.5", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", "zod": "3.24.1", "zustand": "5.0.1" }, "devDependencies": { - "@eslint/js": "9.19.0", + "@eslint/js": "9.20.0", "@faker-js/faker": "9.4.0", "@playwright/test": "1.50.1", "@stylistic/eslint-plugin": "2.13.0", @@ -98,11 +97,11 @@ "@typescript-eslint/parser": "8.22.0", "@typescript-eslint/utils": "8.22.0", "@vitejs/plugin-react": "4.3.4", - "@vitest/eslint-plugin": "1.1.25", + "@vitest/eslint-plugin": "1.1.27", "chokidar": "4.0.3", "cross-env": "7.0.3", - "esbuild": "0.24.2", - "eslint": "9.19.0", + "esbuild": "0.25.0", + "eslint": "9.20.0", "eslint-import-resolver-oxc": "0.10.1", "eslint-plugin-custom-rules": "link:packages/eslint-plugin-custom-rules", "eslint-plugin-i18next": "6.1.1", @@ -110,20 +109,23 @@ "eslint-plugin-import-newlines": "1.4.0", "eslint-plugin-playwright": "2.2.0", "eslint-plugin-react": "7.37.4", - "eslint-plugin-react-refresh": "0.4.18", + "eslint-plugin-react-refresh": "0.4.19", "eslint-plugin-simple-import-sort": "12.1.1", - "express": "4.21.1", + "express": "4.21.2", "fs-extra": "11.3.0", "globals": "15.14.0", "jsdom": "25.0.1", "monocart-coverage-reports": "2.12.0", - "monocart-reporter": "2.9.11", - "swagger-typescript-api": "13.0.22", - "typescript": "5.7.2", + "monocart-reporter": "2.9.13", + "swagger-typescript-api": "13.0.23", + "typescript": "5.7.3", "typescript-eslint": "8.22.0", - "vite": "6.0.9", + "vite": "6.1.0", "vitest": "2.1.1" }, + "resolutions": { + "@types/react": "18" + }, "engines": { "node": ">= 22.11.0" }, diff --git a/openbas-front/packages/eslint-plugin-custom-rules/lib/rules/classes-rule.js b/openbas-front/packages/eslint-plugin-custom-rules/lib/rules/classes-rule.js index ad2315bf68..83e5f8a7b1 100644 --- a/openbas-front/packages/eslint-plugin-custom-rules/lib/rules/classes-rule.js +++ b/openbas-front/packages/eslint-plugin-custom-rules/lib/rules/classes-rule.js @@ -22,17 +22,6 @@ module.exports = { }); } } - if (node.init && node.init.callee && node.init.callee.name === "useStyles") { - if (node.id.name !== "classes") { - context.report({ - node: node, - message: "useStyles must be declared as classes", - fix(fixer) { - return fixer.replaceText(node.id, "classes") - }, - }); - } - } }, ArrowFunctionExpression(node) { if (node.parent.callee && node.parent.callee.name === "makeStyles") { diff --git a/openbas-front/packages/eslint-plugin-custom-rules/package.json b/openbas-front/packages/eslint-plugin-custom-rules/package.json index 98f77883e0..e855bf51fa 100644 --- a/openbas-front/packages/eslint-plugin-custom-rules/package.json +++ b/openbas-front/packages/eslint-plugin-custom-rules/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-custom-rules", - "version": "0.0.1", + "version": "0.0.2", "description": "Additional custom rules", "main": "lib/index.js", "exports": "./lib/index.js", diff --git a/openbas-front/src/admin/Index.tsx b/openbas-front/src/admin/Index.tsx index 7977801def..669f9c5ee7 100644 --- a/openbas-front/src/admin/Index.tsx +++ b/openbas-front/src/admin/Index.tsx @@ -1,7 +1,9 @@ import { Box } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { lazy, Suspense, useEffect } from 'react'; import { Navigate, Route, Routes, useNavigate } from 'react-router'; +import { CSSObject } from 'tss-react'; +import { makeStyles } from 'tss-react/mui'; import { fetchAttackPatterns } from '../actions/AttackPattern'; import type { LoggedHelper } from '../actions/helper'; @@ -10,7 +12,6 @@ import { fetchTags } from '../actions/Tag'; import { errorWrapper } from '../components/Error'; import Loader from '../components/Loader'; import NotFound from '../components/NotFound'; -import type { Theme } from '../components/Theme'; import SystemBanners from '../public/components/systembanners/SystemBanners'; import { computeBannerSettings } from '../public/components/systembanners/utils'; import { useHelper } from '../store'; @@ -37,13 +38,13 @@ const IndexAgents = lazy(() => import('./components/agents/Agents')); const Payloads = lazy(() => import('./components/payloads/Payloads')); const IndexSettings = lazy(() => import('./components/settings/Index')); -const useStyles = makeStyles(theme => ({ - toolbar: theme.mixins.toolbar, +const useStyles = makeStyles()(theme => ({ + toolbar: theme.mixins.toolbar as CSSObject, })); const Index = () => { - const theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const navigate = useNavigate(); const dispatch = useAppDispatch(); const { logged, settings } = useHelper((helper: LoggedHelper) => { diff --git a/openbas-front/src/admin/components/Dashboard.tsx b/openbas-front/src/admin/components/Dashboard.tsx index cc4e496a81..8ff4f6d6a3 100644 --- a/openbas-front/src/admin/components/Dashboard.tsx +++ b/openbas-front/src/admin/components/Dashboard.tsx @@ -1,8 +1,9 @@ import { ComputerOutlined, HubOutlined, MovieFilterOutlined, PersonOutlined } from '@mui/icons-material'; import { Grid, Paper, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { useEffect, useMemo, useState } from 'react'; import Chart from 'react-apexcharts'; +import { makeStyles } from 'tss-react/mui'; import { fetchStatistics } from '../../actions/Application'; import type { AttackPatternHelper } from '../../actions/attack_patterns/attackpattern-helper'; @@ -12,7 +13,6 @@ import { initSorting, type Page } from '../../components/common/queryable/Page'; import Empty from '../../components/Empty'; import { useFormatter } from '../../components/i18n'; import Loader from '../../components/Loader'; -import type { Theme } from '../../components/Theme'; import { useHelper } from '../../store'; import { AttackPattern, ExerciseSimple, type InjectExpectationResultsByAttackPattern, PlatformStatistic } from '../../utils/api-types'; import { horizontalBarsChartOptions, polarAreaChartOptions, verticalBarsChartOptions } from '../../utils/Charts'; @@ -26,7 +26,7 @@ import ExerciseList from './simulations/ExerciseList'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { height: '100%', minHeight: '100%', @@ -61,8 +61,8 @@ const useStyles = makeStyles(() => ({ const Dashboard = () => { // Standard hooks - const theme: Theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const { t, fld, n } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/admin/components/MiniMap.js b/openbas-front/src/admin/components/MiniMap.js deleted file mode 100644 index 5ae74ebe19..0000000000 --- a/openbas-front/src/admin/components/MiniMap.js +++ /dev/null @@ -1,92 +0,0 @@ -import '../../static/css/leaflet.css'; - -import { withStyles, withTheme } from '@mui/styles'; -import * as PropTypes from 'prop-types'; -import * as R from 'ramda'; -import { GeoJSON, MapContainer, TileLayer } from 'react-leaflet'; -import { connect } from 'react-redux'; - -import { storeHelper } from '../../actions/Schema'; -import Loader from '../../components/Loader'; -import countries from '../../static/geo/countries.json'; - -const styles = () => ({ - paper: { - height: '100%', - minHeight: '100%', - margin: '10px 0 0 0', - padding: 0, - borderRadius: 4, - }, -}); - -const colors = [ - '#fff59d', - '#ffe082', - '#ffb300', - '#ffb74d', - '#fb8c00', - '#d95f00', - '#e64a19', - '#f44336', - '#d32f2f', - '#b71c1c', -]; - -const MiniMap = (props) => { - const { parameters, center, zoom, theme, usersByLocationLevels } = props; - if (R.isEmpty(parameters) || R.isNil(parameters)) { - return ; - } - const getStyle = (feature) => { - if (usersByLocationLevels[feature.properties.ISO3]) { - const country = usersByLocationLevels[feature.properties.ISO3]; - return { - color: country.level ? colors[country.level] : colors[5], - weight: 1, - fillOpacity: props.theme.palette.mode === 'light' ? 0.5 : 0.1, - }; - } - return { fillOpacity: 0, color: 'none' }; - }; - return ( -
- - - - -
- ); -}; - -MiniMap.propTypes = { - center: PropTypes.array, - zoom: PropTypes.number, - classes: PropTypes.object, - history: PropTypes.object, -}; - -const select = (state) => { - const helper = storeHelper(state); - const parameters = helper.getPlatformSettings() ?? {}; - return { parameters }; -}; - -export default R.compose( - connect(select, null), - withTheme, - withStyles(styles), -)(MiniMap); diff --git a/openbas-front/src/admin/components/agents/Agents.tsx b/openbas-front/src/admin/components/agents/Agents.tsx index 95c47e0ba8..b0f9a91181 100644 --- a/openbas-front/src/admin/components/agents/Agents.tsx +++ b/openbas-front/src/admin/components/agents/Agents.tsx @@ -1,10 +1,11 @@ import { ContentCopyOutlined, DownloadingOutlined, TerminalOutlined } from '@mui/icons-material'; import { Alert, Button, Card, CardActionArea, CardContent, Dialog, DialogContent, DialogTitle, FormControl, Grid, InputLabel, MenuItem, Select, Tab, Tabs, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Bash, DownloadCircleOutline, Powershell } from 'mdi-material-ui'; import * as R from 'ramda'; import * as React from 'react'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchExecutors } from '../../../actions/Executor'; import type { ExecutorHelper } from '../../../actions/executors/executor-helper'; @@ -14,7 +15,6 @@ import Breadcrumbs from '../../../components/Breadcrumbs'; import Transition from '../../../components/common/Transition'; import { useFormatter } from '../../../components/i18n'; import PlatformIcon from '../../../components/PlatformIcon'; -import type { Theme } from '../../../components/Theme'; import { useHelper } from '../../../store'; import type { Executor } from '../../../utils/api-types'; import { useAppDispatch } from '../../../utils/hooks'; @@ -23,7 +23,7 @@ import useDataLoader from '../../../utils/hooks/useDataLoader'; import { copyToClipboard, download } from '../../../utils/utils'; import ExecutorDocumentationLink from './ExecutorDocumentationLink'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ card: { overflow: 'hidden', height: 250, @@ -44,14 +44,14 @@ const useStyles = makeStyles(() => ({ const Executors = () => { // Standard hooks - const theme = useTheme(); + const theme = useTheme(); const { t } = useFormatter(); const [platform, setPlatform] = useState(null); const [selectedExecutors, setSelectedExecutors] = useState(null); const [activeTab, setActiveTab] = useState(null); const [agentFolder, setAgentFolder] = useState(null); const [arch, setArch] = useState('x86_64'); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data diff --git a/openbas-front/src/admin/components/agents/ExecutorDocumentationLink.tsx b/openbas-front/src/admin/components/agents/ExecutorDocumentationLink.tsx index 1232f34853..5bacac74ac 100644 --- a/openbas-front/src/admin/components/agents/ExecutorDocumentationLink.tsx +++ b/openbas-front/src/admin/components/agents/ExecutorDocumentationLink.tsx @@ -1,12 +1,12 @@ import { ArticleOutlined } from '@mui/icons-material'; import { Chip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../components/i18n'; import type { Executor } from '../../../utils/api-types'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { height: 30, fontSize: 12, @@ -24,7 +24,7 @@ const ExecutorDocumentationLink: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); if (!executor.executor_doc) { return null; diff --git a/openbas-front/src/admin/components/assets/AssetStatus.tsx b/openbas-front/src/admin/components/assets/AssetStatus.tsx index 4c28615136..440549f8aa 100644 --- a/openbas-front/src/admin/components/assets/AssetStatus.tsx +++ b/openbas-front/src/admin/components/assets/AssetStatus.tsx @@ -1,10 +1,10 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../components/i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 20, fontWeight: 800, @@ -40,7 +40,7 @@ interface Props { const AssetStatus: React.FC = ({ variant, status }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'list' ? classes.chipInList : classes.chip; switch (status) { diff --git a/openbas-front/src/admin/components/assets/Index.tsx b/openbas-front/src/admin/components/assets/Index.tsx index dd3830a35b..87e243e032 100644 --- a/openbas-front/src/admin/components/assets/Index.tsx +++ b/openbas-front/src/admin/components/assets/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy, Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../../../components/Error'; import Loader from '../../../components/Loader'; @@ -11,14 +11,14 @@ const IndexEndpoint = lazy(() => import('./endpoints/endpoint/Index')); const AssetGroups = lazy(() => import('./asset_groups/AssetGroups')); const SecurityPlatforms = lazy(() => import('./security_platforms/SecurityPlatforms')); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); return (
}> diff --git a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupCreation.tsx b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupCreation.tsx index 16a93b16c0..846265b77d 100644 --- a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupCreation.tsx +++ b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupCreation.tsx @@ -1,7 +1,7 @@ import { ControlPointOutlined } from '@mui/icons-material'; -import { ListItemButton, ListItemIcon, ListItemText, Theme } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { addAssetGroup } from '../../../../actions/asset_groups/assetgroup-action'; import ButtonCreate from '../../../../components/common/ButtonCreate'; @@ -13,7 +13,7 @@ import { useAppDispatch } from '../../../../utils/hooks'; import type { UserStore } from '../../teams/players/Player'; import AssetGroupForm from './AssetGroupForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ text: { fontSize: theme.typography.h2.fontSize, color: theme.palette.primary.main, @@ -31,7 +31,7 @@ const AssetGroupCreation: FunctionComponent = ({ onCreate, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const [open, setOpen] = useState(false); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupManagement.tsx b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupManagement.tsx index c86c139ec4..4d3a583678 100644 --- a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupManagement.tsx +++ b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupManagement.tsx @@ -1,7 +1,7 @@ import { CloseRounded } from '@mui/icons-material'; import { IconButton, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchAssetGroup } from '../../../../actions/asset_groups/assetgroup-action'; import type { AssetGroupsHelper } from '../../../../actions/asset_groups/assetgroup-helper'; @@ -9,7 +9,6 @@ import type { EndpointHelper } from '../../../../actions/assets/asset-helper'; import { fetchEndpoints } from '../../../../actions/assets/endpoint-actions'; import type { UserHelper } from '../../../../actions/helper'; import SearchFilter from '../../../../components/SearchFilter'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { AssetGroup, Endpoint } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -20,7 +19,7 @@ import EndpointPopover from '../endpoints/EndpointPopover'; import EndpointsList, { EndpointStoreWithType } from '../endpoints/EndpointsList'; import AssetGroupAddEndpoints from './AssetGroupAddEndpoints'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ // Drawer Header header: { backgroundColor: theme.palette.background.nav, @@ -64,7 +63,7 @@ const AssetGroupManagement: FunctionComponent = ({ onRemoveEndpointFromAssetGroup, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data @@ -122,10 +121,10 @@ const AssetGroupManagement: FunctionComponent = ({
e.asset_id)} + endpoints={sortedAsset} actions={userAdmin ? ( - // @ts-expect-error: Endpoint property handle by EndpointsList + // @ts-expect-error: Endpoint property handle by EndpointsList ({ +const useStyles = makeStyles()(() => ({ drawerPaper: { minHeight: '100vh', width: '50%', @@ -46,7 +46,7 @@ const AssetGroupPopover: FunctionComponent = ({ }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/admin/components/assets/asset_groups/AssetGroups.tsx b/openbas-front/src/admin/components/assets/asset_groups/AssetGroups.tsx index 1af5ce1c93..9c8f508603 100644 --- a/openbas-front/src/admin/components/assets/asset_groups/AssetGroups.tsx +++ b/openbas-front/src/admin/components/assets/asset_groups/AssetGroups.tsx @@ -1,8 +1,8 @@ import { Box, Chip, Drawer as MuiDrawer, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import { CSSProperties, Fragment, useMemo, useState } from 'react'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { searchAssetGroups } from '../../../../actions/asset_groups/assetgroup-action'; import type { EndpointHelper } from '../../../../actions/assets/asset-helper'; @@ -25,7 +25,7 @@ import AssetGroupCreation from './AssetGroupCreation'; import AssetGroupManagement from './AssetGroupManagement'; import AssetGroupPopover from './AssetGroupPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -129,7 +129,7 @@ const computeRuleValues = (assetGroup: AssetGroupOutput, t: (value: string) => s const AssetGroups = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [selectedAssetGroupId, setSelectedAssetGroupId] = useState(undefined); diff --git a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupsList.tsx b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupsList.tsx index 1c6c9c9e6b..f36ae90423 100644 --- a/openbas-front/src/admin/components/assets/asset_groups/AssetGroupsList.tsx +++ b/openbas-front/src/admin/components/assets/asset_groups/AssetGroupsList.tsx @@ -1,8 +1,8 @@ import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import * as React from 'react'; import { CSSProperties, FunctionComponent, useEffect, useMemo, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { findAssetGroups } from '../../../../actions/asset_groups/assetgroup-action'; import ListLoader from '../../../../components/common/loader/ListLoader'; @@ -10,7 +10,7 @@ import { Header } from '../../../../components/common/SortHeadersList'; import ItemTags from '../../../../components/ItemTags'; import type { AssetGroupOutput } from '../../../../utils/api-types'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 50, }, @@ -43,7 +43,7 @@ const AssetGroupsList: FunctionComponent = ({ actions, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const component = (assetGroup: AssetGroupOutput) => { return React.cloneElement(actions as React.ReactElement, { assetGroup }); diff --git a/openbas-front/src/admin/components/assets/endpoints/AgentDeploymentMode.tsx b/openbas-front/src/admin/components/assets/endpoints/AgentDeploymentMode.tsx index c4c51c75fa..9493bcb198 100644 --- a/openbas-front/src/admin/components/assets/endpoints/AgentDeploymentMode.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/AgentDeploymentMode.tsx @@ -1,10 +1,10 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 20, borderRadius: 4, @@ -38,7 +38,7 @@ interface Props { const AgentDeploymentMode: React.FC = ({ variant, mode }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'list' ? classes.chipInList : classes.chip; switch (mode) { diff --git a/openbas-front/src/admin/components/assets/endpoints/AgentPrivilege.tsx b/openbas-front/src/admin/components/assets/endpoints/AgentPrivilege.tsx index 7a6feb99d1..0a609dda1e 100644 --- a/openbas-front/src/admin/components/assets/endpoints/AgentPrivilege.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/AgentPrivilege.tsx @@ -1,10 +1,10 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 20, borderRadius: 4, @@ -38,7 +38,7 @@ interface Props { const AgentPrivilege: React.FC = ({ variant, privilege }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'list' ? classes.chipInList : classes.chip; switch (privilege) { diff --git a/openbas-front/src/admin/components/assets/endpoints/EndpointPopover.tsx b/openbas-front/src/admin/components/assets/endpoints/EndpointPopover.tsx index 5893f21059..ee5b4c5019 100644 --- a/openbas-front/src/admin/components/assets/endpoints/EndpointPopover.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/EndpointPopover.tsx @@ -112,7 +112,7 @@ const EndpointPopover: React.FC = ({ if ((assetGroupId && endpoint.type !== 'dynamic')) entries.push({ label: 'Remove from the asset group', action: () => handleRemoveFromAssetGroup() }); if (onDelete) entries.push({ label: 'Delete', action: () => handleDelete() }); - return ( + return entries.length > 0 && ( <> {inline ? ( @@ -146,7 +146,7 @@ const EndpointPopover: React.FC = ({ open={removalFromAssetGroup} handleClose={() => setRemovalFromAssetGroup(false)} handleSubmit={submitRemoveFromAssetGroup} - text={t('Do you want to remove the endpoint from the asset group ?')} + text={t('Do you want to remove the endpoint from the asset group?')} /> ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -78,7 +78,7 @@ const inlineStyles: Record = { const Endpoints = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); const { settings } = useAuth(); diff --git a/openbas-front/src/admin/components/assets/endpoints/EndpointsList.tsx b/openbas-front/src/admin/components/assets/endpoints/EndpointsList.tsx index 62f858945c..d6fe2b7848 100644 --- a/openbas-front/src/admin/components/assets/endpoints/EndpointsList.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/EndpointsList.tsx @@ -1,16 +1,14 @@ import { DevicesOtherOutlined } from '@mui/icons-material'; import { Chip, List, ListItem, ListItemIcon, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; -import { CSSProperties, FunctionComponent, useEffect, useState } from 'react'; +import { CSSProperties, FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -import { findEndpoints } from '../../../../actions/assets/endpoint-actions'; -import ListLoader from '../../../../components/common/loader/ListLoader'; import ItemTags from '../../../../components/ItemTags'; import PlatformIcon from '../../../../components/PlatformIcon'; import { EndpointOutput, EndpointOverviewOutput } from '../../../../utils/api-types'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 50, }, @@ -50,96 +48,76 @@ const inlineStyles: Record = { export type EndpointStoreWithType = EndpointOutput & EndpointOverviewOutput & { type: string }; interface Props { - endpointIds: string[]; + endpoints: EndpointStoreWithType[]; actions: React.ReactElement; } const EndpointsList: FunctionComponent = ({ - endpointIds = [], + endpoints, actions, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); - const component = (endpoint: EndpointOutput) => { + const component = (endpoint: EndpointStoreWithType) => { return React.cloneElement(actions as React.ReactElement, { endpoint }); }; - const [loading, setLoading] = useState(true); - const [endpointValues, setEndpointValues] = useState([]); - useEffect(() => { - setLoading(true); - findEndpoints(endpointIds).then((result) => { - setEndpointValues(result.data); - setLoading(false); - }); - }, [endpointIds]); - - const isLoading = loading && endpointIds.length > 0; - return ( - <> - { - isLoading - ? - : ( - - {endpointValues?.map((endpoint) => { - return ( - - - - - -
- {endpoint.asset_name} -
-
- - {' '} - {endpoint.endpoint_platform} -
-
- -
-
- - - -
- - )} + + {endpoints?.map((endpoint) => { + return ( + + + + + +
+ {endpoint.asset_name} +
+
+ + {' '} + {endpoint.endpoint_platform} +
+
+ +
+
+ + - - ); - })} - - ) - } - + +
+ + )} + /> +
+ ); + })} +
); }; diff --git a/openbas-front/src/admin/components/assets/endpoints/endpoint/AgentList.tsx b/openbas-front/src/admin/components/assets/endpoints/endpoint/AgentList.tsx index a8246210be..a91c6fac29 100644 --- a/openbas-front/src/admin/components/assets/endpoints/endpoint/AgentList.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/endpoint/AgentList.tsx @@ -1,7 +1,7 @@ import { DevicesOtherOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchExecutors } from '../../../../../actions/Executor'; import type { ExecutorHelper } from '../../../../../actions/executors/executor-helper'; @@ -14,7 +14,7 @@ import AssetStatus from '../../AssetStatus'; import AgentDeploymentMode from '../AgentDeploymentMode'; import AgentPrivilege from '../AgentPrivilege'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -65,7 +65,7 @@ interface Props { } const AgentList: FunctionComponent = ({ agents }) => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t, fldt } = useFormatter(); // Fetching data diff --git a/openbas-front/src/admin/components/assets/endpoints/endpoint/Endpoint.tsx b/openbas-front/src/admin/components/assets/endpoints/endpoint/Endpoint.tsx index 04bf84c5fe..f9531303e3 100644 --- a/openbas-front/src/admin/components/assets/endpoints/endpoint/Endpoint.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/endpoint/Endpoint.tsx @@ -1,6 +1,6 @@ import { Grid, List, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { EndpointHelper } from '../../../../../actions/assets/asset-helper'; import Empty from '../../../../../components/Empty'; @@ -12,7 +12,7 @@ import { useHelper } from '../../../../../store'; import type { EndpointOverviewOutput as EndpointType } from '../../../../../utils/api-types'; import AgentList from './AgentList'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { padding: 20, }, @@ -20,7 +20,7 @@ const useStyles = makeStyles(() => ({ const Endpoint = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { endpointId } = useParams() as { endpointId: EndpointType['asset_id'] }; const { t } = useFormatter(); @@ -140,7 +140,7 @@ const Endpoint = () => { - + {t('Agents')} diff --git a/openbas-front/src/admin/components/assets/endpoints/endpoint/EndpointHeader.tsx b/openbas-front/src/admin/components/assets/endpoints/endpoint/EndpointHeader.tsx index 6f3f426648..9b0b189d9a 100644 --- a/openbas-front/src/admin/components/assets/endpoints/endpoint/EndpointHeader.tsx +++ b/openbas-front/src/admin/components/assets/endpoints/endpoint/EndpointHeader.tsx @@ -1,6 +1,6 @@ import { Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useNavigate, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { EndpointHelper } from '../../../../../actions/assets/asset-helper'; import type { UserHelper } from '../../../../../actions/helper'; @@ -9,7 +9,7 @@ import type { EndpointOverviewOutput as EndpointType } from '../../../../../util import { truncate } from '../../../../../utils/String'; import EndpointPopover from '../EndpointPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ title: { float: 'left', }, @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => ({ const EndpointHeader = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const navigate = useNavigate(); const { endpointId } = useParams() as { endpointId: EndpointType['asset_id'] }; diff --git a/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatformCreation.tsx b/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatformCreation.tsx index 5163d40160..39f81f8bc5 100644 --- a/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatformCreation.tsx +++ b/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatformCreation.tsx @@ -1,7 +1,7 @@ import { ControlPointOutlined } from '@mui/icons-material'; -import { ListItemButton, ListItemIcon, ListItemText, Theme } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { addSecurityPlatform } from '../../../../actions/assets/securityPlatform-actions'; import ButtonCreate from '../../../../components/common/ButtonCreate'; @@ -12,7 +12,7 @@ import type { SecurityPlatform, SecurityPlatformInput } from '../../../../utils/ import { useAppDispatch } from '../../../../utils/hooks'; import SecurityPlatformForm from './SecurityPlatformForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ text: { fontSize: theme.typography.h2.fontSize, color: theme.palette.primary.main, @@ -30,7 +30,7 @@ const SecurityPlatformCreation: FunctionComponent = ({ onCreate, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const [open, setOpen] = useState(false); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatforms.tsx b/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatforms.tsx index 0dd3210eb4..1c490d486e 100644 --- a/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatforms.tsx +++ b/openbas-front/src/admin/components/assets/security_platforms/SecurityPlatforms.tsx @@ -1,7 +1,8 @@ import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { CSSProperties, useState } from 'react'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { searchSecurityPlatforms } from '../../../../actions/assets/securityPlatform-actions'; import type { UserHelper } from '../../../../actions/helper'; @@ -12,14 +13,13 @@ import { initSorting } from '../../../../components/common/queryable/Page'; import { buildSearchPagination } from '../../../../components/common/queryable/QueryableUtils'; import { useFormatter } from '../../../../components/i18n'; import ItemTags from '../../../../components/ItemTags'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { SearchPaginationInput, SecurityPlatform } from '../../../../utils/api-types'; import { isNotEmptyField } from '../../../../utils/utils'; import SecurityPlatformCreation from './SecurityPlatformCreation'; import SecurityPlatformPopover from './SecurityPlatformPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -61,8 +61,8 @@ const inlineStyles: Record = { const SecurityPlatforms = () => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const { t } = useFormatter(); // Query param diff --git a/openbas-front/src/admin/components/atomic_testings/InjectResultList.tsx b/openbas-front/src/admin/components/atomic_testings/InjectResultList.tsx index b301cb1eee..3e477e6e7a 100644 --- a/openbas-front/src/admin/components/atomic_testings/InjectResultList.tsx +++ b/openbas-front/src/admin/components/atomic_testings/InjectResultList.tsx @@ -1,8 +1,8 @@ import { HelpOutlineOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useMemo, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { type Page } from '../../../components/common/queryable/Page'; import PaginationComponentV2 from '../../../components/common/queryable/pagination/PaginationComponentV2'; @@ -21,7 +21,7 @@ import InjectorContract from '../common/injects/InjectorContract'; import AtomicTestingPopover from './atomic_testing/AtomicTestingPopover'; import AtomicTestingResult from './atomic_testing/AtomicTestingResult'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -82,7 +82,7 @@ const InjectResultList: FunctionComponent = ({ searchPaginationInput, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, fldt, tPick, nsdt } = useFormatter(); const [loading, setLoading] = useState(true); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTesting.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTesting.tsx index 3c3178f998..1cb89ca03e 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTesting.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTesting.tsx @@ -1,6 +1,6 @@ import { Chip, Grid, List, Paper, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext, useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../../../actions/Document'; import { DocumentHelper } from '../../../../actions/helper'; @@ -23,7 +23,7 @@ import { InjectResultOverviewOutputContext, InjectResultOverviewOutputContextTyp import TargetListItem from './TargetListItem'; import TargetResultsDetail from './TargetResultsDetail'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -46,7 +46,7 @@ const useStyles = makeStyles(() => ({ const AtomicTesting = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t, tPick, fldt } = useFormatter(); const [selectedTarget, setSelectedTarget] = useState(); @@ -63,7 +63,7 @@ const AtomicTesting = () => { // Fetching data const { injectResultOverviewOutput } = useContext(InjectResultOverviewOutputContext); useEffect(() => { - setSelectedTarget(selectedTarget || currentParentTarget || injectResultOverviewOutput?.inject_targets[0]); + setSelectedTarget(selectedTarget || currentParentTarget || injectResultOverviewOutput?.inject_targets ? injectResultOverviewOutput?.inject_targets[0] : undefined); }, [injectResultOverviewOutput]); const sortedTargets: InjectTargetWithResult[] = filtering.filterAndSort(injectResultOverviewOutput?.inject_targets ?? []); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingDetail.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingDetail.tsx index 3f936b2221..f742e7e808 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingDetail.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingDetail.tsx @@ -1,119 +1,73 @@ -import { Grid, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { Props } from 'html-react-parser/lib/attributes-to-props'; -import { FunctionComponent, useContext } from 'react'; +import { FunctionComponent, useContext, useEffect, useState } from 'react'; -import { useFormatter } from '../../../../components/i18n'; -import ItemStatus from '../../../../components/ItemStatus'; +import { searchEndpoints } from '../../../../actions/assets/endpoint-actions'; +import { buildFilter } from '../../../../components/common/queryable/filter/FilterUtils'; +import { buildSearchPagination } from '../../../../components/common/queryable/QueryableUtils'; +import Loader from '../../../../components/Loader'; +import { EndpointOutput, type InjectResultOverviewOutput } from '../../../../utils/api-types'; +import InjectStatus from '../../common/injects/status/InjectStatus'; import { InjectResultOverviewOutputContext, InjectResultOverviewOutputContextType } from '../InjectResultOverviewOutputContext'; -const useStyles = makeStyles(() => ({ - paper: { - position: 'relative', - padding: 20, - overflow: 'hidden', - height: '100%', - }, - header: { - fontWeight: 'bold', - }, - listItem: { - marginBottom: 8, - }, -})); - const AtomicTestingDetail: FunctionComponent = () => { - const classes = useStyles(); - const { t } = useFormatter(); - // Fetching data + const [loading, setLoading] = useState(true); const { injectResultOverviewOutput } = useContext(InjectResultOverviewOutputContext); + const [endpointsMap, setEndpointsMap] = useState>(new Map()); + + const extractEndpointsFromInjectResult = (injectResult: InjectResultOverviewOutput): Map => { + const map = new Map(); + injectResult?.inject_targets.forEach((result) => { + if (result.targetType === 'ASSETS_GROUPS' && result.children) { + result.children.forEach(({ id, name, platformType }) => { + map.set(id, { asset_id: id, asset_name: name, endpoint_platform: platformType } as EndpointOutput); + }); + } + if (result.targetType === 'ASSETS') { + map.set(result.id, { asset_id: result.id, asset_name: result.name, endpoint_platform: result.platformType } as EndpointOutput); + } + }); + return map; + }; + + const findMissingEndpointIds = (injectResult: InjectResultOverviewOutput, existingMap: Map): string[] => { + return injectResult.inject_status?.status_traces_by_agent + ?.filter(traceByAgent => !existingMap.has(traceByAgent.asset_id)) + .map(traceByAgent => traceByAgent.asset_id) || []; + }; + + useEffect(() => { + if (!injectResultOverviewOutput) return; + const newEndpointsMap = extractEndpointsFromInjectResult(injectResultOverviewOutput); + const missingEndpointIds = findMissingEndpointIds(injectResultOverviewOutput, newEndpointsMap); + if (missingEndpointIds.length > 0) { + searchEndpoints(buildSearchPagination({ + filterGroup: { + mode: 'and', + filters: [ + buildFilter('asset_id', missingEndpointIds, 'eq'), + ], + }, + })).then(({ data }) => { + data?.content.forEach((endpoint: EndpointOutput) => newEndpointsMap.set(endpoint.asset_id, endpoint)); + setEndpointsMap(newEndpointsMap); + setLoading(false); + }); + } else { + setEndpointsMap(newEndpointsMap); + setLoading(false); + } + }, [injectResultOverviewOutput]); + + if (loading) { + return ; + } return ( - - - {t('Execution logs')} - {injectResultOverviewOutput ? ( - - - {t('Execution status')} - - {injectResultOverviewOutput.inject_status?.status_name - && } - - {t('Traces')} - -
-              {injectResultOverviewOutput.inject_status?.tracking_sent_date ? (
-                <>
-                  
-                    {t('Tracking Sent Date')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_sent_date}
-                  
-                  
-                    {t('Tracking Ack Date')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_ack_date}
-                  
-                  
-                    {t('Tracking End Date')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_end_date}
-                  
-                  
-                    {t('Tracking Total Execution')}
-                    {t('Time')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_total_execution_time}
-                    {' '}
-                    {t('ms')}
-                  
-                  
-                    {t('Tracking Total Count')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_total_count}
-                  
-                  
-                    {t('Tracking Total Error')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_total_error}
-                  
-                  
-                    {t('Tracking Total Success')}
-                    :
-                    {injectResultOverviewOutput.inject_status?.tracking_total_success}
-                  
-                
-              ) : (
-                
-                  {t('No data available')}
-                
-              )}
-              {(injectResultOverviewOutput.inject_status?.status_traces?.length ?? 0) > 0 && (
-                <>
-                  
-                    {t('Traces')}
-                    :
-                  
-                  
    - {injectResultOverviewOutput.inject_status?.status_traces?.map((trace, index) => ( -
  • - {`${trace.execution_status} ${trace.execution_message}`} -
  • - ))} -
- - )} -
-
- ) : ( - - {t('No data available')} - - )} -
-
+ ); }; diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingHeader.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingHeader.tsx index c7c9c23614..8a74006dfe 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingHeader.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingHeader.tsx @@ -1,8 +1,8 @@ import { PlayArrowOutlined, SettingsOutlined } from '@mui/icons-material'; import { Alert, Button, Dialog, DialogActions, DialogContent, DialogContentText, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext, useState } from 'react'; import { useNavigate } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { launchAtomicTesting, @@ -17,7 +17,7 @@ import { InjectResultOverviewOutputContext, InjectResultOverviewOutputContextTyp import AtomicTestingPopover from './AtomicTestingPopover'; import AtomicTestingUpdate from './AtomicTestingUpdate'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ title: { float: 'left', marginRight: 10, @@ -31,7 +31,7 @@ const useStyles = makeStyles(() => ({ const AtomicTestingHeader = () => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const navigate = useNavigate(); const { injectResultOverviewOutput, updateInjectResultOverviewOutput } = useContext(InjectResultOverviewOutputContext); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingPayloadInfo.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingPayloadInfo.tsx index 5debdeafe4..b6a58d8843 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingPayloadInfo.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingPayloadInfo.tsx @@ -1,8 +1,8 @@ import { Chip, Grid, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { Props } from 'html-react-parser/lib/attributes-to-props'; import { FunctionComponent, useEffect, useState } from 'react'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchAtomicTestingPayload } from '../../../../actions/atomic_testings/atomic-testing-actions'; import { useFormatter } from '../../../../components/i18n'; @@ -12,7 +12,7 @@ import PlatformIcon from '../../../../components/PlatformIcon'; import { AttackPatternSimple, PayloadArgument, PayloadCommandBlock, PayloadPrerequisite, StatusPayloadOutput } from '../../../../utils/api-types'; import { emptyFilled } from '../../../../utils/String'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', padding: 20, @@ -30,7 +30,7 @@ const useStyles = makeStyles(() => ({ })); const AtomicTestingPayloadInfo: FunctionComponent = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { injectId } = useParams(); const [payloadOutput, setPayloadOutput] = useState(); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingResult.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingResult.tsx index 8b1de48853..e3f027ca98 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingResult.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingResult.tsx @@ -1,12 +1,12 @@ import { SensorOccupiedOutlined, ShieldOutlined, TrackChangesOutlined } from '@mui/icons-material'; import { Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import type { ExpectationResultsByType, InjectResultOutput } from '../../../../utils/api-types'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ inline: { display: 'flex', alignItems: 'center', @@ -22,7 +22,7 @@ interface Props { const AtomicTestingResult: React.FC = ({ expectations, injectId }) => { const { t } = useFormatter(); let tooltipLabel: string = ''; - const classes = useStyles(); + const { classes } = useStyles(); const getColor = (result: string | undefined): string => { const colorMap: Record = { SUCCESS: 'rgb(107, 235, 112)', diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/Index.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/Index.tsx index 1fb39a272b..2f84613b29 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/Index.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/Index.tsx @@ -1,8 +1,8 @@ import { Box, Tab, Tabs } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { lazy, Suspense, useEffect, useState } from 'react'; import { Link, Route, Routes, useLocation, useParams } from 'react-router'; import { interval } from 'rxjs'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjectResultOverviewOutput } from '../../../../actions/atomic_testings/atomic-testing-actions'; import Breadcrumbs from '../../../../components/Breadcrumbs'; @@ -21,7 +21,7 @@ import teamContextForAtomicTesting from './context/TeamContextForAtomicTesting'; const interval$ = interval(FIVE_SECONDS); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 30, fontSize: 13, @@ -37,7 +37,7 @@ const AtomicTesting = lazy(() => import('./AtomicTesting')); const AtomicTestingDetail = lazy(() => import('./AtomicTestingDetail')); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const location = useLocation(); let tabValue = location.pathname; diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetListItem.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetListItem.tsx index fd1bbfdf10..5649d59ece 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetListItem.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetListItem.tsx @@ -1,14 +1,14 @@ import { DevicesOtherOutlined, Groups3Outlined, PersonOutlined } from '@mui/icons-material'; import { Divider, ListItemButton, ListItemIcon, ListItemText, Paper } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import PlatformIcon from '../../../../components/PlatformIcon'; import type { InjectTargetWithResult } from '../../../../utils/api-types'; import AtomicTestingResult from './AtomicTestingResult'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ bodyTarget: { fontSize: 13, whiteSpace: 'nowrap', @@ -17,7 +17,6 @@ const useStyles = makeStyles(() => ({ textOverflow: 'ellipsis', }, dividerL: { - content: '', position: 'absolute', backgroundColor: 'rgba(105, 103, 103, 0.45)', width: '2px', @@ -35,7 +34,7 @@ interface Props { } const TargetListItem: React.FC = ({ isChild, onClick, target, selected }) => { - const classes = useStyles(); + const { classes } = useStyles(); const style = isChild ? { marginBottom: 10, marginLeft: 50 } : { marginBottom: 10 }; const handleItemClick = () => { onClick(target); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetResultsDetail.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetResultsDetail.tsx index a2057fae2b..ee3b8334db 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetResultsDetail.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/TargetResultsDetail.tsx @@ -21,17 +21,17 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Edge, MarkerType, ReactFlow, ReactFlowProvider, useEdgesState, useNodesState, useReactFlow } from '@xyflow/react'; import { FunctionComponent, useContext, useEffect, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjectResultOverviewOutput, fetchTargetResult } from '../../../../actions/atomic_testings/atomic-testing-actions'; import { deleteInjectExpectationResult } from '../../../../actions/Exercise'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import ItemResult from '../../../../components/ItemResult'; -import type { Theme } from '../../../../components/Theme'; import { type InjectExpectation, InjectExpectationResult, InjectResultOverviewOutput, InjectTargetWithResult } from '../../../../utils/api-types'; import useAutoLayout, { type LayoutOptions } from '../../../../utils/flows/useAutoLayout'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -54,7 +54,7 @@ interface Steptarget { key?: string; } -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ container: { margin: '20px 0 0 0', overflow: 'hidden', @@ -120,9 +120,9 @@ const TargetResultsDetailFlow: FunctionComponent = ({ target, parentTargetId, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); - const theme = useTheme(); + const theme = useTheme(); const { nsdt, t } = useFormatter(); const [anchorEls, setAnchorEls] = useState>({}); const [selectedExpectationForCreation, setSelectedExpectationForCreation] = useState<{ injectExpectation: InjectExpectationsStore; sourceIds: string[] } | null>(null); diff --git a/openbas-front/src/admin/components/atomic_testings/atomic_testing/types/nodes/NodeResultStep.tsx b/openbas-front/src/admin/components/atomic_testings/atomic_testing/types/nodes/NodeResultStep.tsx index 1f95e8ebcc..f0f53de8bf 100644 --- a/openbas-front/src/admin/components/atomic_testings/atomic_testing/types/nodes/NodeResultStep.tsx +++ b/openbas-front/src/admin/components/atomic_testings/atomic_testing/types/nodes/NodeResultStep.tsx @@ -1,14 +1,12 @@ import { FlagOutlined, HelpOutlined, ModeStandbyOutlined, ScoreOutlined } from '@mui/icons-material'; import { Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { Handle, Node, NodeProps, Position } from '@xyflow/react'; import { memo } from 'react'; - -import type { Theme } from '../../../../../../components/Theme'; +import { makeStyles } from 'tss-react/mui'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ node: { position: 'relative', border: @@ -72,7 +70,7 @@ export type NodeResultStep = Node<{ >; const NodeResultStepComponent = ({ data }: NodeProps) => { - const classes = useStyles(); + const { classes } = useStyles(); return (
diff --git a/openbas-front/src/admin/components/common/Context.ts b/openbas-front/src/admin/components/common/Context.ts index 98901c49ce..576d333313 100644 --- a/openbas-front/src/admin/components/common/Context.ts +++ b/openbas-front/src/admin/components/common/Context.ts @@ -13,8 +13,7 @@ import type { Inject, InjectBulkProcessingInput, InjectBulkUpdateInputs, - InjectsImportInput, - InjectTestStatus, + InjectsImportInput, InjectTestStatusOutput, LessonsAnswer, LessonsAnswerCreateInput, LessonsCategory, @@ -102,7 +101,7 @@ export type InjectContextType = { onBulkDeleteInjects: (param: InjectBulkProcessingInput) => Promise; bulkTestInjects: (param: InjectBulkProcessingInput) => Promise<{ uri: string; - data: InjectTestStatus[]; + data: InjectTestStatusOutput[]; }>; }; export type LessonContextType = { @@ -234,9 +233,9 @@ export const InjectContext = createContext({ }, bulkTestInjects(_param: InjectBulkProcessingInput): Promise<{ uri: string; - data: InjectTestStatus[]; + data: InjectTestStatusOutput[]; }> { - return new Promise<{ uri: string; data: InjectTestStatus[] }>(() => { + return new Promise<{ uri: string; data: InjectTestStatusOutput[] }>(() => { }); }, }); diff --git a/openbas-front/src/admin/components/common/ToolBar.js b/openbas-front/src/admin/components/common/ToolBar.js index 0ed00ebc6f..077285b698 100644 --- a/openbas-front/src/admin/components/common/ToolBar.js +++ b/openbas-front/src/admin/components/common/ToolBar.js @@ -25,12 +25,12 @@ import { Tooltip, Typography, } from '@mui/material'; -import { withStyles, withTheme } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component, forwardRef } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { fetchAssetGroups } from '../../../actions/asset_groups/assetgroup-action'; import { fetchEndpoints } from '../../../actions/assets/endpoint-actions'; @@ -158,6 +158,11 @@ const styles = theme => ({ autoCompleteIndicator: { display: 'none', }, + numberOfSelectedElements: { + padding: '2px 5px 2px 5px', + marginRight: 5, + backgroundColor: theme.palette.background.accent, + }, }); const Transition = forwardRef((props, ref) => ( @@ -504,7 +509,6 @@ class ToolBar extends Component { classes, numberOfSelectedElements, handleClearSelectedElements, - theme, variant, } = this.props; const { actionsInputs, navOpen } = this.state; @@ -549,13 +553,7 @@ class ToolBar extends Component { color="inherit" variant="subtitle1" > - + {numberOfSelectedElements} {' '} @@ -735,7 +733,6 @@ class ToolBar extends Component { ToolBar.propTypes = { classes: PropTypes.object, - theme: PropTypes.object, t: PropTypes.func, numberOfSelectedElements: PropTypes.number, selectedElements: PropTypes.object, @@ -771,6 +768,5 @@ const select = (state, ownProps) => { export default R.compose( connect(select, { fetchEndpoints, fetchAssetGroups }), inject18n, - withTheme, - withStyles(styles), + Component => withStyles(Component, styles), )(ToolBar); diff --git a/openbas-front/src/admin/components/common/articles/ArticleAddDocuments.js b/openbas-front/src/admin/components/common/articles/ArticleAddDocuments.js index e60a4581d8..5600174138 100644 --- a/openbas-front/src/admin/components/common/articles/ArticleAddDocuments.js +++ b/openbas-front/src/admin/components/common/articles/ArticleAddDocuments.js @@ -12,9 +12,9 @@ import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../../../actions/Document'; import Transition from '../../../../components/common/Transition'; @@ -29,7 +29,7 @@ import CreateDocument from '../../components/documents/CreateDocument'; import { PermissionsContext } from '../Context'; import TagsFilter from '../filters/TagsFilter'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ box: { width: '100%', minHeight: '100%', @@ -53,7 +53,7 @@ const useStyles = makeStyles(theme => ({ const ArticleAddDocuments = (props) => { const { handleAddDocuments, articleDocumentsIds, channelType } = props; // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/common/articles/ArticleForm.js b/openbas-front/src/admin/components/common/articles/ArticleForm.js index 254ac33406..0ddc27ace6 100644 --- a/openbas-front/src/admin/components/common/articles/ArticleForm.js +++ b/openbas-front/src/admin/components/common/articles/ArticleForm.js @@ -1,10 +1,10 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined, AttachmentOutlined } from '@mui/icons-material'; import { Box, Button, Grid, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useState } from 'react'; import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { fetchChannels } from '../../../../actions/channels/channel-action'; import { fetchDocuments } from '../../../../actions/Document'; @@ -20,7 +20,7 @@ import DocumentPopover from '../../components/documents/DocumentPopover'; import DocumentType from '../../components/documents/DocumentType'; import ArticleAddDocuments from './ArticleAddDocuments'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -110,7 +110,7 @@ const ArticleForm = ({ editing, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const [documentsSortBy, setDocumentsSortBy] = useState('document_name'); const [documentsOrderAsc, setDocumentsOrderAsc] = useState(true); diff --git a/openbas-front/src/admin/components/common/articles/Articles.tsx b/openbas-front/src/admin/components/common/articles/Articles.tsx index b40955cd21..a83467354e 100644 --- a/openbas-front/src/admin/components/common/articles/Articles.tsx +++ b/openbas-front/src/admin/components/common/articles/Articles.tsx @@ -1,10 +1,10 @@ import { ChatBubbleOutlineOutlined, FavoriteBorderOutlined, NewspaperOutlined, ShareOutlined, VisibilityOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, CardMedia, Chip, Grid, IconButton, Tooltip, Typography } from '@mui/material'; import { green, orange } from '@mui/material/colors'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { Fragment, FunctionComponent, useContext, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { FullArticleStore } from '../../../../actions/channels/Article'; import { fetchChannels } from '../../../../actions/channels/channel-action'; @@ -27,7 +27,7 @@ import { ArticleContext, PermissionsContext } from '../Context'; import ArticlePopover from './ArticlePopover'; import CreateArticle from './CreateArticle'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ channel: { fontSize: 12, float: 'left', @@ -56,7 +56,7 @@ interface Props { const Articles: FunctionComponent = ({ articles }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/common/articles/CreateArticle.js b/openbas-front/src/admin/components/common/articles/CreateArticle.js index 1da21d6020..08286cee5b 100644 --- a/openbas-front/src/admin/components/common/articles/CreateArticle.js +++ b/openbas-front/src/admin/components/common/articles/CreateArticle.js @@ -1,14 +1,14 @@ import { Add, ControlPointOutlined } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, IconButton, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext } from 'react'; +import { makeStyles } from 'tss-react/mui'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import { ArticleContext } from '../Context'; import ArticleForm from './ArticleForm'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ createButton: { float: 'left', marginTop: -15, @@ -22,7 +22,7 @@ const useStyles = makeStyles(theme => ({ const CreateArticle = (props) => { const { onCreate, inline, openCreate, handleOpenCreate, handleCloseCreate } = props; - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Context diff --git a/openbas-front/src/admin/components/common/challenges/ContextualChallenges.js b/openbas-front/src/admin/components/common/challenges/ContextualChallenges.js index 2f04657f48..a4f89cccd5 100644 --- a/openbas-front/src/admin/components/common/challenges/ContextualChallenges.js +++ b/openbas-front/src/admin/components/common/challenges/ContextualChallenges.js @@ -8,9 +8,9 @@ import { VisibilityOutlined, } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, Chip, Grid, IconButton, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../../components/Empty'; import ExpandableMarkdown from '../../../../components/ExpandableMarkdown'; @@ -18,7 +18,7 @@ import { useFormatter } from '../../../../components/i18n'; import useSearchAnFilter from '../../../../utils/SortingFiltering'; import { ChallengeContext } from '../Context'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ flag: { fontSize: 12, float: 'left', @@ -47,7 +47,7 @@ const useStyles = makeStyles(() => ({ const ContextualChallenges = ({ challenges, linkToInjects }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Context diff --git a/openbas-front/src/admin/components/common/entreprise_edition/EEChip.tsx b/openbas-front/src/admin/components/common/entreprise_edition/EEChip.tsx index 6ee1c0dbf9..adaabd6d25 100644 --- a/openbas-front/src/admin/components/common/entreprise_edition/EEChip.tsx +++ b/openbas-front/src/admin/components/common/entreprise_edition/EEChip.tsx @@ -1,15 +1,14 @@ -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../actions/helper'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import useEnterpriseEdition from '../../../../utils/hooks/useEnterpriseEdition'; import EnterpriseEditionAgreement from './EnterpriseEditionAgreement'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ container: { fontSize: 'xx-small', height: 14, @@ -43,7 +42,7 @@ const useStyles = makeStyles(theme => ({ })); const EEChip = ({ clickable = true, floating = false }: { clickable?: boolean; floating?: boolean }) => { - const classes = useStyles(); + const { classes } = useStyles(); const isEnterpriseEdition = useEnterpriseEdition(); const [displayDialog, setDisplayDialog] = useState(false); const userAdmin = useHelper((helper: UserHelper) => { diff --git a/openbas-front/src/admin/components/common/entreprise_edition/EEField.tsx b/openbas-front/src/admin/components/common/entreprise_edition/EEField.tsx index f4eddbccf2..2b8d3e9370 100644 --- a/openbas-front/src/admin/components/common/entreprise_edition/EEField.tsx +++ b/openbas-front/src/admin/components/common/entreprise_edition/EEField.tsx @@ -1,13 +1,13 @@ -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import EEChip from './EEChip'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles({ +const useStyles = makeStyles()({ labelRoot: { '& .MuiFormLabel-root': { zIndex: 1, @@ -22,7 +22,7 @@ interface EEFieldProps { const EEField: FunctionComponent = ({ children, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const component = React.cloneElement(children, { label: diff --git a/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEdition.tsx b/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEdition.tsx index fa56461826..c96bc21224 100644 --- a/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEdition.tsx +++ b/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEdition.tsx @@ -14,15 +14,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ import { Alert, AlertTitle } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import EnterpriseEditionButton from './EnterpriseEditionButton'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ alert: { width: '100%', marginBottom: 20, @@ -32,7 +31,7 @@ const useStyles = makeStyles(theme => ({ })); const EnterpriseEdition = ({ message }: { message?: string; feature?: string }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); return ( <> diff --git a/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEditionButton.tsx b/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEditionButton.tsx index 713797c49d..16d0d106c6 100644 --- a/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEditionButton.tsx +++ b/openbas-front/src/admin/components/common/entreprise_edition/EnterpriseEditionButton.tsx @@ -1,8 +1,7 @@ import { RocketLaunchOutlined } from '@mui/icons-material'; import { Button } from '@mui/material'; -import { makeStyles } from '@mui/styles'; -import classNames from 'classnames'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../actions/helper'; import { useFormatter } from '../../../../components/i18n'; @@ -11,7 +10,7 @@ import EnterpriseEditionAgreement from './EnterpriseEditionAgreement'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles({ +const useStyles = makeStyles()({ button: { marginLeft: 20, }, @@ -23,7 +22,7 @@ const useStyles = makeStyles({ const EnterpriseEditionButton = ({ inLine = false }: { inLine?: boolean }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); const [openEnterpriseEditionConsent, setOpenEnterpriseEditionConsent] = useState(false); const userAdmin = useHelper((helper: UserHelper) => { const me = helper.getMe(); @@ -42,7 +41,7 @@ const EnterpriseEditionButton = ({ inLine = false }: { inLine?: boolean }) => { onClick={() => setOpenEnterpriseEditionConsent(true)} startIcon={} classes={{ - root: classNames({ + root: cx({ [classes.button]: true, [classes.inLine]: inLine, }), diff --git a/openbas-front/src/admin/components/common/filters/KillChainPhasesFilter.js b/openbas-front/src/admin/components/common/filters/KillChainPhasesFilter.js index 105e0d01f1..f2c2b27bc6 100644 --- a/openbas-front/src/admin/components/common/filters/KillChainPhasesFilter.js +++ b/openbas-front/src/admin/components/common/filters/KillChainPhasesFilter.js @@ -1,14 +1,14 @@ import { RouteOutlined } from '@mui/icons-material'; import { Autocomplete, Box, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useEffect } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { buildEmptyFilter } from '../../../../components/common/queryable/filter/FilterUtils'; import { useFormatter } from '../../../../components/i18n'; import { useHelper } from '../../../../store'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -22,7 +22,7 @@ const useStyles = makeStyles(() => ({ const KillChainPhasesFilter = (props) => { const { fullWidth, filterKey, helpers } = props; - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const killChainPhases = useHelper(helper => helper.getKillChainPhases()); useEffect(() => { diff --git a/openbas-front/src/admin/components/common/filters/MitreFilter.tsx b/openbas-front/src/admin/components/common/filters/MitreFilter.tsx index 737d9d41fd..3b0b25cf3e 100644 --- a/openbas-front/src/admin/components/common/filters/MitreFilter.tsx +++ b/openbas-front/src/admin/components/common/filters/MitreFilter.tsx @@ -1,6 +1,6 @@ import { Button, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useEffect } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AttackPatternHelper } from '../../../../actions/attack_patterns/attackpattern-helper'; import type { InjectorContractHelper } from '../../../../actions/injector_contracts/injector-contract-helper'; @@ -9,7 +9,6 @@ import type { KillChainPhaseHelper } from '../../../../actions/kill_chain_phases import { FilterHelpers } from '../../../../components/common/queryable/filter/FilterHelpers'; import { buildEmptyFilter } from '../../../../components/common/queryable/filter/FilterUtils'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { AttackPattern, KillChainPhase } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -20,7 +19,7 @@ interface InjectorContractLight { injector_contract_attack_patterns_external_id?: string[]; } -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ container: { display: 'flex', gap: 10, @@ -56,7 +55,7 @@ const KillChainPhaseColumn: FunctionComponent = ({ onClick, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Attack Pattern @@ -147,7 +146,7 @@ const MitreFilter: FunctionComponent = ({ onClick, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data diff --git a/openbas-front/src/admin/components/common/filters/TagsFilter.js b/openbas-front/src/admin/components/common/filters/TagsFilter.js index c552e54bf5..5189c4dd62 100644 --- a/openbas-front/src/admin/components/common/filters/TagsFilter.js +++ b/openbas-front/src/admin/components/common/filters/TagsFilter.js @@ -1,12 +1,12 @@ import { LabelOutlined } from '@mui/icons-material'; import { Autocomplete, Box, Chip, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import { useHelper } from '../../../../store'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -26,7 +26,7 @@ const useStyles = makeStyles(() => ({ })); const TagsFilter = (props) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const tags = useHelper(helper => helper.getTags()); const { onAddTag, onClearTag, onRemoveTag, currentTags, fullWidth } = props; diff --git a/openbas-front/src/admin/components/common/injects/CreateInject.tsx b/openbas-front/src/admin/components/common/injects/CreateInject.tsx index 9549dc290e..a4c689e29c 100644 --- a/openbas-front/src/admin/components/common/injects/CreateInject.tsx +++ b/openbas-front/src/admin/components/common/injects/CreateInject.tsx @@ -1,7 +1,7 @@ import { KeyboardArrowRight } from '@mui/icons-material'; import { Chip, Grid, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useEffect, useMemo, useRef, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AttackPatternHelper } from '../../../../actions/attack_patterns/attackpattern-helper'; import { searchInjectorContracts } from '../../../../actions/InjectorContracts'; @@ -23,7 +23,7 @@ import { isNotEmptyField } from '../../../../utils/utils'; import CreateInjectDetails from './CreateInjectDetails'; import InjectIcon from './InjectIcon'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -83,7 +83,7 @@ interface Props { const CreateInject: FunctionComponent = ({ title, onCreateInject, open = false, handleClose, isAtomic = false, presetValues, ...props }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const drawerRef = useRef(null); const { t, tPick } = useFormatter(); diff --git a/openbas-front/src/admin/components/common/injects/CreateInjectDetails.js b/openbas-front/src/admin/components/common/injects/CreateInjectDetails.js index b5a559ac2e..77b5334eae 100644 --- a/openbas-front/src/admin/components/common/injects/CreateInjectDetails.js +++ b/openbas-front/src/admin/components/common/injects/CreateInjectDetails.js @@ -1,10 +1,10 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { ArrowDropDownOutlined, ArrowDropUpOutlined, HelpOutlined, HighlightOffOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, IconButton } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { useFormatter } from '../../../../components/i18n'; @@ -15,7 +15,7 @@ import InjectDefinition from './form/InjectDefinition'; import InjectForm from './form/InjectForm'; import InjectIcon from './InjectIcon'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ injectorContract: { marginTop: 30, width: '100%', @@ -77,7 +77,7 @@ const CreateInjectDetails = ({ ...props }) => { const { t, tPick } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { permissions } = useContext(PermissionsContext); const [openDetails, setOpenDetails] = useState(false); const [defaultValues, setDefaultValues] = useState({}); diff --git a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromInjectsTest.tsx b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromInjectsTest.tsx index 67279d0e73..12874e40dd 100644 --- a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromInjectsTest.tsx +++ b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromInjectsTest.tsx @@ -1,9 +1,9 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Autocomplete as MuiAutocomplete, Box, Button, MenuItem, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import moment from 'moment-timezone'; import { FunctionComponent, SyntheticEvent, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { testXlsFile } from '../../../../actions/mapper/mapper-actions'; @@ -12,7 +12,7 @@ import { useFormatter } from '../../../../components/i18n'; import type { ImportMapperAddInput, ImportTestSummary, InjectsImportTestInput } from '../../../../utils/api-types'; import { zodImplement } from '../../../../utils/Zod'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', flexDirection: 'column', @@ -46,7 +46,7 @@ const ImportUploaderInjectFromInjectsTest: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // TimeZone const timezones = moment.tz.names(); diff --git a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsFile.tsx b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsFile.tsx index 303b3c450f..726dbed57a 100644 --- a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsFile.tsx +++ b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsFile.tsx @@ -1,8 +1,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Button } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, SyntheticEvent, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import CustomFileUploader from '../../../../components/common/CustomFileUploader'; @@ -10,7 +10,7 @@ import { useFormatter } from '../../../../components/i18n'; import Loader from '../../../../components/Loader'; import { zodImplement } from '../../../../utils/Zod'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', flexDirection: 'column', @@ -39,7 +39,7 @@ const ImportUploaderInjectFromXlsFile: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const [loading, setLoading] = useState(false); diff --git a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsInjects.tsx b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsInjects.tsx index c56584b6c3..c3e84de267 100644 --- a/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsInjects.tsx +++ b/openbas-front/src/admin/components/common/injects/ImportUploaderInjectFromXlsInjects.tsx @@ -1,12 +1,12 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { TableViewOutlined } from '@mui/icons-material'; import { Autocomplete as MuiAutocomplete, Box, Button, MenuItem, TextField, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { DateTimePicker } from '@mui/x-date-pickers'; import { InformationOutline } from 'mdi-material-ui'; import moment from 'moment-timezone'; import { FunctionComponent, SyntheticEvent, useContext, useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { searchMappers } from '../../../../actions/mapper/mapper-actions'; @@ -16,7 +16,7 @@ import type { ImportMapper, ImportMessage, ImportTestSummary, InjectsImportInput import { zodImplement } from '../../../../utils/Zod'; import { InjectContext } from '../Context'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', flexDirection: 'column', @@ -61,7 +61,7 @@ const ImportUploaderInjectFromXlsInjects: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // TimeZone const timezones = moment.tz.names(); diff --git a/openbas-front/src/admin/components/common/injects/InjectAddArticles.tsx b/openbas-front/src/admin/components/common/injects/InjectAddArticles.tsx index ac414ab004..d387e0a675 100644 --- a/openbas-front/src/admin/components/common/injects/InjectAddArticles.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectAddArticles.tsx @@ -12,9 +12,9 @@ import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { FullArticleStore } from '../../../../actions/channels/Article'; import type { ArticlesHelper } from '../../../../actions/channels/article-helper'; @@ -23,7 +23,6 @@ import type { ChannelsHelper } from '../../../../actions/channels/channel-helper import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import SearchFilter from '../../../../components/SearchFilter'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import { Article } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -33,7 +32,7 @@ import ChannelIcon from '../../components/channels/ChannelIcon'; import CreateArticle from '../articles/CreateArticle'; import { PermissionsContext } from '../Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ box: { width: '100%', minHeight: '100%', @@ -66,7 +65,7 @@ const InjectAddArticles: FunctionComponent = ({ injectArticlesIds, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/common/injects/InjectAddChallenges.tsx b/openbas-front/src/admin/components/common/injects/InjectAddChallenges.tsx index 8059cd3eb4..ca2143bdf8 100644 --- a/openbas-front/src/admin/components/common/injects/InjectAddChallenges.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectAddChallenges.tsx @@ -13,16 +13,15 @@ import { ListItemIcon, ListItemText, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchChallenges } from '../../../../actions/Challenge'; import type { ChallengeHelper } from '../../../../actions/helper'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import SearchFilter from '../../../../components/SearchFilter'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Challenge } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -33,7 +32,7 @@ import CreateChallenge from '../../components/challenges/CreateChallenge'; import { PermissionsContext } from '../Context'; import TagsFilter from '../filters/TagsFilter'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ box: { width: '100%', minHeight: '100%', @@ -64,7 +63,7 @@ const InjectAddChallenges: FunctionComponent = ({ injectChallengesIds, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/common/injects/InjectAddTeams.tsx b/openbas-front/src/admin/components/common/injects/InjectAddTeams.tsx index dcb4f98750..045c67c42a 100644 --- a/openbas-front/src/admin/components/common/injects/InjectAddTeams.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectAddTeams.tsx @@ -1,7 +1,7 @@ import { ControlPointOutlined, GroupsOutlined } from '@mui/icons-material'; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useEffect, useMemo, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { findTeams } from '../../../../actions/teams/team-actions'; import PaginationComponentV2 from '../../../../components/common/queryable/pagination/PaginationComponentV2'; @@ -11,12 +11,11 @@ import SelectList, { SelectListElements } from '../../../../components/common/Se import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import ItemTags from '../../../../components/ItemTags'; -import type { Theme } from '../../../../components/Theme'; import type { TeamOutput } from '../../../../utils/api-types'; import CreateTeam from '../../components/teams/CreateTeam'; import { PermissionsContext, TeamContext } from '../Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -39,7 +38,7 @@ const InjectAddTeams: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { permissions } = useContext(PermissionsContext); const { searchTeams } = useContext(TeamContext); diff --git a/openbas-front/src/admin/components/common/injects/InjectChainsForm.tsx b/openbas-front/src/admin/components/common/injects/InjectChainsForm.tsx index a812fd0f9c..bdbfdfa5bb 100644 --- a/openbas-front/src/admin/components/common/injects/InjectChainsForm.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectChainsForm.tsx @@ -14,11 +14,9 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; -import { Value } from 'classnames'; import { FormApi } from 'final-form'; import { ReactElement, ReactNode, useEffect, useState } from 'react'; -import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { ConditionElement, ConditionType, Content, ConvertedContentType, Dependency, InjectOutputType } from '../../../../actions/injects/Inject'; import type { Element } from '../../../../components/common/chips/ClickableChip'; @@ -28,7 +26,7 @@ import { useFormatter } from '../../../../components/i18n'; import type { Inject, InjectDependency, InjectDependencyCondition, InjectOutput } from '../../../../utils/api-types'; import { capitalize } from '../../../../utils/String'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'inline-flex', alignItems: 'center', @@ -50,7 +48,7 @@ interface Props { } const InjectForm: React.FC = ({ values, form, injects }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // List of parents @@ -167,7 +165,7 @@ const InjectForm: React.FC = ({ values, form, injects }) => { * @param _event the event * @param parent the parent key */ - const handleChangeParent = (_event: SelectChangeEvent, parent: ReactNode) => { + const handleChangeParent = (_event: SelectChangeEvent, parent: ReactNode) => { const rx = /\.\$select-parent-(.*)-inject-(.*)/g; if (!parent) return; let key = ''; diff --git a/openbas-front/src/admin/components/common/injects/InjectDistributionByTeam.tsx b/openbas-front/src/admin/components/common/injects/InjectDistributionByTeam.tsx index 36337cac3f..0601236849 100644 --- a/openbas-front/src/admin/components/common/injects/InjectDistributionByTeam.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectDistributionByTeam.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import { fetchExerciseTeams } from '../../../../actions/Exercise'; import type { TeamsHelper } from '../../../../actions/teams/team-helper'; import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Exercise, Team } from '../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../utils/Charts'; @@ -25,7 +24,7 @@ const InjectDistributionByTeam: FunctionComponent = ({ // Standard hooks const { t } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { teams } = useHelper((helper: TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/common/injects/InjectDistributionByType.tsx b/openbas-front/src/admin/components/common/injects/InjectDistributionByType.tsx index 6d9e71dd71..07dd815586 100644 --- a/openbas-front/src/admin/components/common/injects/InjectDistributionByType.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectDistributionByType.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -9,7 +9,6 @@ import type { InjectStore } from '../../../../actions/injects/Inject'; import type { InjectHelper } from '../../../../actions/injects/inject-helper'; import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Exercise, InjectExpectation } from '../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../utils/Charts'; @@ -26,7 +25,7 @@ const InjectDistributionByType: FunctionComponent = ({ // Standard hooks const { t, tPick } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injects } = useHelper((helper: InjectHelper & InjectorContractHelper) => ({ diff --git a/openbas-front/src/admin/components/common/injects/InjectPopover.tsx b/openbas-front/src/admin/components/common/injects/InjectPopover.tsx index a17da52935..149c2c2905 100644 --- a/openbas-front/src/admin/components/common/injects/InjectPopover.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectPopover.tsx @@ -1,5 +1,5 @@ import { MoreVert } from '@mui/icons-material'; -import { Button, Dialog, DialogActions, DialogContent, DialogContentText, IconButton, Menu, MenuItem, Table, TableBody, TableCell, TableRow } from '@mui/material'; +import { Button, Dialog, DialogActions, DialogContent, DialogContentText, IconButton, Menu, MenuItem } from '@mui/material'; import { FunctionComponent, useContext, useState } from 'react'; import * as React from 'react'; import { Link } from 'react-router'; @@ -13,7 +13,7 @@ import DialogTest from '../../../../components/common/DialogTest'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import { useHelper } from '../../../../store'; -import type { Inject, InjectStatus, InjectStatusExecution, InjectTestStatus } from '../../../../utils/api-types'; +import type { Inject, InjectStatus, InjectTestStatusOutput } from '../../../../utils/api-types'; import { MESSAGING$ } from '../../../../utils/Environment'; import { useAppDispatch } from '../../../../utils/hooks'; import { InjectContext, PermissionsContext } from '../Context'; @@ -72,9 +72,7 @@ const InjectPopover: FunctionComponent = ({ const [openEnable, setOpenEnable] = useState(false); const [openDisable, setOpenDisable] = useState(false); const [openDone, setOpenDone] = useState(false); - const [openResult, setOpenResult] = useState(false); const [openTrigger, setOpenTrigger] = useState(false); - const [injectResult, setInjectResult] = useState(null); const [anchorEl, setAnchorEl] = useState(null); const isExercise = useHelper((helper: ExercisesHelper) => helper.getExercisesMap()[exerciseOrScenarioId!] !== undefined); @@ -119,11 +117,6 @@ const InjectPopover: FunctionComponent = ({ }); }; - const handleCloseResult = () => { - setOpenResult(false); - setInjectResult(null); - }; - const handleOpenTest = () => { setOpenTest(true); handlePopoverClose(); @@ -131,7 +124,7 @@ const InjectPopover: FunctionComponent = ({ const handleCloseTest = () => setOpenTest(false); const submitTest = () => { - testInject(inject.inject_id).then((result: { data: InjectTestStatus }) => { + testInject(inject.inject_id).then((result: { data: InjectTestStatusOutput }) => { if (isExercise) { MESSAGING$.notifySuccess(t('Inject test has been sent, you can view test logs details on {itsDedicatedPage}.', { itsDedicatedPage: {t('its dedicated page')}, @@ -399,67 +392,6 @@ const InjectPopover: FunctionComponent = ({ - - - {/* TODO: selectable={false} */} - - {/* TODO: displayRowCheckbox={false} */} - - {injectResult && Object.entries(injectResult).map( - ([key, value]) => { - if (key === 'status_traces') { - return ( - - {key} - - {/* TODO: selectable={false} */} -
- {/* TODO: displayRowCheckbox={false} */} - - <> - {value?.filter((trace: InjectStatusExecution) => !!trace.execution_message) - .map((trace: InjectStatusExecution) => ( - - - {trace.execution_message} - - - {trace.execution_status} - - {trace.execution_time} - - ))} - - -
- - - ); - } - return ( - - {key} - {value} - - ); - }, - )} - - -
- - - -
); }; diff --git a/openbas-front/src/admin/components/common/injects/InjectStatusDetails.js b/openbas-front/src/admin/components/common/injects/InjectStatusDetails.js deleted file mode 100644 index 3e90c382f2..0000000000 --- a/openbas-front/src/admin/components/common/injects/InjectStatusDetails.js +++ /dev/null @@ -1,103 +0,0 @@ -import { PreviewOutlined } from '@mui/icons-material'; -import { Button, Dialog, DialogActions, DialogContent, IconButton, Table, TableBody, TableCell, TableRow } from '@mui/material'; -import * as PropTypes from 'prop-types'; -import * as R from 'ramda'; -import { Component } from 'react'; - -import Transition from '../../../../components/common/Transition'; -import inject18n from '../../../../components/i18n'; - -class InjectStatusDetails extends Component { - constructor(props) { - super(props); - this.state = { open: false }; - } - - handleOpen() { - this.setState({ open: true }); - } - - handleClose() { - this.setState({ open: false }); - } - - render() { - const { t, status } = this.props; - return ( -
- - - - {status && ( - - - - - {Object.entries(status).map( - ([key, value]) => { - if (key === 'status_traces') { - return ( - - {key} - -
- - {value.filter(trace => !!trace.execution_message) - .map(trace => ( - - - {trace.execution_message} - - - {trace.execution_status} - - {trace.execution_time} - - ))} - -
- - - ); - } - return ( - - {key} - {value} - - ); - }, - )} - - -
- - - -
- )} -
- ); - } -} - -InjectStatusDetails.propTypes = { - classes: PropTypes.object, - t: PropTypes.func, - status: PropTypes.object, -}; - -export default R.compose(inject18n)(InjectStatusDetails); diff --git a/openbas-front/src/admin/components/common/injects/InjectorContract.js b/openbas-front/src/admin/components/common/injects/InjectorContract.js index bc5054f70a..710a5b3cfe 100644 --- a/openbas-front/src/admin/components/common/injects/InjectorContract.js +++ b/openbas-front/src/admin/components/common/injects/InjectorContract.js @@ -1,8 +1,8 @@ import { Chip, Tooltip } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import inject18n from '../../../../components/i18n'; @@ -50,4 +50,4 @@ InjectorContract.propTypes = { deleted: PropTypes.bool, }; -export default R.compose(inject18n, withStyles(styles))(InjectorContract); +export default R.compose(inject18n, Component => withStyles(Component, styles))(InjectorContract); diff --git a/openbas-front/src/admin/components/common/injects/Injects.tsx b/openbas-front/src/admin/components/common/injects/Injects.tsx index a3627765f9..3be59604cc 100644 --- a/openbas-front/src/admin/components/common/injects/Injects.tsx +++ b/openbas-front/src/admin/components/common/injects/Injects.tsx @@ -1,9 +1,9 @@ import { Checkbox, Chip, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { CSSProperties, FunctionComponent, useContext, useMemo, useState } from 'react'; import * as React from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { InjectorContractConvertedContent, InjectOutputType, InjectStore } from '../../../../actions/injects/Inject'; import ChainedTimeline from '../../../../components/ChainedTimeline'; @@ -24,7 +24,7 @@ import type { FilterGroup, Inject, InjectBulkUpdateOperation, - InjectTestStatus, + InjectTestStatusOutput, Team, Variable, } from '../../../../utils/api-types'; @@ -41,7 +41,7 @@ import InjectPopover from './InjectPopover'; import InjectsListButtons from './InjectsListButtons'; import UpdateInject from './UpdateInject'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ disabled: { opacity: 0.38, pointerEvents: 'none', @@ -124,7 +124,7 @@ const Injects: FunctionComponent = ({ teamsUsers, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, tPick } = useFormatter(); const injectContext = useContext(InjectContext); const viewModeContext = useContext(ViewModeContext); @@ -461,7 +461,7 @@ const Injects: FunctionComponent = ({ inject_ids_to_process: selectAll ? undefined : testIds, inject_ids_to_ignore: ignoreIds, simulation_or_scenario_id: exerciseOrScenarioId, - }).then((result: { uri: string; data: InjectTestStatus[] }) => { + }).then((result: { uri: string; data: InjectTestStatusOutput[] }) => { if (numberOfSelectedElements === 1) { MESSAGING$.notifySuccess(t('Inject test has been sent, you can view test logs details on {itsDedicatedPage}.', { itsDedicatedPage: {t('its dedicated page')}, diff --git a/openbas-front/src/admin/components/common/injects/InjectsDistribution.tsx b/openbas-front/src/admin/components/common/injects/InjectsDistribution.tsx index 5ffcdb0872..91197be87b 100644 --- a/openbas-front/src/admin/components/common/injects/InjectsDistribution.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectsDistribution.tsx @@ -1,10 +1,9 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import type { Team } from '../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../utils/Charts'; @@ -21,7 +20,7 @@ const InjectsDistribution: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme = useTheme(); + const theme = useTheme(); return ( <> diff --git a/openbas-front/src/admin/components/common/injects/InjectsListButtons.tsx b/openbas-front/src/admin/components/common/injects/InjectsListButtons.tsx index 164642b2da..c5796ec83f 100644 --- a/openbas-front/src/admin/components/common/injects/InjectsListButtons.tsx +++ b/openbas-front/src/admin/components/common/injects/InjectsListButtons.tsx @@ -1,7 +1,7 @@ import { BarChartOutlined, ReorderOutlined, ViewTimelineOutlined } from '@mui/icons-material'; import { ToggleButton, ToggleButtonGroup, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { TagHelper } from '../../../../actions/helper'; import type { InjectOutputType } from '../../../../actions/injects/Inject'; @@ -13,7 +13,7 @@ import useExportToXLS from '../../../../utils/hooks/useExportToXLS'; import { InjectContext, ViewModeContext } from '../Context'; import ImportUploaderInjectFromXls from './ImportUploaderInjectFromXls'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', justifyContent: 'flex-end', @@ -38,7 +38,7 @@ const InjectsListButtons: FunctionComponent = ({ isAtLeastOneValidInject, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const injectContext = useContext(InjectContext); diff --git a/openbas-front/src/admin/components/common/injects/ResponsePie.tsx b/openbas-front/src/admin/components/common/injects/ResponsePie.tsx index 2f5520e6ba..5ac43348b5 100644 --- a/openbas-front/src/admin/components/common/injects/ResponsePie.tsx +++ b/openbas-front/src/admin/components/common/injects/ResponsePie.tsx @@ -1,12 +1,11 @@ import { InfoOutlined, SensorOccupiedOutlined, ShieldOutlined, TrackChangesOutlined } from '@mui/icons-material'; -import { Box, Button, Grid2 as Grid } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { Box, Button, Grid2 as Grid, Theme } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent, useCallback, useMemo } from 'react'; import Chart from 'react-apexcharts'; import { Link } from 'react-router'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import type { ExpectationResultsByType, ResultDistribution } from '../../../../utils/api-types'; import { donutChartOptions } from '../../../../utils/Charts'; @@ -49,7 +48,7 @@ const ResponsePie: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme = useTheme(); + const theme = useTheme(); const prevention = expectationResultsByTypes?.find(e => e.type === 'PREVENTION'); const detection = expectationResultsByTypes?.find(e => e.type === 'DETECTION'); diff --git a/openbas-front/src/admin/components/common/injects/UpdateInjectDetails.js b/openbas-front/src/admin/components/common/injects/UpdateInjectDetails.js index 3bc131a971..35b55d7f49 100644 --- a/openbas-front/src/admin/components/common/injects/UpdateInjectDetails.js +++ b/openbas-front/src/admin/components/common/injects/UpdateInjectDetails.js @@ -1,10 +1,10 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { ArrowDropDownOutlined, ArrowDropUpOutlined, HelpOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { useFormatter } from '../../../../components/i18n'; @@ -16,7 +16,7 @@ import { PermissionsContext } from '../Context'; import InjectDefinition from './form/InjectDefinition'; import InjectForm from './form/InjectForm'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ details: { marginTop: 20, }, @@ -58,7 +58,7 @@ const UpdateInjectDetails = ({ ...props }) => { const { t, tPick } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { permissions } = useContext(PermissionsContext); const [openDetails, setOpenDetails] = useState(true); const [injectDetailsState, setInjectDetailsState] = useState({}); diff --git a/openbas-front/src/admin/components/common/injects/UpdateInjectLogicalChains.tsx b/openbas-front/src/admin/components/common/injects/UpdateInjectLogicalChains.tsx index 76e862a17a..a7e99174a4 100644 --- a/openbas-front/src/admin/components/common/injects/UpdateInjectLogicalChains.tsx +++ b/openbas-front/src/admin/components/common/injects/UpdateInjectLogicalChains.tsx @@ -1,20 +1,19 @@ import { HelpOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import arrayMutators from 'final-form-arrays'; import * as React from 'react'; import { Form } from 'react-final-form'; +import { makeStyles } from 'tss-react/mui'; import type { InjectOutputType } from '../../../../actions/injects/Inject'; import type { InjectHelper } from '../../../../actions/injects/inject-helper'; import { useFormatter } from '../../../../components/i18n'; import PlatformIcon from '../../../../components/PlatformIcon'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Inject, InjectDependency } from '../../../../utils/api-types'; import InjectChainsForm from './InjectChainsForm'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ injectorContract: { margin: '10px 0 20px 0', width: '100%', @@ -39,7 +38,7 @@ interface Props { const UpdateInjectLogicalChains: React.FC = ({ inject, handleClose, onUpdateInject, injects }) => { const { t, tPick } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { injectsMap } = useHelper((helper: InjectHelper) => ({ injectsMap: helper.getInjectsMap(), diff --git a/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormCreate.tsx b/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormCreate.tsx index aaa892ded5..48b1709a3c 100644 --- a/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormCreate.tsx +++ b/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormCreate.tsx @@ -1,12 +1,11 @@ import { Alert, Button, InputLabel, MenuItem, Select as MUISelect, TextField as MuiTextField, TextField, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, SyntheticEvent, useEffect } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { LoggedHelper } from '../../../../../actions/helper'; import { useFormatter } from '../../../../../components/i18n'; import ScaleBar from '../../../../../components/scalebar/ScaleBar'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { PlatformSettings } from '../../../../../utils/api-types'; import { splitDuration } from '../../../../../utils/Time'; @@ -16,7 +15,7 @@ import { isTechnicalExpectation } from './ExpectationUtils'; import ExpectationGroupField from './field/ExpectationGroupField'; import useExpectationExpirationTime from './useExpectationExpirationTime'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ marginTop_2: { marginTop: theme.spacing(2), }, @@ -55,7 +54,7 @@ const ExpectationFormCreate: FunctionComponent = ({ handleClose, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { settings }: { settings: PlatformSettings } = useHelper((helper: LoggedHelper) => ({ settings: helper.getPlatformSettings(), diff --git a/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormUpdate.tsx b/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormUpdate.tsx index 634d51521f..895fdf2ca3 100644 --- a/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormUpdate.tsx +++ b/openbas-front/src/admin/components/common/injects/expectations/ExpectationFormUpdate.tsx @@ -1,18 +1,17 @@ import { Alert, Button, InputLabel, MenuItem, Select as MUISelect, TextField as MuiTextField, TextField, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, SyntheticEvent } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../components/i18n'; import ScaleBar from '../../../../../components/scalebar/ScaleBar'; -import type { Theme } from '../../../../../components/Theme'; import { splitDuration } from '../../../../../utils/Time'; import { ExpectationInput, ExpectationInputForm } from './Expectation'; import { formProps, infoMessage } from './ExpectationFormUtils'; import { isTechnicalExpectation } from './ExpectationUtils'; import ExpectationGroupField from './field/ExpectationGroupField'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ marginTop_2: { marginTop: theme.spacing(2), }, @@ -51,7 +50,7 @@ const ExpectationFormUpdate: FunctionComponent = ({ initialValues, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const expirationTime = splitDuration(initialValues.expectation_expiration_time || 0); const formInitialValues: ExpectationInputForm = { diff --git a/openbas-front/src/admin/components/common/injects/expectations/InjectAddExpectation.tsx b/openbas-front/src/admin/components/common/injects/expectations/InjectAddExpectation.tsx index e6adaed4ba..378d9920ec 100644 --- a/openbas-front/src/admin/components/common/injects/expectations/InjectAddExpectation.tsx +++ b/openbas-front/src/admin/components/common/injects/expectations/InjectAddExpectation.tsx @@ -1,16 +1,15 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import Dialog from '../../../../../components/common/Dialog'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { PermissionsContext } from '../../Context'; import type { ExpectationInput, ExpectationInputForm } from './Expectation'; import ExpectationFormCreate from './ExpectationFormCreate'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -32,7 +31,7 @@ const InjectAddExpectation: FunctionComponent = ({ handleAddExpectation, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/common/injects/expectations/InjectExpectations.tsx b/openbas-front/src/admin/components/common/injects/expectations/InjectExpectations.tsx index 9fba82b471..ee6af82bf6 100644 --- a/openbas-front/src/admin/components/common/injects/expectations/InjectExpectations.tsx +++ b/openbas-front/src/admin/components/common/injects/expectations/InjectExpectations.tsx @@ -1,17 +1,16 @@ import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { truncate } from '../../../../../utils/String'; import type { ExpectationInput } from './Expectation'; import ExpectationPopover from './ExpectationPopover'; import { isAutomatic, typeIcon } from './ExpectationUtils'; import InjectAddExpectation from './InjectAddExpectation'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -37,7 +36,7 @@ const InjectExpectations: FunctionComponent = ({ handleExpectations, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [expectations, setExpectations] = useState(expectationDatas ?? []); diff --git a/openbas-front/src/admin/components/common/injects/expectations/field/ExpectationGroupField.tsx b/openbas-front/src/admin/components/common/injects/expectations/field/ExpectationGroupField.tsx index edd819887b..4a94f211ec 100644 --- a/openbas-front/src/admin/components/common/injects/expectations/field/ExpectationGroupField.tsx +++ b/openbas-front/src/admin/components/common/injects/expectations/field/ExpectationGroupField.tsx @@ -1,15 +1,14 @@ import { InfoOutlined } from '@mui/icons-material'; import { FormControlLabel, FormLabel, Radio, RadioGroup, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; import { FunctionComponent } from 'react'; import { Control, Controller } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import { ExpectationInputForm } from '../Expectation'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ marginTop_2: { marginTop: theme.spacing(2), }, @@ -30,7 +29,7 @@ const ExpectationGroupField: FunctionComponent = ({ isTechnicalExpectation, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); return ( this.props.setInjectDetailsState(this.state)); + async refreshEndpoints(assetIds) { + const result = await findEndpoints(assetIds); + return result.data; } - handleRemoveAsset(assetId) { + async setAssetIdsState(assetIds) { this.setState({ - assetIds: this.state.assetIds.filter(a => a !== assetId), + assetIds: assetIds, }, () => this.props.setInjectDetailsState(this.state)); + + // also force update resolved endpoints at the cost of a backend call + this.setState({ endpoints: await this.refreshEndpoints(assetIds) }); + } + + async handleAddAssets(assetIds) { + await this.setAssetIdsState(assetIds); + } + + async handleRemoveAsset(assetId) { + await this.setAssetIdsState(this.state.assetIds.filter(a => a !== assetId)); } // Asset Groups @@ -473,6 +486,7 @@ class InjectDefinition extends Component { allTeams, teamsIds, assetIds, + endpoints, assetGroupIds, documents, expectations, @@ -650,7 +664,7 @@ class InjectDefinition extends Component { {t('Targeted assets')} withStyles(Component, styles), )(InjectDefinition); diff --git a/openbas-front/src/admin/components/common/injects/form/InjectForm.js b/openbas-front/src/admin/components/common/injects/form/InjectForm.js index 1ff1ed678a..0271db0cd0 100644 --- a/openbas-front/src/admin/components/common/injects/form/InjectForm.js +++ b/openbas-front/src/admin/components/common/injects/form/InjectForm.js @@ -1,8 +1,8 @@ -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { Controller } from 'react-hook-form'; +import { withStyles } from 'tss-react/mui'; import TagField from '../../../../../components/fields/TagField'; import TextField from '../../../../../components/fields/TextField'; @@ -146,4 +146,4 @@ InjectForm.propTypes = { t: PropTypes.func, }; -export default R.compose(inject18n, withStyles(styles))(InjectForm); +export default R.compose(inject18n, Component => withStyles(Component, styles))(InjectForm); diff --git a/openbas-front/src/admin/components/common/injects/status/InjectStatus.tsx b/openbas-front/src/admin/components/common/injects/status/InjectStatus.tsx new file mode 100644 index 0000000000..4bcea2daad --- /dev/null +++ b/openbas-front/src/admin/components/common/injects/status/InjectStatus.tsx @@ -0,0 +1,62 @@ +import { Paper, Typography } from '@mui/material'; + +import { useFormatter } from '../../../../../components/i18n'; +import ItemStatus from '../../../../../components/ItemStatus'; +import { + AgentStatusOutput, + EndpointOutput, InjectStatusOutput, +} from '../../../../../utils/api-types'; +import EndpointTraces from './traces/EndpointTraces'; +import ExecutionTime from './traces/ExecutionTime'; +import TraceMessage from './traces/TraceMessage'; + +interface Props { + injectStatus?: InjectStatusOutput | null; + endpointsMap?: Map; +} + +const InjectStatus = ({ injectStatus = null, endpointsMap = new Map() }: Props) => { + const { t } = useFormatter(); + const orderedTracesByAsset = new Map(); + + (injectStatus?.status_traces_by_agent || []).forEach((t) => { + if (!orderedTracesByAsset.has(t.asset_id)) { + orderedTracesByAsset.set(t.asset_id, []); + } + orderedTracesByAsset.get(t.asset_id)!.push(t); + }); + + return ( + <> + {t('Execution logs')} + {injectStatus ? ( + + + {t('Execution status')} + + {injectStatus.status_name + && ( + + )} + + + {t('Traces')} + + {(injectStatus.status_main_traces || []).length > 0 && } + {Array.from(orderedTracesByAsset.entries()).map(([assetId, tracesByAgent]) => ( + + ))} + + ) : ( + + {t('No data available')} + + )} + + ); +}; +export default InjectStatus; diff --git a/openbas-front/src/admin/components/common/injects/status/traces/AgentTraces.tsx b/openbas-front/src/admin/components/common/injects/status/traces/AgentTraces.tsx new file mode 100644 index 0000000000..5119b6d295 --- /dev/null +++ b/openbas-front/src/admin/components/common/injects/status/traces/AgentTraces.tsx @@ -0,0 +1,81 @@ +import { ArrowDropDownSharp, ArrowRightSharp } from '@mui/icons-material'; +import { Typography } from '@mui/material'; +import { useState } from 'react'; + +import { useFormatter } from '../../../../../../components/i18n'; +import ItemStatus from '../../../../../../components/ItemStatus'; +import { AgentStatusOutput, ExecutionTracesOutput } from '../../../../../../utils/api-types'; +import ExecutionTime from './ExecutionTime'; +import TraceMessage from './TraceMessage'; + +interface Props { + agentStatus: AgentStatusOutput; +} + +const AgentTraces = ({ agentStatus }: Props) => { + const [isExpanded, setIsExpanded] = useState(false); + const { t } = useFormatter(); + + const toggleExpand = () => { + setIsExpanded(prevState => !prevState); + }; + + const tracesByAction: { action: string; traces: ExecutionTracesOutput[] }[] = []; + (agentStatus.agent_traces || []) + .sort((a, b) => new Date(a.execution_time).getTime() - new Date(b.execution_time).getTime()) + .forEach((trace, index) => { + if (index > 0 && trace.execution_action === tracesByAction[tracesByAction?.length - 1]?.action) { + tracesByAction[tracesByAction?.length - 1].traces.push(trace); + } else { + tracesByAction.push({ action: trace.execution_action, traces: [trace] }); + } + }); + + return ( + <> +
+ {isExpanded ? : } + + {agentStatus.agent_name} + + +
+ {isExpanded && ( +
+ +
+ {t('Executor')} + {agentStatus.agent_executor_type} + {t(agentStatus.agent_executor_name)} +
+ + {t('Traces :')} + + {(tracesByAction || []) + .map((traceByAction, index) => ( +
+ + {t(traceByAction.action)} + + +
+ ))} +
+ )} + + ); +}; +export default AgentTraces; diff --git a/openbas-front/src/admin/components/common/injects/status/traces/EndpointTraces.tsx b/openbas-front/src/admin/components/common/injects/status/traces/EndpointTraces.tsx new file mode 100644 index 0000000000..9d7a1831dd --- /dev/null +++ b/openbas-front/src/admin/components/common/injects/status/traces/EndpointTraces.tsx @@ -0,0 +1,37 @@ +import { Typography } from '@mui/material'; + +import { useFormatter } from '../../../../../../components/i18n'; +import PlatformIcon from '../../../../../../components/PlatformIcon'; +import { AgentStatusOutput, EndpointOutput } from '../../../../../../utils/api-types'; +import AgentTraces from './AgentTraces'; + +interface Props { + endpoint: EndpointOutput; + tracesByAgent: AgentStatusOutput[]; +} + +const EndpointTraces = ({ endpoint, tracesByAgent }: Props) => { + const { t } = useFormatter(); + + return ( +
+
+ {t('Name')} + {endpoint.asset_name} +
+
+ {t('Type')} + {t('Endpoint').toUpperCase()} +
+
+ {t('Platform')} + + {t(endpoint.endpoint_platform)} +
+
+ {tracesByAgent.map(t => )} +
+
+ ); +}; +export default EndpointTraces; diff --git a/openbas-front/src/admin/components/common/injects/status/traces/ExecutionTime.tsx b/openbas-front/src/admin/components/common/injects/status/traces/ExecutionTime.tsx new file mode 100644 index 0000000000..eaed857746 --- /dev/null +++ b/openbas-front/src/admin/components/common/injects/status/traces/ExecutionTime.tsx @@ -0,0 +1,36 @@ +import { Typography } from '@mui/material'; +import { CSSProperties } from 'react'; + +import { useFormatter } from '../../../../../../components/i18n'; + +interface Props { + startDate: string | null; + endDate: string | null; + style?: CSSProperties; +} + +const ExecutionTime = ({ startDate, endDate, style = {} }: Props) => { + const { t } = useFormatter(); + const executionTimeInfo: { label: string; value: string | null }[] = [ + { label: 'Start date', value: startDate }, + { label: 'End date', value: endDate }, + { label: 'Execution Time', value: startDate && endDate + ? `${(new Date(endDate).getTime() - new Date(startDate).getTime()) / 1000} s` + : '', + }, + ]; + + return ( +
+ {executionTimeInfo.map(info => ( +
+ {t(info.label)} + {info.value} +
+ ), + )} +
+ ); +}; + +export default ExecutionTime; diff --git a/openbas-front/src/admin/components/common/injects/status/traces/TraceMessage.tsx b/openbas-front/src/admin/components/common/injects/status/traces/TraceMessage.tsx new file mode 100644 index 0000000000..b1da559e64 --- /dev/null +++ b/openbas-front/src/admin/components/common/injects/status/traces/TraceMessage.tsx @@ -0,0 +1,26 @@ +import { ExecutionTracesOutput } from '../../../../../../utils/api-types'; + +interface Props { + traces: ExecutionTracesOutput[]; +} + +const TraceMessage = ({ traces }: Props) => { + return ( +
+      {traces.length > 1 ? (
+        
    + {traces.sort((a, b) => new Date(a.execution_time).getTime() - new Date(b.execution_time).getTime()).map((tr, index) => ( +
  • + {tr.execution_status} + {' '} + {tr.execution_message} +
  • + ))} +
+ ) : ( + traces.map(tr => `${tr.execution_status} ${tr.execution_message}`) + )} +
+ ); +}; +export default TraceMessage; diff --git a/openbas-front/src/admin/components/common/injects/teams/InjectTeamsList.tsx b/openbas-front/src/admin/components/common/injects/teams/InjectTeamsList.tsx index 0ed0f4ee2f..3d40c4eec3 100644 --- a/openbas-front/src/admin/components/common/injects/teams/InjectTeamsList.tsx +++ b/openbas-front/src/admin/components/common/injects/teams/InjectTeamsList.tsx @@ -1,17 +1,16 @@ import { GroupsOutlined } from '@mui/icons-material'; import { ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useContext, useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { findTeams } from '../../../../../actions/teams/team-actions'; import ItemTags from '../../../../../components/ItemTags'; -import type { Theme } from '../../../../../components/Theme'; import type { TeamOutput } from '../../../../../utils/api-types'; import TeamPopover from '../../../components/teams/TeamPopover'; import { PermissionsContext, TeamContext } from '../../Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -35,7 +34,7 @@ const InjectTeamsList: FunctionComponent = ({ handleRemoveTeam, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { permissions } = useContext(PermissionsContext); const { computeTeamUsersEnabled } = useContext(TeamContext); diff --git a/openbas-front/src/admin/components/common/injects/teams/utils.ts b/openbas-front/src/admin/components/common/injects/teams/utils.ts index 215019a7ce..9106fd07c7 100644 --- a/openbas-front/src/admin/components/common/injects/teams/utils.ts +++ b/openbas-front/src/admin/components/common/injects/teams/utils.ts @@ -1,13 +1,12 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; -import type { Theme } from '../../../../../components/Theme'; import type { Team } from '../../../../../utils/api-types'; import { colors } from '../../../../../utils/Charts'; // eslint-disable-next-line import/prefer-default-export export const getTeamsColors: (teams: Team[]) => Record = (teams: Team[]) => { - const theme = useTheme(); + const theme = useTheme(); const mapIndexed = R.addIndex(R.map); return R.pipe( diff --git a/openbas-front/src/admin/components/common/matrix/AttackPatternBox.tsx b/openbas-front/src/admin/components/common/matrix/AttackPatternBox.tsx index 2b591dfc6a..8c770385f4 100644 --- a/openbas-front/src/admin/components/common/matrix/AttackPatternBox.tsx +++ b/openbas-front/src/admin/components/common/matrix/AttackPatternBox.tsx @@ -1,15 +1,15 @@ import { Button, ListItemText, Menu, MenuItem, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { FunctionComponent, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../../../../components/Theme'; import type { AttackPattern, ExpectationResultsByType, InjectExpectationResultsByAttackPattern, InjectExpectationResultsByType } from '../../../../utils/api-types'; import { hexToRGB } from '../../../../utils/Colors'; import AtomicTestingResult from '../../atomic_testings/atomic_testing/AtomicTestingResult'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ button: { whiteSpace: 'nowrap', width: '100%', @@ -52,8 +52,8 @@ const AttackPatternBox: FunctionComponent = ({ dummy, }) => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const [open, setOpen] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const results: InjectExpectationResultsByType[] = injectResult?.inject_expectation_results ?? []; diff --git a/openbas-front/src/admin/components/common/matrix/KillChainPhaseColumn.tsx b/openbas-front/src/admin/components/common/matrix/KillChainPhaseColumn.tsx index 720b294b4d..e8085717e0 100644 --- a/openbas-front/src/admin/components/common/matrix/KillChainPhaseColumn.tsx +++ b/openbas-front/src/admin/components/common/matrix/KillChainPhaseColumn.tsx @@ -1,11 +1,11 @@ -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../../../../components/Theme'; import type { AttackPattern, InjectExpectationResultsByAttackPattern, KillChainPhase } from '../../../../utils/api-types'; import AttackPatternBox from './AttackPatternBox'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ column: { display: 'flex', flexDirection: 'column', @@ -29,8 +29,8 @@ const KillChainPhaseColumn: FunctionComponent = ({ dummy, }) => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); // Attack Pattern const sortAttackPattern = (attackPattern1: AttackPattern, attackPattern2: AttackPattern) => { if (attackPattern1.attack_pattern_name < attackPattern2.attack_pattern_name) { diff --git a/openbas-front/src/admin/components/common/matrix/MitreMatrix.tsx b/openbas-front/src/admin/components/common/matrix/MitreMatrix.tsx index b913cc3ef6..7dfec86d72 100644 --- a/openbas-front/src/admin/components/common/matrix/MitreMatrix.tsx +++ b/openbas-front/src/admin/components/common/matrix/MitreMatrix.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AttackPatternHelper } from '../../../../actions/attack_patterns/attackpattern-helper'; import type { KillChainPhaseHelper } from '../../../../actions/kill_chain_phases/killchainphase-helper'; @@ -9,7 +9,7 @@ import type { AttackPattern, InjectExpectationResultsByAttackPattern, KillChainP import KillChainPhaseColumn from './KillChainPhaseColumn'; import MitreMatrixDummy from './MitreMatrixDummy'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { width: '100%', display: 'flex', @@ -30,7 +30,7 @@ const MitreMatrix: FunctionComponent = ({ injectResults, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { attackPatternMap, killChainPhaseMap }: { attackPatternMap: Record; diff --git a/openbas-front/src/admin/components/common/matrix/MitreMatrixDummy.tsx b/openbas-front/src/admin/components/common/matrix/MitreMatrixDummy.tsx index da40e08ff6..02ba03c08e 100644 --- a/openbas-front/src/admin/components/common/matrix/MitreMatrixDummy.tsx +++ b/openbas-front/src/admin/components/common/matrix/MitreMatrixDummy.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AttackPatternHelper } from '../../../../actions/attack_patterns/attackpattern-helper'; import type { KillChainPhaseHelper } from '../../../../actions/kill_chain_phases/killchainphase-helper'; @@ -9,7 +9,7 @@ import type { AttackPattern, KillChainPhase } from '../../../../utils/api-types' import { random } from '../../../../utils/Number'; import KillChainPhaseColumn from './KillChainPhaseColumn'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { width: '100%', display: 'flex', @@ -23,7 +23,7 @@ const useStyles = makeStyles(() => ({ const MitreMatrixDummy: FunctionComponent = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { attackPatterns, killChainPhaseMap }: { attackPatterns: AttackPattern[]; diff --git a/openbas-front/src/admin/components/common/simulate/EmailParametersForm.tsx b/openbas-front/src/admin/components/common/simulate/EmailParametersForm.tsx index 27029417ec..b90e7e4145 100644 --- a/openbas-front/src/admin/components/common/simulate/EmailParametersForm.tsx +++ b/openbas-front/src/admin/components/common/simulate/EmailParametersForm.tsx @@ -1,15 +1,15 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Alert, AlertTitle, Autocomplete, Button, Chip, TextField as MuiTextField, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import * as React from 'react'; import { Controller, SubmitHandler, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { useFormatter } from '../../../../components/i18n'; import { zodImplement } from '../../../../utils/Zod'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ buttons: { display: 'flex', justifyContent: 'end', @@ -46,7 +46,7 @@ const EmailParametersForm: React.FC = ({ disabled, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [inputValue, setInputValue] = useState(''); diff --git a/openbas-front/src/admin/components/common/simulate/PaperMetric.tsx b/openbas-front/src/admin/components/common/simulate/PaperMetric.tsx index 3f5b3c96a4..ab057b82d0 100644 --- a/openbas-front/src/admin/components/common/simulate/PaperMetric.tsx +++ b/openbas-front/src/admin/components/common/simulate/PaperMetric.tsx @@ -1,13 +1,12 @@ import { Paper } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import ItemNumberDifference from '../../../../components/ItemNumberDifference'; -import type { Theme } from '../../../../components/Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ title: { textTransform: 'uppercase', fontSize: theme.typography.h4.fontSize, @@ -49,7 +48,7 @@ const PaperMetric: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const component = React.cloneElement(icon as React.ReactElement, { color: 'primary', style: { fontSize: 35, marginTop: 15 } }); return ( diff --git a/openbas-front/src/admin/components/common/tags/TagChip.tsx b/openbas-front/src/admin/components/common/tags/TagChip.tsx index 137321ef3f..1bdd84f146 100644 --- a/openbas-front/src/admin/components/common/tags/TagChip.tsx +++ b/openbas-front/src/admin/components/common/tags/TagChip.tsx @@ -1,11 +1,11 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { TagHelper } from '../../../../actions/helper'; import { useHelper } from '../../../../store'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ tag: { marginLeft: 5, }, @@ -23,7 +23,7 @@ const TagChip: FunctionComponent = ({ deleteTag, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const tag = useHelper((helper: TagHelper) => helper.getTag(tagId)); if (!tag) { diff --git a/openbas-front/src/admin/components/components/Index.tsx b/openbas-front/src/admin/components/components/Index.tsx index 387fd24868..cc9c0dd8c7 100644 --- a/openbas-front/src/admin/components/components/Index.tsx +++ b/openbas-front/src/admin/components/components/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy, Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../../../components/Error'; import Loader from '../../../components/Loader'; @@ -13,14 +13,14 @@ const Challenges = lazy(() => import('./challenges/Challenges')); const Lessons = lazy(() => import('./lessons/LessonsTemplates')); const LessonIndex = lazy(() => import('./lessons/Index')); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); return (
}> diff --git a/openbas-front/src/admin/components/components/challenges/ChallengeForm.js b/openbas-front/src/admin/components/components/challenges/ChallengeForm.js index 0e25aafa79..c152a73896 100644 --- a/openbas-front/src/admin/components/components/challenges/ChallengeForm.js +++ b/openbas-front/src/admin/components/components/challenges/ChallengeForm.js @@ -1,11 +1,11 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined, AttachmentOutlined, ControlPointOutlined, DeleteOutlined } from '@mui/icons-material'; import { Button, Grid, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, MenuItem, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import arrayMutators from 'final-form-arrays'; import { useState } from 'react'; import { Form } from 'react-final-form'; import { FieldArray } from 'react-final-form-arrays'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../../../actions/Document'; import { fetchExercises } from '../../../../actions/Exercise'; @@ -21,7 +21,7 @@ import useDataLoader from '../../../../utils/hooks/useDataLoader'; import DocumentPopover from '../documents/DocumentPopover'; import DocumentType from '../documents/DocumentType'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -97,7 +97,7 @@ const inlineStyles = { }; const ChallengeForm = (props) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useDispatch(); const { onSubmit, handleClose, initialValues, editing, documentsIds } = props; diff --git a/openbas-front/src/admin/components/components/challenges/Challenges.js b/openbas-front/src/admin/components/components/challenges/Challenges.js index 6619b67440..77441c9d76 100644 --- a/openbas-front/src/admin/components/components/challenges/Challenges.js +++ b/openbas-front/src/admin/components/components/challenges/Challenges.js @@ -1,9 +1,9 @@ import { RowingOutlined } from '@mui/icons-material'; import { Chip, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useDispatch } from 'react-redux'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchChallenges } from '../../../../actions/Challenge'; import { fetchDocuments } from '../../../../actions/Document'; @@ -19,7 +19,7 @@ import TagsFilter from '../../common/filters/TagsFilter'; import ChallengePopover from './ChallengePopover'; import CreateChallenge from './CreateChallenge'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ parameters: { marginTop: -10, display: 'flex', @@ -136,7 +136,7 @@ const inlineStyles = { const Challenges = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/components/challenges/CreateChallenge.js b/openbas-front/src/admin/components/components/challenges/CreateChallenge.js index 4a0b6f5803..edfb64304d 100644 --- a/openbas-front/src/admin/components/components/challenges/CreateChallenge.js +++ b/openbas-front/src/admin/components/components/challenges/CreateChallenge.js @@ -1,9 +1,9 @@ import { Add, ControlPointOutlined } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, Fab, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { addChallenge } from '../../../../actions/Challenge'; import Drawer from '../../../../components/common/Drawer'; @@ -11,7 +11,7 @@ import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; import ChallengeForm from './ChallengeForm'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ createButton: { position: 'fixed', bottom: 30, @@ -26,7 +26,7 @@ const useStyles = makeStyles(theme => ({ const CreateChallenge = (props) => { const { onCreate, inline } = props; - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/admin/components/components/channels/Channel.js b/openbas-front/src/admin/components/components/channels/Channel.js index 48c022c9b0..7d4058489a 100644 --- a/openbas-front/src/admin/components/components/channels/Channel.js +++ b/openbas-front/src/admin/components/components/channels/Channel.js @@ -1,8 +1,8 @@ import { Grid, Paper, Skeleton, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { updateChannel, updateChannelLogos } from '../../../../actions/channels/channel-action'; import { fetchDocuments } from '../../../../actions/Document'; @@ -15,7 +15,7 @@ import ChannelOverviewNewspaper from './ChannelOverviewNewspaper'; import ChannelOverviewTvChannel from './ChannelOverviewTvChannel'; import ChannelParametersForm from './ChannelParametersForm'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, paddingBottom: 40, @@ -27,7 +27,7 @@ const useStyles = makeStyles(() => ({ })); const Channel = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { channelId } = useParams(); const dispatch = useDispatch(); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/components/channels/ChannelHeader.js b/openbas-front/src/admin/components/components/channels/ChannelHeader.js index ea978fe979..e490ff4478 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelHeader.js +++ b/openbas-front/src/admin/components/components/channels/ChannelHeader.js @@ -1,11 +1,11 @@ import { Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { useHelper } from '../../../../store'; import ChannelPopover from './ChannelPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { width: '100%', }, @@ -16,7 +16,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelHeader = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { channelId } = useParams(); const { channel, userAdmin } = useHelper(helper => ({ channel: helper.getChannel(channelId), diff --git a/openbas-front/src/admin/components/components/channels/ChannelOverviewMicroblogging.js b/openbas-front/src/admin/components/components/channels/ChannelOverviewMicroblogging.js index 76c4859253..dd7528d2f3 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelOverviewMicroblogging.js +++ b/openbas-front/src/admin/components/components/channels/ChannelOverviewMicroblogging.js @@ -1,8 +1,9 @@ import { Card, CardHeader, Grid, Skeleton, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Fragment } from 'react'; +import { makeStyles } from 'tss-react/mui'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, paddingBottom: 50, @@ -14,7 +15,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelOverviewMicroblogging = ({ channel }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const isDark = theme.palette.mode === 'dark'; const logo = isDark ? channel.logoDark : channel.logoLight; diff --git a/openbas-front/src/admin/components/components/channels/ChannelOverviewNewspaper.js b/openbas-front/src/admin/components/components/channels/ChannelOverviewNewspaper.js index 7c4c7bc912..c351cabcb8 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelOverviewNewspaper.js +++ b/openbas-front/src/admin/components/components/channels/ChannelOverviewNewspaper.js @@ -1,8 +1,9 @@ import { Card, CardContent, CardHeader, Grid, Skeleton, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Fragment } from 'react'; +import { makeStyles } from 'tss-react/mui'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, paddingBottom: 50, @@ -14,7 +15,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelOverviewNewspaper = ({ channel }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const isDark = theme.palette.mode === 'dark'; const logo = isDark ? channel.logoDark : channel.logoLight; diff --git a/openbas-front/src/admin/components/components/channels/ChannelOverviewTvChannel.js b/openbas-front/src/admin/components/components/channels/ChannelOverviewTvChannel.js index 3140b1429d..467c116860 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelOverviewTvChannel.js +++ b/openbas-front/src/admin/components/components/channels/ChannelOverviewTvChannel.js @@ -1,7 +1,8 @@ import { Card, CardHeader, Grid, Skeleton, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; +import { makeStyles } from 'tss-react/mui'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, paddingBottom: 50, @@ -13,7 +14,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelOverviewTvChannel = ({ channel }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const isDark = theme.palette.mode === 'dark'; const logo = isDark ? channel.logoDark : channel.logoLight; diff --git a/openbas-front/src/admin/components/components/channels/ChannelPopover.tsx b/openbas-front/src/admin/components/components/channels/ChannelPopover.tsx index 0d7bcfcdd3..e2ce9af6d3 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelPopover.tsx +++ b/openbas-front/src/admin/components/components/channels/ChannelPopover.tsx @@ -1,9 +1,9 @@ import { MoreVert } from '@mui/icons-material'; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, Menu, MenuItem, PopoverProps } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import * as React from 'react'; import { useNavigate } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { deleteChannel, updateChannel } from '../../../../actions/channels/channel-action'; import Transition from '../../../../components/common/Transition'; @@ -12,7 +12,7 @@ import type { Channel, ChannelUpdateInput } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; import ChannelForm from './ChannelForm'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ button: { float: 'left', margin: '-10px 0 0 5px', @@ -27,7 +27,7 @@ const ChannelPopover: React.FC = ({ channel }) => { const [anchorEl, setAnchorEl] = useState(null); const [openDelete, setOpenDelete] = useState(false); const [openEdit, setOpenEdit] = useState(false); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const navigate = useNavigate(); diff --git a/openbas-front/src/admin/components/components/channels/Channels.tsx b/openbas-front/src/admin/components/components/channels/Channels.tsx index 9fc1a6b311..cc2c4f1b46 100644 --- a/openbas-front/src/admin/components/components/channels/Channels.tsx +++ b/openbas-front/src/admin/components/components/channels/Channels.tsx @@ -1,8 +1,8 @@ import { ChevronRightOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchChannels } from '../../../../actions/channels/channel-action'; import type { ChannelsHelper } from '../../../../actions/channels/channel-helper'; @@ -18,7 +18,7 @@ import useSearchAnFilter from '../../../../utils/SortingFiltering'; import ChannelIcon from './ChannelIcon'; import CreateChannel from './CreateChannel'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ parameters: { marginTop: -10, display: 'flex', @@ -100,7 +100,7 @@ const inlineStyles: Record = { const Channels = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); // Filter and sort hook diff --git a/openbas-front/src/admin/components/components/channels/ChannelsFilter.tsx b/openbas-front/src/admin/components/components/channels/ChannelsFilter.tsx index c4bda54754..4b6785c356 100644 --- a/openbas-front/src/admin/components/components/channels/ChannelsFilter.tsx +++ b/openbas-front/src/admin/components/components/channels/ChannelsFilter.tsx @@ -1,7 +1,7 @@ import { Autocomplete, Box, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useEffect } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchChannels } from '../../../../actions/channels/channel-action'; import type { ChannelsHelper } from '../../../../actions/channels/channel-helper'; @@ -12,7 +12,7 @@ import { useAppDispatch } from '../../../../utils/hooks'; import ChannelIcon from './ChannelIcon'; import type { ChannelOption } from './ChannelOption'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -38,7 +38,7 @@ interface ChannelTransformed { } const ChannelsFilter: React.FC = (props) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); useEffect(() => { diff --git a/openbas-front/src/admin/components/components/channels/CreateChannel.js b/openbas-front/src/admin/components/components/channels/CreateChannel.js index 45a5666870..dd44c4d019 100644 --- a/openbas-front/src/admin/components/components/channels/CreateChannel.js +++ b/openbas-front/src/admin/components/components/channels/CreateChannel.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addChannel } from '../../../../actions/channels/channel-action'; import Drawer from '../../../../components/common/Drawer'; @@ -76,5 +76,5 @@ CreateChannel.propTypes = { export default R.compose( connect(null, { addChannel }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateChannel); diff --git a/openbas-front/src/admin/components/components/channels/Index.tsx b/openbas-front/src/admin/components/components/channels/Index.tsx index 95a45096e2..cdf685c888 100644 --- a/openbas-front/src/admin/components/components/channels/Index.tsx +++ b/openbas-front/src/admin/components/components/channels/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy } from 'react'; import { Route, Routes, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchChannel } from '../../../../actions/channels/channel-action'; import type { ChannelsHelper } from '../../../../actions/channels/channel-helper'; @@ -13,7 +13,7 @@ import { useAppDispatch } from '../../../../utils/hooks'; import useDataLoader from '../../../../utils/hooks/useDataLoader'; import ChannelHeader from './ChannelHeader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, @@ -22,7 +22,7 @@ const useStyles = makeStyles(() => ({ const Channel = lazy(() => import('./Channel')); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { channelId } = useParams() as { channelId: ChannelType['channel_id'] }; const { channel } = useHelper((helper: ChannelsHelper) => ({ diff --git a/openbas-front/src/admin/components/components/documents/CreateDocument.js b/openbas-front/src/admin/components/components/documents/CreateDocument.js index 832bcfda50..7d34b60edd 100644 --- a/openbas-front/src/admin/components/components/documents/CreateDocument.js +++ b/openbas-front/src/admin/components/components/documents/CreateDocument.js @@ -1,10 +1,10 @@ import { Add, ControlPointOutlined } from '@mui/icons-material'; import { Fab, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { useContext, useState } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addDocument, fetchDocument } from '../../../../actions/Document'; import Dialog from '../../../../components/common/Dialog'; @@ -130,5 +130,5 @@ CreateDocument.propTypes = { export default R.compose( connect(null, { addDocument, fetchDocument }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateDocument); diff --git a/openbas-front/src/admin/components/components/documents/DocumentType.js b/openbas-front/src/admin/components/components/documents/DocumentType.js index 6d50dbc9ca..8d01863356 100644 --- a/openbas-front/src/admin/components/components/documents/DocumentType.js +++ b/openbas-front/src/admin/components/components/documents/DocumentType.js @@ -1,8 +1,8 @@ import { Chip } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import { compose } from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import inject18n from '../../../../components/i18n'; import { hexToRGB, stringToColour } from '../../../../utils/Colors'; @@ -65,4 +65,4 @@ DocumentType.propTypes = { disabled: PropTypes.bool, }; -export default compose(inject18n, withStyles(styles))(DocumentType); +export default compose(inject18n, Component => withStyles(Component, styles))(DocumentType); diff --git a/openbas-front/src/admin/components/components/documents/Documents.js b/openbas-front/src/admin/components/components/documents/Documents.js index bded447ccf..1037960786 100644 --- a/openbas-front/src/admin/components/components/documents/Documents.js +++ b/openbas-front/src/admin/components/components/documents/Documents.js @@ -1,10 +1,10 @@ import { DescriptionOutlined, RowingOutlined } from '@mui/icons-material'; import { Chip, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { useNavigate } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { searchDocuments } from '../../../../actions/Document'; import { fetchExercises } from '../../../../actions/Exercise'; @@ -21,7 +21,7 @@ import CreateDocument from './CreateDocument'; import DocumentPopover from './DocumentPopover'; import DocumentType from './DocumentType'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -83,7 +83,7 @@ const inlineStyles = { const Documents = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const navigate = useNavigate(); const { t } = useFormatter(); @@ -112,6 +112,17 @@ const Documents = () => { sorts: initSorting('document_name'), }); + /** + * Callback when a new document has been created or an previous one updated with a new version + * @param result the result of the call + */ + const handleCreateDocuments = (result) => { + // If the documents was already in the list displayed, we don't add it to the list + if (documents.find(element => element.document_id === result.document_id) === undefined) { + setDocuments([result, ...documents]); + } + }; + // Export const exportProps = { exportType: 'tags', @@ -287,7 +298,7 @@ const Documents = () => { {userAdmin && ( setDocuments([result, ...documents])} + onCreate={handleCreateDocuments} /> )} diff --git a/openbas-front/src/admin/components/components/lessons/LessonsTemplate.tsx b/openbas-front/src/admin/components/components/lessons/LessonsTemplate.tsx index 798d94882a..a8972b8775 100644 --- a/openbas-front/src/admin/components/components/lessons/LessonsTemplate.tsx +++ b/openbas-front/src/admin/components/components/lessons/LessonsTemplate.tsx @@ -1,7 +1,7 @@ import { HelpOutlined } from '@mui/icons-material'; import { Grid, List, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../actions/helper'; import { fetchLessonsTemplateCategories, fetchLessonsTemplateQuestions } from '../../../../actions/Lessons'; @@ -16,7 +16,7 @@ import LessonsTemplateCategoryPopover from './categories/LessonsTemplateCategory import CreateLessonsTemplateQuestion from './categories/questions/CreateLessonsTemplateQuestion'; import LessonsTemplateQuestionPopover from './categories/questions/LessonsTemplateQuestionPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', alignItems: 'center', @@ -26,7 +26,7 @@ const useStyles = makeStyles(() => ({ const LessonsTemplate = () => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { lessonsTemplateId } = useParams() as { lessonsTemplateId: string }; diff --git a/openbas-front/src/admin/components/components/lessons/LessonsTemplateHeader.tsx b/openbas-front/src/admin/components/components/lessons/LessonsTemplateHeader.tsx index 2d02713797..e1aa3a7afc 100644 --- a/openbas-front/src/admin/components/components/lessons/LessonsTemplateHeader.tsx +++ b/openbas-front/src/admin/components/components/lessons/LessonsTemplateHeader.tsx @@ -1,13 +1,13 @@ import { Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../actions/helper'; import type { LessonsTemplatesHelper } from '../../../../actions/lessons/lesson-helper'; import { useHelper } from '../../../../store'; import LessonsTemplatePopover from './LessonsTemplatePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ containerTitle: { display: 'flex', alignItems: 'center', @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => ({ const LessonsTemplateHeader = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { lessonsTemplateId } = useParams() as { lessonsTemplateId: string }; const { lessonsTemplate, userAdmin } = useHelper((helper: LessonsTemplatesHelper & UserHelper) => ({ diff --git a/openbas-front/src/admin/components/components/lessons/LessonsTemplates.tsx b/openbas-front/src/admin/components/components/lessons/LessonsTemplates.tsx index 0223f706d4..858abc14bd 100644 --- a/openbas-front/src/admin/components/components/lessons/LessonsTemplates.tsx +++ b/openbas-front/src/admin/components/components/lessons/LessonsTemplates.tsx @@ -1,8 +1,8 @@ import { ChevronRightOutlined, SchoolOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../actions/helper'; import { searchLessonsTemplates } from '../../../../actions/Lessons'; @@ -16,7 +16,7 @@ import { useHelper } from '../../../../store'; import type { LessonsTemplate, SearchPaginationInput } from '../../../../utils/api-types'; import CreateLessonsTemplate from './CreateLessonsTemplate'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 17, textTransform: 'uppercase', @@ -51,7 +51,7 @@ const inlineStyles: Record = { const LessonsTemplates = () => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { userAdmin } = useHelper((helper: UserHelper) => { diff --git a/openbas-front/src/admin/components/components/teams/ContextualTeams.tsx b/openbas-front/src/admin/components/components/teams/ContextualTeams.tsx index f527704134..93e1431210 100644 --- a/openbas-front/src/admin/components/components/teams/ContextualTeams.tsx +++ b/openbas-front/src/admin/components/components/teams/ContextualTeams.tsx @@ -1,8 +1,8 @@ import { CheckCircleOutlined, GroupsOutlined } from '@mui/icons-material'; import { Drawer, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useContext, useState } from 'react'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import ItemTags from '../../../../components/ItemTags'; import type { Team } from '../../../../utils/api-types'; @@ -11,7 +11,7 @@ import { PermissionsContext, TeamContext } from '../../common/Context'; import TeamPlayers from './TeamPlayers'; import TeamPopover from './TeamPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -128,7 +128,7 @@ interface TeamStoreExtended extends Team { const ContextualTeams: FunctionComponent = ({ teams }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const [selectedTeam, setSelectedTeam] = useState(null); const { computeTeamUsersEnabled } = useContext(TeamContext); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/components/teams/CreateTeam.tsx b/openbas-front/src/admin/components/components/teams/CreateTeam.tsx index 349efa86ba..a8574d7634 100644 --- a/openbas-front/src/admin/components/components/teams/CreateTeam.tsx +++ b/openbas-front/src/admin/components/components/teams/CreateTeam.tsx @@ -1,20 +1,19 @@ import { Add, ControlPointOutlined } from '@mui/icons-material'; import { Fab, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { TeamInputForm } from '../../../../actions/teams/Team'; import { addTeam } from '../../../../actions/teams/team-actions'; import Dialog from '../../../../components/common/Dialog'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import type { Team, TeamCreateInput } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; import { Option } from '../../../../utils/Option'; import { TeamContext } from '../../common/Context'; import TeamForm from './TeamForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ createButton: { position: 'fixed', bottom: 30, @@ -37,7 +36,7 @@ const CreateTeam: FunctionComponent = ({ onCreate, }) => { const dispatch = useAppDispatch(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [openDialog, setOpenDialog] = useState(false); const { onCreateTeam } = useContext(TeamContext); diff --git a/openbas-front/src/admin/components/components/teams/TeamAddPlayers.tsx b/openbas-front/src/admin/components/components/teams/TeamAddPlayers.tsx index 5e743f16b0..ce21cf32a4 100644 --- a/openbas-front/src/admin/components/components/teams/TeamAddPlayers.tsx +++ b/openbas-front/src/admin/components/components/teams/TeamAddPlayers.tsx @@ -15,10 +15,10 @@ import { ListItemIcon, ListItemText, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { OrganizationHelper, UserHelper } from '../../../../actions/helper'; import { fetchPlayers } from '../../../../actions/User'; @@ -37,7 +37,7 @@ import TagsFilter from '../../common/filters/TagsFilter'; import CreatePlayer from '../../teams/players/CreatePlayer'; import type { UserStore } from '../../teams/players/Player'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ createButton: { position: 'fixed', bottom: 30, @@ -67,7 +67,7 @@ type UserStoreExtended = UserStore & { const TeamAddPlayers: React.FC = ({ addedUsersIds, teamId }) => { const dispatch = useAppDispatch(); const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const [open, setOpen] = useState(false); const [keyword, setKeyword] = useState(''); const [usersIds, setUsersIds] = useState([]); diff --git a/openbas-front/src/admin/components/components/teams/TeamForm.tsx b/openbas-front/src/admin/components/components/teams/TeamForm.tsx index 689c1f6a23..04782f26ca 100644 --- a/openbas-front/src/admin/components/components/teams/TeamForm.tsx +++ b/openbas-front/src/admin/components/components/teams/TeamForm.tsx @@ -1,7 +1,7 @@ import { Button } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext } from 'react'; import { Form } from 'react-final-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { TeamInputForm } from '../../../../actions/teams/Team'; @@ -10,11 +10,10 @@ import OldTextField from '../../../../components/fields/OldTextField'; import { useFormatter } from '../../../../components/i18n'; import OrganizationField from '../../../../components/OrganizationField'; import TagField from '../../../../components/TagField'; -import type { Theme } from '../../../../components/Theme'; import { schemaValidator } from '../../../../utils/Zod'; import { TeamContext, TeamContextType } from '../../common/Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ container: { display: 'flex', gap: theme.spacing(2), @@ -35,7 +34,7 @@ const TeamForm: FunctionComponent = ({ initialValues, handleClose, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { onCreateTeam } = useContext(TeamContext); const teamFormSchemaValidation = z.object({ diff --git a/openbas-front/src/admin/components/components/teams/TeamPlayers.tsx b/openbas-front/src/admin/components/components/teams/TeamPlayers.tsx index 4c000c810f..134232c294 100644 --- a/openbas-front/src/admin/components/components/teams/TeamPlayers.tsx +++ b/openbas-front/src/admin/components/components/teams/TeamPlayers.tsx @@ -1,9 +1,9 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined, CloseRounded, EmailOutlined, KeyOutlined, PersonOutlined, SmartphoneOutlined } from '@mui/icons-material'; import { IconButton, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { CSSProperties, useContext, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { OrganizationHelper, UserHelper } from '../../../../actions/helper'; import { fetchOrganizations } from '../../../../actions/Organization'; @@ -13,7 +13,6 @@ import { useFormatter } from '../../../../components/i18n'; import ItemBoolean from '../../../../components/ItemBoolean'; import ItemTags from '../../../../components/ItemTags'; import SearchFilter from '../../../../components/SearchFilter'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Organization, Team } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -25,7 +24,7 @@ import type { UserStore } from '../../teams/players/Player'; import PlayerPopover from '../../teams/players/PlayerPopover'; import TeamAddPlayers from './TeamAddPlayers'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ header: { backgroundColor: theme.palette.background.nav, padding: '20px 20px 20px 60px', @@ -164,7 +163,7 @@ type UserStoreExtended = UserStore & { const TeamPlayers: React.FC = ({ teamId, handleClose }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const [keyword, setKeyword] = useState(''); diff --git a/openbas-front/src/admin/components/components/teams/Teams.tsx b/openbas-front/src/admin/components/components/teams/Teams.tsx index 7a5f6cd40c..1a079a3dde 100644 --- a/openbas-front/src/admin/components/components/teams/Teams.tsx +++ b/openbas-front/src/admin/components/components/teams/Teams.tsx @@ -1,12 +1,13 @@ import { GroupsOutlined } from '@mui/icons-material'; import { Drawer, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useState } from 'react'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { EndpointHelper } from '../../../../actions/assets/asset-helper'; import type { TagHelper, UserHelper } from '../../../../actions/helper'; import { searchTeams } from '../../../../actions/teams/team-actions'; +import { TeamsHelper } from '../../../../actions/teams/team-helper'; import Breadcrumbs from '../../../../components/Breadcrumbs'; import PaginationComponent from '../../../../components/common/pagination/PaginationComponent'; import SortHeadersComponent from '../../../../components/common/pagination/SortHeadersComponent'; @@ -20,7 +21,7 @@ import CreateTeam from './CreateTeam'; import TeamPlayers from './TeamPlayers'; import TeamPopover from './TeamPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', cursor: 'pointer', @@ -70,7 +71,7 @@ const inlineStyles: Record = { const Teams = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const [selectedTeam, setSelectedTeam] = useState(null); @@ -100,6 +101,21 @@ const Teams = () => { textSearch: search, })); + const { refetched } = useHelper((helper: TeamsHelper) => ({ + refetched: helper.getTeam(selectedTeam ?? ''), + })); + + const onTeamUpdated = (team: Team) => { + setTeams(teams.map(v => (v.team_id !== team.team_id ? v : team))); + }; + + const onPlayersChanged = (team_id: string | null) => { + if (team_id) { + onTeamUpdated(refetched); + setSelectedTeam(null); + } + }; + // Export const exportProps = { exportType: 'team', @@ -176,7 +192,7 @@ const Teams = () => { setSelectedTeam(team.team_id)} - onUpdate={result => setTeams(teams.map(v => (v.team_id !== result.team_id ? v : result)))} + onUpdate={result => onTeamUpdated(result)} onDelete={result => setTeams(teams.filter(v => (v.team_id !== result)))} openEditOnInit={team.team_id === searchId} /> @@ -190,13 +206,13 @@ const Teams = () => { anchor="right" sx={{ zIndex: 1202 }} classes={{ paper: classes.drawerPaper }} - onClose={() => setSelectedTeam(null)} + onClose={() => onPlayersChanged(selectedTeam)} elevation={1} > {selectedTeam !== null && ( setSelectedTeam(null)} + handleClose={() => onPlayersChanged(selectedTeam)} /> )} diff --git a/openbas-front/src/admin/components/components/teams/UpdateTeams.tsx b/openbas-front/src/admin/components/components/teams/UpdateTeams.tsx index d53b1ebc45..b6f74f79b7 100644 --- a/openbas-front/src/admin/components/components/teams/UpdateTeams.tsx +++ b/openbas-front/src/admin/components/components/teams/UpdateTeams.tsx @@ -1,8 +1,8 @@ import { Add, GroupsOutlined } from '@mui/icons-material'; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext, useEffect, useMemo, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { findTeams } from '../../../../actions/teams/team-actions'; import PaginationComponentV2 from '../../../../components/common/queryable/pagination/PaginationComponentV2'; @@ -16,7 +16,7 @@ import type { Team, TeamOutput } from '../../../../utils/api-types'; import { TeamContext } from '../../common/Context'; import CreateTeam from './CreateTeam'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ createButton: { float: 'left', marginTop: -15, @@ -32,7 +32,7 @@ const UpdateTeams: React.FC = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { searchTeams, onReplaceTeam } = useContext(TeamContext); const [teamValues, setTeamValues] = useState([]); diff --git a/openbas-front/src/admin/components/components/variables/CreateVariable.tsx b/openbas-front/src/admin/components/components/variables/CreateVariable.tsx index a30a34e059..8d82252745 100644 --- a/openbas-front/src/admin/components/components/variables/CreateVariable.tsx +++ b/openbas-front/src/admin/components/components/variables/CreateVariable.tsx @@ -7,11 +7,10 @@ import { ListItemButton, ListItemIcon, ListItemText, - Theme, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; @@ -19,7 +18,7 @@ import type { VariableInput } from '../../../../utils/api-types'; import { VariableContext } from '../../common/Context'; import VariableForm from './VariableForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ createButton: { float: 'left', marginTop: -15, @@ -39,7 +38,7 @@ const CreateVariable: React.FC = ({ inline, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Context diff --git a/openbas-front/src/admin/components/components/variables/Variables.tsx b/openbas-front/src/admin/components/components/variables/Variables.tsx index 8b17fc0dd2..74e3dcd32d 100644 --- a/openbas-front/src/admin/components/components/variables/Variables.tsx +++ b/openbas-front/src/admin/components/components/variables/Variables.tsx @@ -1,14 +1,14 @@ import { AttachMoneyOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useContext } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { Variable } from '../../../../utils/api-types'; import useSearchAnFilter from '../../../../utils/SortingFiltering'; import { PermissionsContext, VariableContext } from '../../common/Context'; import VariablePopover from './VariablePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', cursor: 'pointer', @@ -91,7 +91,7 @@ interface Props { const Variables: FunctionComponent = ({ variables }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); // Context const { onEditVariable, onDeleteVariable } = useContext(VariableContext); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/injects/InjectTestDetail.tsx b/openbas-front/src/admin/components/injects/InjectTestDetail.tsx index e5ea730d35..4fabcdda50 100644 --- a/openbas-front/src/admin/components/injects/InjectTestDetail.tsx +++ b/openbas-front/src/admin/components/injects/InjectTestDetail.tsx @@ -1,48 +1,18 @@ -import { Card, CardContent, CardHeader, Grid, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { Card, CardContent, CardHeader, Paper, Typography } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; import Drawer from '../../../components/common/Drawer'; import { useFormatter } from '../../../components/i18n'; -import ItemStatus from '../../../components/ItemStatus'; -import type { Theme } from '../../../components/Theme'; -import type { InjectTestStatus } from '../../../utils/api-types'; +import { InjectTestStatusOutput } from '../../../utils/api-types'; import { truncate } from '../../../utils/String'; -import { isNotEmptyField } from '../../../utils/utils'; import InjectIcon from '../common/injects/InjectIcon'; - -const useStyles = makeStyles((theme: Theme) => ({ - paper: { - position: 'relative', - padding: 20, - overflow: 'hidden', - height: '100%', - }, - header: { - fontWeight: 'bold', - }, - listItem: { - marginBottom: 8, - }, - injectorContract: { - margin: '20px 0 20px 15px', - width: '100%', - border: `1px solid ${theme.palette.divider}`, - borderRadius: 4, - }, - injectorContractHeader: { - backgroundColor: theme.palette.background.default, - }, - injectorContractContent: { - fontSize: 18, - textAlign: 'center', - }, -})); +import InjectStatus from '../common/injects/status/InjectStatus'; interface Props { open: boolean; handleClose: () => void; - test: InjectTestStatus | undefined; + test: InjectTestStatusOutput | undefined; } const InjectTestDetail: FunctionComponent = ({ @@ -50,7 +20,7 @@ const InjectTestDetail: FunctionComponent = ({ handleClose, test, }) => { - const classes = useStyles(); + const theme = useTheme(); const { t } = useFormatter(); return ( @@ -60,118 +30,32 @@ const InjectTestDetail: FunctionComponent = ({ title={t('Test Details')} > - - +
+ {test ? ( )} /> ) : ( - + {t('No data available')} )} - + {truncate(test?.inject_title, 80)} - - {t('Execution logs')} - {test ? ( - - - {t('Execution status')} - - {test.status_name - && } - - {t('Traces')} - -
-                {test.tracking_sent_date ? (
-                  <>
-                    
-                      {t('Tracking Sent Date')}
-                      :
-                      {test.tracking_sent_date}
-                    
-                    
-                      {t('Tracking Ack Date')}
-                      :
-                      {test.tracking_ack_date}
-                    
-                    
-                      {t('Tracking End Date')}
-                      :
-                      {test.tracking_end_date}
-                    
-                    
-                      {t('Tracking Total Execution')}
-                      {t('Time')}
-                      :
-                      {test.tracking_total_execution_time}
-                      {' '}
-                      {t('ms')}
-                    
-                    
-                      {t('Tracking Total Count')}
-                      :
-                      {test.tracking_total_count}
-                    
-                    
-                      {t('Tracking Total Error')}
-                      :
-                      {test.tracking_total_error}
-                    
-                    
-                      {t('Tracking Total Success')}
-                      :
-                      {test.tracking_total_success}
-                    
-                  
-                ) : (
-                  
-                    {t('No data available')}
-                  
-                )}
-                {(test.status_traces?.length ?? 0) > 0 && (
-                  <>
-                    
-                      {t('Traces')}
-                      :
-                    
-                    
    - {test.status_traces?.map((trace, index) => ( -
  • - {`${trace.execution_status} ${trace.execution_message}`} -
  • - ))} -
- - )} -
-
- ) : ( - - {t('No data available')} - - )} -
- + +
); diff --git a/openbas-front/src/admin/components/injects/InjectTestList.tsx b/openbas-front/src/admin/components/injects/InjectTestList.tsx index 61ee1b712f..b595664440 100644 --- a/openbas-front/src/admin/components/injects/InjectTestList.tsx +++ b/openbas-front/src/admin/components/injects/InjectTestList.tsx @@ -1,6 +1,6 @@ import { List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import PaginationComponent from '../../../components/common/pagination/PaginationComponent'; import SortHeadersComponent from '../../../components/common/pagination/SortHeadersComponent'; @@ -9,14 +9,13 @@ import { buildSearchPagination } from '../../../components/common/queryable/Quer import Empty from '../../../components/Empty'; import { useFormatter } from '../../../components/i18n'; import ItemStatus from '../../../components/ItemStatus'; -import type { InjectTestStatus, SearchPaginationInput } from '../../../utils/api-types'; -import { isNotEmptyField } from '../../../utils/utils'; +import type { InjectTestStatusOutput, SearchPaginationInput } from '../../../utils/api-types'; import InjectIcon from '../common/injects/InjectIcon'; import InjectTestDetail from './InjectTestDetail'; import InjectTestPopover from './InjectTestPopover'; import InjectTestReplayAll from './InjectTestReplayAll'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ bodyItems: { display: 'flex', alignItems: 'center', @@ -55,8 +54,8 @@ const inlineStyles: Record = { }; interface Props { - searchInjectTests: (exerciseOrScenarioId: string, input: SearchPaginationInput) => Promise<{ data: Page }>; - searchInjectTest: (testId: string) => Promise<{ data: InjectTestStatus }>; + searchInjectTests: (exerciseOrScenarioId: string, input: SearchPaginationInput) => Promise<{ data: Page }>; + searchInjectTest: (testId: string) => Promise<{ data: InjectTestStatusOutput }>; exerciseOrScenarioId: string; statusId: string | undefined; } @@ -68,15 +67,15 @@ const InjectTestList: FunctionComponent = ({ statusId, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, fldt } = useFormatter(); - const [selectedTest, setSelectedTest] = useState(null); + const [selectedTest, setSelectedTest] = useState(null); // Fetching test useEffect(() => { if (statusId !== null && statusId !== undefined) { - searchInjectTest(statusId).then((result: { data: InjectTestStatus }) => { + searchInjectTest(statusId).then((result: { data: InjectTestStatusOutput }) => { setSelectedTest(result.data); }); } @@ -88,26 +87,26 @@ const InjectTestList: FunctionComponent = ({ field: 'inject_title', label: 'Inject title', isSortable: true, - value: (test: InjectTestStatus) => test.inject_title, + value: (test: InjectTestStatusOutput) => test.inject_title, }, { field: 'tracking_sent_date', label: 'Test execution time', isSortable: true, - value: (test: InjectTestStatus) => fldt(test.tracking_sent_date), + value: (test: InjectTestStatusOutput) => fldt(test.tracking_sent_date), }, { field: 'status_name', label: 'Test status', isSortable: true, - value: (test: InjectTestStatus) => { + value: (test: InjectTestStatusOutput) => { return (); }, }, ]; // Filter and sort hook - const [tests, setTests] = useState([]); + const [tests, setTests] = useState([]); const [searchPaginationInput, setSearchPaginationInput] = useState(buildSearchPagination({})); return ( @@ -117,7 +116,12 @@ const InjectTestList: FunctionComponent = ({ searchPaginationInput={searchPaginationInput} setContent={setTests} > - test.inject_id!)} onTest={result => setTests(result)} /> + test.inject_id!)} + onTest={result => setTests(result)} + /> = ({ divider secondaryAction={( setTests(tests?.map(existing => (existing.status_id !== result.status_id ? existing : result)))} - onDelete={result => setTests(tests.filter(existing => (existing.status_id !== result)))} + injectTest={test} + onTest={result => + setTests(tests?.map(existing => existing.status_id !== result.status_id ? existing : result))} + onDelete={injectStatusId => setTests(tests.filter(existing => (existing.status_id !== injectStatusId)))} /> )} disablePadding @@ -160,13 +165,7 @@ const InjectTestList: FunctionComponent = ({ > diff --git a/openbas-front/src/admin/components/injects/InjectTestPopover.tsx b/openbas-front/src/admin/components/injects/InjectTestPopover.tsx index d870f3504c..9d76876528 100644 --- a/openbas-front/src/admin/components/injects/InjectTestPopover.tsx +++ b/openbas-front/src/admin/components/injects/InjectTestPopover.tsx @@ -8,18 +8,18 @@ import { testInject } from '../../../actions/injects/inject-action'; import DialogDelete from '../../../components/common/DialogDelete'; import DialogTest from '../../../components/common/DialogTest'; import { useFormatter } from '../../../components/i18n'; -import type { InjectTestStatus } from '../../../utils/api-types'; +import type { InjectTestStatusOutput } from '../../../utils/api-types'; import { MESSAGING$ } from '../../../utils/Environment'; import { PermissionsContext } from '../common/Context'; interface Props { - injectTestStatus: InjectTestStatus; - onTest?: (result: InjectTestStatus) => void; + injectTest: InjectTestStatusOutput; + onTest?: (result: InjectTestStatusOutput) => void; onDelete?: (result: string) => void; } const InjectTestPopover: FunctionComponent = ({ - injectTestStatus, + injectTest, onDelete, onTest, }) => { @@ -43,10 +43,11 @@ const InjectTestPopover: FunctionComponent = ({ }; const handleCloseDelete = () => setOpenDelete(false); const submitDelete = () => { - deleteInjectTest(injectTestStatus.status_id); - if (onDelete) { - onDelete(injectTestStatus.status_id!); - } + deleteInjectTest(injectTest.status_id).then(() => { + if (onDelete) { + onDelete(injectTest.status_id!); + } + }); handleCloseDelete(); }; @@ -60,9 +61,9 @@ const InjectTestPopover: FunctionComponent = ({ }; const submitTest = () => { - testInject(injectTestStatus.inject_id!).then((result: { data: InjectTestStatus }) => { + testInject(injectTest.inject_id!).then((result: { data: InjectTestStatusOutput }) => { onTest?.(result.data); - MESSAGING$.notifySuccess(t('Test for inject {injectTitle} has been sent', { injectTitle: injectTestStatus.inject_title })); + MESSAGING$.notifySuccess(t(`Test for inject ${injectTest.inject_title} has been sent`)); return result; }); handleCloseTest(); diff --git a/openbas-front/src/admin/components/injects/InjectTestReplayAll.tsx b/openbas-front/src/admin/components/injects/InjectTestReplayAll.tsx index 731120badd..6d2503a0a8 100644 --- a/openbas-front/src/admin/components/injects/InjectTestReplayAll.tsx +++ b/openbas-front/src/admin/components/injects/InjectTestReplayAll.tsx @@ -5,16 +5,20 @@ import { FunctionComponent, useState } from 'react'; import { bulkTestInjects } from '../../../actions/injects/inject-action'; import DialogTest from '../../../components/common/DialogTest'; import { useFormatter } from '../../../components/i18n'; -import type { InjectTestStatus } from '../../../utils/api-types'; +import type { InjectTestStatusOutput, SearchPaginationInput } from '../../../utils/api-types'; import { MESSAGING$ } from '../../../utils/Environment'; interface Props { + searchPaginationInput: SearchPaginationInput; + exerciseOrScenarioId: string; injectIds: string[] | undefined; - onTest?: (result: InjectTestStatus[]) => void; + onTest?: (result: InjectTestStatusOutput[]) => void; } -const ImportUploaderMapper: FunctionComponent = ({ +const InjectTestReplayAll: FunctionComponent = ({ + searchPaginationInput, injectIds, + exerciseOrScenarioId, onTest, }) => { // Standard hooks @@ -32,10 +36,11 @@ const ImportUploaderMapper: FunctionComponent = ({ const handleSubmitAllTest = () => { bulkTestInjects({ - inject_ids_to_process: injectIds!, - }!).then((result: { data: InjectTestStatus[] }) => { + search_pagination_input: searchPaginationInput, + simulation_or_scenario_id: exerciseOrScenarioId, + }!).then((result: { data: InjectTestStatusOutput[] }) => { onTest?.(result.data); - MESSAGING$.notifySuccess(t('{testNumber} test(s) sent', { testNumber: injectIds?.length })); + MESSAGING$.notifySuccess(t('Test(s) sent')); return result; }); handleCloseAllTest(); @@ -69,4 +74,4 @@ const ImportUploaderMapper: FunctionComponent = ({ ); }; -export default ImportUploaderMapper; +export default InjectTestReplayAll; diff --git a/openbas-front/src/admin/components/integrations/Collectors.tsx b/openbas-front/src/admin/components/integrations/Collectors.tsx index ef97c09343..8f0deb0da6 100644 --- a/openbas-front/src/admin/components/integrations/Collectors.tsx +++ b/openbas-front/src/admin/components/integrations/Collectors.tsx @@ -1,19 +1,18 @@ import { Card, CardContent, Chip, Grid, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { fetchCollectors } from '../../../actions/Collector'; import type { CollectorHelper } from '../../../actions/collectors/collector-helper'; import Breadcrumbs from '../../../components/Breadcrumbs'; import { useFormatter } from '../../../components/i18n'; import SearchFilter from '../../../components/SearchFilter'; -import type { Theme } from '../../../components/Theme'; import { useHelper } from '../../../store'; import type { Collector } from '../../../utils/api-types'; import { useAppDispatch } from '../../../utils/hooks'; import useDataLoader from '../../../utils/hooks/useDataLoader'; import useSearchAnFilter from '../../../utils/SortingFiltering'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ parameters: { marginTop: -3, }, @@ -52,7 +51,7 @@ const useStyles = makeStyles((theme: Theme) => ({ const Collectors = () => { // Standard hooks const { t, nsdt } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Filter and sort hook diff --git a/openbas-front/src/admin/components/integrations/Executors.tsx b/openbas-front/src/admin/components/integrations/Executors.tsx index 0da8896500..f0896d9d70 100644 --- a/openbas-front/src/admin/components/integrations/Executors.tsx +++ b/openbas-front/src/admin/components/integrations/Executors.tsx @@ -1,19 +1,18 @@ import { Card, CardContent, Chip, Grid, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { fetchExecutors } from '../../../actions/Executor'; import type { ExecutorHelper } from '../../../actions/executors/executor-helper'; import Breadcrumbs from '../../../components/Breadcrumbs'; import { useFormatter } from '../../../components/i18n'; import SearchFilter from '../../../components/SearchFilter'; -import type { Theme } from '../../../components/Theme'; import { useHelper } from '../../../store'; import type { Executor } from '../../../utils/api-types'; import { useAppDispatch } from '../../../utils/hooks'; import useDataLoader from '../../../utils/hooks/useDataLoader'; import useSearchAnFilter from '../../../utils/SortingFiltering'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ parameters: { marginTop: -3, }, @@ -46,7 +45,7 @@ const useStyles = makeStyles((theme: Theme) => ({ const Executors = () => { // Standard hooks const { t, nsdt } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Filter and sort hook diff --git a/openbas-front/src/admin/components/integrations/Index.tsx b/openbas-front/src/admin/components/integrations/Index.tsx index 449f77f5c6..f8db7a52f9 100644 --- a/openbas-front/src/admin/components/integrations/Index.tsx +++ b/openbas-front/src/admin/components/integrations/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy, Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../../../components/Error'; import Loader from '../../../components/Loader'; @@ -11,14 +11,14 @@ const IndexInjector = lazy(() => import('./injectors/Index')); const Collectors = lazy(() => import('./Collectors')); const Executors = lazy(() => import('./Executors')); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); return (
}> diff --git a/openbas-front/src/admin/components/integrations/Injectors.tsx b/openbas-front/src/admin/components/integrations/Injectors.tsx index 7308c236b7..9c096a4b6e 100644 --- a/openbas-front/src/admin/components/integrations/Injectors.tsx +++ b/openbas-front/src/admin/components/integrations/Injectors.tsx @@ -1,21 +1,20 @@ import { AutoModeOutlined, SubscriptionsOutlined } from '@mui/icons-material'; import { Card, CardActionArea, CardContent, Chip, Grid, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjectors } from '../../../actions/Injectors'; import type { InjectorHelper } from '../../../actions/injectors/injector-helper'; import Breadcrumbs from '../../../components/Breadcrumbs'; import { useFormatter } from '../../../components/i18n'; import SearchFilter from '../../../components/SearchFilter'; -import type { Theme } from '../../../components/Theme'; import { useHelper } from '../../../store'; import type { Injector } from '../../../utils/api-types'; import { useAppDispatch } from '../../../utils/hooks'; import useDataLoader from '../../../utils/hooks/useDataLoader'; import useSearchAnFilter from '../../../utils/SortingFiltering'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ parameters: { marginTop: -3, }, @@ -67,7 +66,7 @@ const useStyles = makeStyles((theme: Theme) => ({ const Injectors = () => { // Standard hooks const { t, nsdt } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Filter and sort hook diff --git a/openbas-front/src/admin/components/integrations/injectors/Index.tsx b/openbas-front/src/admin/components/integrations/injectors/Index.tsx index ead18c2118..beb6f27f08 100644 --- a/openbas-front/src/admin/components/integrations/injectors/Index.tsx +++ b/openbas-front/src/admin/components/integrations/injectors/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy } from 'react'; import { Route, Routes, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjector } from '../../../../actions/Injectors'; import type { InjectorHelper } from '../../../../actions/injectors/injector-helper'; @@ -15,7 +15,7 @@ import { useAppDispatch } from '../../../../utils/hooks'; import useDataLoader from '../../../../utils/hooks/useDataLoader'; import InjectorHeader from './InjectorHeader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, @@ -24,7 +24,7 @@ const useStyles = makeStyles(() => ({ const InjectorContracts = lazy(() => import('./InjectorContracts')); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const { injectorId } = useParams() as { injectorId: InjectorType['injector_id'] }; diff --git a/openbas-front/src/admin/components/integrations/injectors/InjectorContracts.js b/openbas-front/src/admin/components/integrations/injectors/InjectorContracts.js index 35b3c98c71..de091f4ed0 100644 --- a/openbas-front/src/admin/components/integrations/injectors/InjectorContracts.js +++ b/openbas-front/src/admin/components/integrations/injectors/InjectorContracts.js @@ -1,9 +1,9 @@ import { SmartButtonOutlined } from '@mui/icons-material'; import { Chip, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useState } from 'react'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { searchInjectorContracts } from '../../../../actions/InjectorContracts'; import PaginationComponent from '../../../../components/common/pagination/PaginationComponent'; @@ -14,7 +14,7 @@ import { useHelper } from '../../../../store'; import CreateInjectorContract from './injector_contracts/CreateInjectorContract'; import InjectorContractPopover from './injector_contracts/InjectorContractPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { marginTop: 20, }, @@ -96,7 +96,7 @@ const inlineStyles = { const InjectorContracts = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { injectorId } = useParams(); const { t, tPick, nsdt } = useFormatter(); const { injector, attackPatternsMap, killChainPhasesMap } = useHelper(helper => ({ diff --git a/openbas-front/src/admin/components/integrations/injectors/InjectorHeader.js b/openbas-front/src/admin/components/integrations/injectors/InjectorHeader.js index 3389f81c09..81a4e23f18 100644 --- a/openbas-front/src/admin/components/integrations/injectors/InjectorHeader.js +++ b/openbas-front/src/admin/components/integrations/injectors/InjectorHeader.js @@ -1,17 +1,17 @@ import { Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { useHelper } from '../../../../store'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { width: '100%', }, })); const InjectorHeader = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { injectorId } = useParams(); const { injector } = useHelper(helper => ({ injector: helper.getInjector(injectorId), diff --git a/openbas-front/src/admin/components/integrations/injectors/injector_contracts/CreateInjectorContract.js b/openbas-front/src/admin/components/integrations/injectors/injector_contracts/CreateInjectorContract.js index a76feec231..64f8ecaa9f 100644 --- a/openbas-front/src/admin/components/integrations/injectors/injector_contracts/CreateInjectorContract.js +++ b/openbas-front/src/admin/components/integrations/injectors/injector_contracts/CreateInjectorContract.js @@ -1,10 +1,10 @@ import { Add, SmartButtonOutlined } from '@mui/icons-material'; import { Fab, List, ListItemButton, ListItemIcon, ListItemText, Step, StepLabel, Stepper } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { v4 as uuid } from 'uuid'; import { addInjectorContract } from '../../../../../actions/InjectorContracts'; @@ -152,5 +152,5 @@ CreateInjectorContract.propTypes = { export default R.compose( connect(null, { addInjectorContract }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateInjectorContract); diff --git a/openbas-front/src/admin/components/integrations/injectors/injector_contracts/InjectorContractCustomForm.js b/openbas-front/src/admin/components/integrations/injectors/injector_contracts/InjectorContractCustomForm.js index 50d1eb51d4..fd39c8501a 100644 --- a/openbas-front/src/admin/components/integrations/injectors/injector_contracts/InjectorContractCustomForm.js +++ b/openbas-front/src/admin/components/integrations/injectors/injector_contracts/InjectorContractCustomForm.js @@ -1,5 +1,5 @@ import { Button, Grid, Switch, TextField as MUITextField, Typography } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { useState } from 'react'; diff --git a/openbas-front/src/admin/components/lessons/CreateObjective.js b/openbas-front/src/admin/components/lessons/CreateObjective.js index 3945f3bca5..4a7ce91b56 100644 --- a/openbas-front/src/admin/components/lessons/CreateObjective.js +++ b/openbas-front/src/admin/components/lessons/CreateObjective.js @@ -1,9 +1,9 @@ import { Add } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, IconButton } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import Transition from '../../../components/common/Transition'; import inject18n from '../../../components/i18n'; @@ -88,5 +88,5 @@ CreateObjective.propTypes = { export default R.compose( inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateObjective); diff --git a/openbas-front/src/admin/components/lessons/categories/CreateLessonsCategory.js b/openbas-front/src/admin/components/lessons/categories/CreateLessonsCategory.js index c958bc3d9a..5d96cc90b2 100644 --- a/openbas-front/src/admin/components/lessons/categories/CreateLessonsCategory.js +++ b/openbas-front/src/admin/components/lessons/categories/CreateLessonsCategory.js @@ -1,7 +1,7 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, ListItemButton, ListItemIcon, ListItemText, Slide } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { forwardRef, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import ButtonCreate from '../../../../components/common/ButtonCreate'; import { useFormatter } from '../../../../components/i18n'; @@ -13,7 +13,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ text: { fontSize: 15, color: theme.palette.primary.main, @@ -23,7 +23,7 @@ const useStyles = makeStyles(theme => ({ const CreateLessonsCategory = (props) => { const { onCreate, inline } = props; - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/admin/components/lessons/categories/LessonsCategoryAddTeams.js b/openbas-front/src/admin/components/lessons/categories/LessonsCategoryAddTeams.js index 2d030c4d73..41d07ab25c 100644 --- a/openbas-front/src/admin/components/lessons/categories/LessonsCategoryAddTeams.js +++ b/openbas-front/src/admin/components/lessons/categories/LessonsCategoryAddTeams.js @@ -14,10 +14,10 @@ import { ListItemIcon, ListItemText, } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import Transition from '../../../../components/common/Transition'; import inject18n from '../../../../components/i18n'; @@ -292,5 +292,5 @@ LessonsCategoryAddTeams.propTypes = { export default R.compose( inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(LessonsCategoryAddTeams); diff --git a/openbas-front/src/admin/components/lessons/categories/LessonsCategoryPopover.js b/openbas-front/src/admin/components/lessons/categories/LessonsCategoryPopover.js index 985b20c569..4bd73e891c 100644 --- a/openbas-front/src/admin/components/lessons/categories/LessonsCategoryPopover.js +++ b/openbas-front/src/admin/components/lessons/categories/LessonsCategoryPopover.js @@ -1,8 +1,8 @@ import { MoreVert } from '@mui/icons-material'; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, Menu, MenuItem, Slide } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { forwardRef, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import { LessonContext } from '../../common/Context'; @@ -13,7 +13,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ button: { float: 'left', margin: '-15px 0 0 5px', @@ -22,7 +22,7 @@ const useStyles = makeStyles(() => ({ const LessonsCategoryPopover = ({ lessonsCategory }) => { // utils - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // states const [openDelete, setOpenDelete] = useState(false); diff --git a/openbas-front/src/admin/components/lessons/categories/questions/CreateLessonsQuestion.js b/openbas-front/src/admin/components/lessons/categories/questions/CreateLessonsQuestion.js index 241f354285..89a0b6c7f2 100644 --- a/openbas-front/src/admin/components/lessons/categories/questions/CreateLessonsQuestion.js +++ b/openbas-front/src/admin/components/lessons/categories/questions/CreateLessonsQuestion.js @@ -9,8 +9,8 @@ import { ListItemText, Slide, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { forwardRef, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../components/i18n'; import { LessonContext } from '../../../common/Context'; @@ -21,7 +21,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ createButton: { float: 'left', margin: '-15px 0 0 5px', @@ -35,7 +35,7 @@ const useStyles = makeStyles(theme => ({ const CreateLessonsQuestion = (props) => { const { onCreate, inline, lessonsCategoryId } = props; - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/admin/components/lessons/exercises/Lessons.tsx b/openbas-front/src/admin/components/lessons/exercises/Lessons.tsx index de2be3b050..092bd7cdfb 100644 --- a/openbas-front/src/admin/components/lessons/exercises/Lessons.tsx +++ b/openbas-front/src/admin/components/lessons/exercises/Lessons.tsx @@ -23,14 +23,13 @@ import { Radio, RadioGroup, Switch, - Theme, Typography, useTheme, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; @@ -44,7 +43,7 @@ import AnswersByQuestionDialog from './AnswersByQuestionDialog'; import LessonsCategories from './LessonsCategories'; import LessonsObjectives from './LessonsObjectives'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ metric: { position: 'relative', padding: 20, @@ -123,7 +122,7 @@ const Lessons: React.FC = ({ usersMap, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const { t, nsdt } = useFormatter(); diff --git a/openbas-front/src/admin/components/lessons/exercises/LessonsCategories.js b/openbas-front/src/admin/components/lessons/exercises/LessonsCategories.js index 7f81f41c88..1c6beed1be 100644 --- a/openbas-front/src/admin/components/lessons/exercises/LessonsCategories.js +++ b/openbas-front/src/admin/components/lessons/exercises/LessonsCategories.js @@ -1,8 +1,8 @@ import { CastForEducationOutlined, HelpOutlined } from '@mui/icons-material'; import { Box, Chip, Grid, LinearProgress, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Paper, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useContext } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import { truncate } from '../../../../utils/String'; @@ -12,7 +12,7 @@ import LessonsCategoryPopover from '../categories/LessonsCategoryPopover'; import CreateLessonsQuestion from '../categories/questions/CreateLessonsQuestion'; import LessonsQuestionPopover from '../categories/questions/LessonsQuestionPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', padding: 0, @@ -40,7 +40,7 @@ const LessonsCategories = ({ isReport, style = {}, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Context diff --git a/openbas-front/src/admin/components/lessons/exercises/LessonsObjectives.js b/openbas-front/src/admin/components/lessons/exercises/LessonsObjectives.js index 3ef226067c..22c56ba934 100644 --- a/openbas-front/src/admin/components/lessons/exercises/LessonsObjectives.js +++ b/openbas-front/src/admin/components/lessons/exercises/LessonsObjectives.js @@ -11,9 +11,10 @@ import { Paper, Typography, } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import Chart from 'react-apexcharts'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; @@ -21,7 +22,7 @@ import { areaChartOptions } from '../../../../utils/Charts'; import CreateObjective from '../CreateObjective'; import ObjectivePopover from '../ObjectivePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', padding: 0, @@ -43,7 +44,7 @@ const LessonsObjectives = ({ setSelectedObjective, isReport, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const { t, nsdt } = useFormatter(); const sortedObjectives = R.sortWith( diff --git a/openbas-front/src/admin/components/lessons/scenarios/Lessons.tsx b/openbas-front/src/admin/components/lessons/scenarios/Lessons.tsx index b19f330d8c..a5671f970f 100644 --- a/openbas-front/src/admin/components/lessons/scenarios/Lessons.tsx +++ b/openbas-front/src/admin/components/lessons/scenarios/Lessons.tsx @@ -18,9 +18,9 @@ import { Typography, useTheme, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useContext, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; @@ -32,7 +32,7 @@ import ObjectiveEvaluations from '../ObjectiveEvaluations'; import LessonsCategories from './LessonsCategories'; import LessonsObjectives from './LessonsObjectives'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', padding: 0, @@ -84,7 +84,7 @@ const Lessons: React.FC = ({ lessonsTemplates, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const { t } = useFormatter(); @@ -124,7 +124,7 @@ const Lessons: React.FC = ({ return (
- + {t('Parameters')} @@ -187,7 +187,7 @@ const Lessons: React.FC = ({ - + ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', padding: 0, @@ -37,7 +37,7 @@ const LessonsCategories = ({ teams, isReport, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Context diff --git a/openbas-front/src/admin/components/lessons/scenarios/LessonsObjectives.js b/openbas-front/src/admin/components/lessons/scenarios/LessonsObjectives.js index 101dd28c0c..4531122528 100644 --- a/openbas-front/src/admin/components/lessons/scenarios/LessonsObjectives.js +++ b/openbas-front/src/admin/components/lessons/scenarios/LessonsObjectives.js @@ -10,15 +10,15 @@ import { Paper, Typography, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; import CreateObjective from '../CreateObjective'; import ObjectivePopover from '../ObjectivePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paper: { position: 'relative', height: '250px', @@ -32,7 +32,7 @@ const LessonsObjectives = ({ setSelectedObjective, isReport, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const sortedObjectives = R.sortWith( [R.ascend(R.prop('objective_priority'))], diff --git a/openbas-front/src/admin/components/mitigations/CreateMitigation.js b/openbas-front/src/admin/components/mitigations/CreateMitigation.js index b2d57b6be0..1073eb502b 100644 --- a/openbas-front/src/admin/components/mitigations/CreateMitigation.js +++ b/openbas-front/src/admin/components/mitigations/CreateMitigation.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addMitigation } from '../../../actions/Mitigation'; import Drawer from '../../../components/common/Drawer'; @@ -87,5 +87,5 @@ CreateMitigation.propTypes = { export default R.compose( connect(null, { addMitigation }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateMitigation); diff --git a/openbas-front/src/admin/components/mitigations/Mitigations.js b/openbas-front/src/admin/components/mitigations/Mitigations.js index b637bc7553..c7a5d7619c 100644 --- a/openbas-front/src/admin/components/mitigations/Mitigations.js +++ b/openbas-front/src/admin/components/mitigations/Mitigations.js @@ -1,7 +1,7 @@ import { DynamicFormOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { searchMitigations } from '../../../actions/Mitigation'; import Breadcrumbs from '../../../components/Breadcrumbs'; @@ -13,7 +13,7 @@ import { useHelper } from '../../../store'; import CreateMitigation from './CreateMitigation'; import MitigationPopover from './MitigationPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, }, @@ -95,7 +95,7 @@ const inlineStyles = { const Mitigations = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const { attackPatternsMap, killChainPhasesMap } = useHelper(helper => ({ attackPatternsMap: helper.getAttackPatternsMap(), diff --git a/openbas-front/src/admin/components/nav/TopBar.tsx b/openbas-front/src/admin/components/nav/TopBar.tsx index 5cb6b2071d..5d4d1aadd0 100644 --- a/openbas-front/src/admin/components/nav/TopBar.tsx +++ b/openbas-front/src/admin/components/nav/TopBar.tsx @@ -1,14 +1,14 @@ import { AccountCircleOutlined, AppsOutlined, ImportantDevicesOutlined } from '@mui/icons-material'; import { AppBar, Badge, Box, Grid, IconButton, Menu, MenuItem, Popover, Toolbar, Tooltip } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { useEffect, useState } from 'react'; import { Link, useLocation, useNavigate, useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { logout } from '../../../actions/Application'; import { useFormatter } from '../../../components/i18n'; import SearchInput from '../../../components/SearchFilter'; -import type { Theme } from '../../../components/Theme'; import { computeBannerSettings } from '../../../public/components/systembanners/utils'; import obasDark from '../../../static/images/xtm/obas_dark.png'; import obasLight from '../../../static/images/xtm/obas_light.png'; @@ -22,7 +22,7 @@ import { MESSAGING$ } from '../../../utils/Environment'; import { useAppDispatch } from '../../../utils/hooks'; import useAuth from '../../../utils/hooks/useAuth'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ appBar: { width: '100%', zIndex: theme.zIndex.drawer + 1, @@ -95,10 +95,10 @@ const useStyles = makeStyles(theme => ({ const TopBar: React.FC = () => { // Standard hooks - const theme = useTheme(); + const theme = useTheme(); const location = useLocation(); const navigate = useNavigate(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { settings } = useAuth(); const { bannerHeightNumber } = computeBannerSettings(settings); @@ -188,7 +188,6 @@ const TopBar: React.FC = () => { { withStyles(Component, styles), )(CreatePayload); diff --git a/openbas-front/src/admin/components/payloads/PayloadComponent.tsx b/openbas-front/src/admin/components/payloads/PayloadComponent.tsx index 97184a6af2..8f242851ae 100644 --- a/openbas-front/src/admin/components/payloads/PayloadComponent.tsx +++ b/openbas-front/src/admin/components/payloads/PayloadComponent.tsx @@ -1,6 +1,6 @@ import { Chip, Grid, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { AttackPatternHelper } from '../../../actions/attack_patterns/attackpattern-helper'; import { useFormatter } from '../../../components/i18n'; @@ -11,7 +11,7 @@ import { useHelper } from '../../../store'; import { AttackPattern, Command, DnsResolution, Executable, FileDrop, Payload as PayloadType, PayloadArgument, PayloadPrerequisite } from '../../../utils/api-types'; import { emptyFilled } from '../../../utils/String'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -30,7 +30,7 @@ const PayloadComponent: FunctionComponent = ({ selectedPayload, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { attackPatternsMap } = useHelper((helper: AttackPatternHelper) => ({ diff --git a/openbas-front/src/admin/components/payloads/PayloadForm.tsx b/openbas-front/src/admin/components/payloads/PayloadForm.tsx index ad5e2d9e8b..d08feffbb8 100644 --- a/openbas-front/src/admin/components/payloads/PayloadForm.tsx +++ b/openbas-front/src/admin/components/payloads/PayloadForm.tsx @@ -1,9 +1,9 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { ControlPointOutlined, DeleteOutlined } from '@mui/icons-material'; import { Button, IconButton, InputLabel, List, ListItem, ListItemText, MenuItem, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FormEvent, FunctionComponent } from 'react'; import { Controller, SubmitHandler, useFieldArray, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import AttackPatternField from '../../../components/AttackPatternField'; @@ -15,7 +15,7 @@ import PlatformField from '../../../components/PlatformField'; import type { PayloadCreateInput } from '../../../utils/api-types'; import type { Option } from '../../../utils/Option'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ errorColor: { color: '#f44336', }, @@ -61,7 +61,7 @@ const PayloadForm: FunctionComponent = ({ payload_prerequisites: [], }, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const payloadPrerequisiteZodObject = z.object({ diff --git a/openbas-front/src/admin/components/payloads/Payloads.tsx b/openbas-front/src/admin/components/payloads/Payloads.tsx index dc0bebd514..f1e7dfc277 100644 --- a/openbas-front/src/admin/components/payloads/Payloads.tsx +++ b/openbas-front/src/admin/components/payloads/Payloads.tsx @@ -1,6 +1,6 @@ import { Chip, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useMemo, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchCollectors } from '../../../actions/Collector'; import type { CollectorHelper } from '../../../actions/collectors/collector-helper'; @@ -29,7 +29,7 @@ import CreatePayload from './CreatePayload'; import PayloadComponent from './PayloadComponent'; import PayloadPopover from './PayloadPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -124,7 +124,7 @@ const fromPayloadStatusToChipColor = (payloadStatus: string) => { const Payloads = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/admin/components/scenarios/Scenarios.tsx b/openbas-front/src/admin/components/scenarios/Scenarios.tsx index b7f65033eb..7e55bb165c 100644 --- a/openbas-front/src/admin/components/scenarios/Scenarios.tsx +++ b/openbas-front/src/admin/components/scenarios/Scenarios.tsx @@ -1,8 +1,8 @@ import { MovieFilterOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, ToggleButtonGroup } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useMemo, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchStatistics } from '../../../actions/Application'; import type { TagHelper, UserHelper } from '../../../actions/helper'; @@ -28,7 +28,7 @@ import ScenarioPopover from './scenario/ScenarioPopover'; import ScenarioStatus from './scenario/ScenarioStatus'; import ScenarioCreation from './ScenarioCreation'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -74,7 +74,7 @@ const inlineStyles: Record = { const Scenarios = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const [loading, setLoading] = useState(true); diff --git a/openbas-front/src/admin/components/scenarios/scenario/Index.tsx b/openbas-front/src/admin/components/scenarios/scenario/Index.tsx index b4502fbbd1..cc26403480 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/Index.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/Index.tsx @@ -1,9 +1,10 @@ import { UpdateOutlined } from '@mui/icons-material'; import { Alert, AlertTitle, Box, IconButton, Tab, Tabs, Tooltip } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import cronstrue from 'cronstrue'; import { FunctionComponent, lazy, Suspense, useState } from 'react'; import { Link, Route, Routes, useLocation, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchScenario } from '../../../../actions/scenarios/scenario-actions'; import type { ScenariosHelper } from '../../../../actions/scenarios/scenario-helper'; @@ -12,7 +13,6 @@ import { errorWrapper } from '../../../../components/Error'; import { useFormatter } from '../../../../components/i18n'; import Loader from '../../../../components/Loader'; import NotFound from '../../../../components/NotFound'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import { Scenario } from '../../../../utils/api-types'; import { parseCron, ParsedCron } from '../../../../utils/Cron'; @@ -32,7 +32,7 @@ const Lessons = lazy(() => import('./lessons/ScenarioLessons')); // eslint-disable-next-line no-underscore-dangle const _MS_PER_DAY = 1000 * 60 * 60 * 24; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ scheduling: { display: 'flex', margin: '-35px 8px 0 0', @@ -46,8 +46,8 @@ const IndexScenarioComponent: FunctionComponent<{ scenario: Scenario }> = ({ }) => { const { t, ft, locale, fld } = useFormatter(); const location = useLocation(); - const theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const permissionsContext: PermissionsContextType = { permissions: useScenarioPermissions(scenario.scenario_id), }; diff --git a/openbas-front/src/admin/components/scenarios/scenario/Scenario.tsx b/openbas-front/src/admin/components/scenarios/scenario/Scenario.tsx index a83bf7131a..f0e53ee706 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/Scenario.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/Scenario.tsx @@ -1,10 +1,11 @@ import { PlayArrowOutlined } from '@mui/icons-material'; import { Avatar, Button, Chip, Grid, Paper, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import * as React from 'react'; import { useState } from 'react'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { ExercisesHelper } from '../../../../actions/exercises/exercise-helper'; import { searchScenarioExercises } from '../../../../actions/scenarios/scenario-actions'; @@ -20,7 +21,6 @@ import ItemMainFocus from '../../../../components/ItemMainFocus'; import ItemSeverity from '../../../../components/ItemSeverity'; import ItemTags from '../../../../components/ItemTags'; import PlatformIcon from '../../../../components/PlatformIcon'; -import type { Theme } from '../../../../components/Theme'; import octiDark from '../../../../static/images/xtm/octi_dark.png'; import octiLight from '../../../../static/images/xtm/octi_light.png'; import { useHelper } from '../../../../store'; @@ -32,7 +32,7 @@ import ScenarioDistributionByExercise from './ScenarioDistributionByExercise'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -55,8 +55,8 @@ const useStyles = makeStyles(() => ({ const Scenario = ({ setOpenInstantiateSimulationAndStart }: { setOpenInstantiateSimulationAndStart: React.Dispatch> }) => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const { t } = useFormatter(); const { scenarioId } = useParams() as { scenarioId: ScenarioType['scenario_id'] }; // Fetching data diff --git a/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts b/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts index e3d646207a..e5e95fbcba 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts +++ b/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts @@ -22,7 +22,7 @@ import type { InjectBulkProcessingInput, InjectBulkUpdateInputs, InjectsImportInput, - InjectTestStatus, + InjectTestStatusOutput, Scenario, SearchPaginationInput, } from '../../../../utils/api-types'; @@ -67,7 +67,7 @@ const injectContextForScenario = (scenario: Scenario) => { onBulkDeleteInjects(param: InjectBulkProcessingInput): Promise { return bulkDeleteInjectsSimple(param).then((result: { data: Inject[] }) => result?.data); }, - bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatus[] }> { + bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatusOutput[] }> { return bulkTestInjects(param).then(result => ({ uri: `/admin/scenarios/${scenario.scenario_id}/tests`, data: result.data, diff --git a/openbas-front/src/admin/components/scenarios/scenario/ScenarioDefinition.tsx b/openbas-front/src/admin/components/scenarios/scenario/ScenarioDefinition.tsx index e4adc9de4f..43b45ba018 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/ScenarioDefinition.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/ScenarioDefinition.tsx @@ -1,6 +1,6 @@ import { Grid, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { ScenariosHelper } from '../../../../actions/scenarios/scenario-helper'; import { useFormatter } from '../../../../components/i18n'; @@ -13,7 +13,7 @@ import ScenarioVariables from './variables/ScenarioVariables'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ gridContainer: { marginBottom: 20, }, @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => ({ const ScenarioDefinition = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { scenarioId } = useParams() as { scenarioId: Scenario['scenario_id'] }; // Fetching data diff --git a/openbas-front/src/admin/components/scenarios/scenario/ScenarioDistributionByExercise.tsx b/openbas-front/src/admin/components/scenarios/scenario/ScenarioDistributionByExercise.tsx index b911561084..fc0496f6ca 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/ScenarioDistributionByExercise.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/ScenarioDistributionByExercise.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent, useEffect, useState } from 'react'; import Chart from 'react-apexcharts'; @@ -6,7 +6,6 @@ import { fetchScenarioStatistic } from '../../../../actions/scenarios/scenario-a import Empty from '../../../../components/Empty'; import { useFormatter } from '../../../../components/i18n'; import Loader from '../../../../components/Loader'; -import type { Theme } from '../../../../components/Theme'; import { GlobalScoreBySimulationEndDate, ScenarioStatistic } from '../../../../utils/api-types'; import { CustomTooltipFunction, CustomTooltipOptions, verticalBarsChartOptions } from '../../../../utils/Charts'; @@ -66,8 +65,7 @@ const customTooltip = (simulationEndDateLabel: string): CustomTooltipFunction => }; }; -function getXFormatter() { - const { fsd } = useFormatter(); +function getXFormatter(fsd: (date: string) => string) { return (rawData: string) => { if (!rawData) { return rawData; @@ -85,8 +83,8 @@ const ScenarioDistributionByExercise: FunctionComponent = ({ scenarioId, }) => { // Standard hooks - const { t } = useFormatter(); - const theme: Theme = useTheme(); + const { fsd, t } = useFormatter(); + const theme = useTheme(); const simulationEndDateLabel = t('Simulation end date'); @@ -126,7 +124,7 @@ const ScenarioDistributionByExercise: FunctionComponent = ({ ({ +const useStyles = makeStyles()(() => ({ title: { float: 'left', marginRight: 10, @@ -75,8 +75,8 @@ const ScenarioHeader = ({ const { t } = useFormatter(); const dispatch = useAppDispatch(); const navigate = useNavigate(); - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const { scenarioId } = useParams() as { scenarioId: Scenario['scenario_id'] }; // Fetching data diff --git a/openbas-front/src/admin/components/scenarios/scenario/ScenarioStatus.tsx b/openbas-front/src/admin/components/scenarios/scenario/ScenarioStatus.tsx index 2f2808e176..b32e862f7d 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/ScenarioStatus.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/ScenarioStatus.tsx @@ -1,12 +1,12 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import type { Scenario } from '../../../../utils/api-types'; import { inlineStylesColors } from '../../../../utils/Colors'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { marginTop: 2, fontSize: 14, @@ -40,7 +40,7 @@ const scenarioStatus: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'list' ? classes.chipInList : classes.chip; if (scenario.scenario_recurrence) { diff --git a/openbas-front/src/admin/components/scenarios/scenario/tests/ScenarioTests.tsx b/openbas-front/src/admin/components/scenarios/scenario/tests/ScenarioTests.tsx index e76365f287..6d8f398fa8 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/tests/ScenarioTests.tsx +++ b/openbas-front/src/admin/components/scenarios/scenario/tests/ScenarioTests.tsx @@ -2,11 +2,11 @@ import { FunctionComponent } from 'react'; import { useParams } from 'react-router'; import { fetchInjectTestStatus, searchScenarioInjectTests } from '../../../../../actions/inject_test/inject-test-actions'; -import type { InjectTestStatus, Scenario } from '../../../../../utils/api-types'; +import type { InjectTestStatusOutput, Scenario } from '../../../../../utils/api-types'; import InjectTestList from '../../../injects/InjectTestList'; const ScenarioTests: FunctionComponent = () => { - const { scenarioId, statusId } = useParams() as { scenarioId: Scenario['scenario_id']; statusId: InjectTestStatus['status_id'] }; + const { scenarioId, statusId } = useParams() as { scenarioId: Scenario['scenario_id']; statusId: InjectTestStatusOutput['status_id'] }; return ( diff --git a/openbas-front/src/admin/components/search/FullTextSearch.tsx b/openbas-front/src/admin/components/search/FullTextSearch.tsx index 0b6aff9e6f..b48a21817e 100644 --- a/openbas-front/src/admin/components/search/FullTextSearch.tsx +++ b/openbas-front/src/admin/components/search/FullTextSearch.tsx @@ -1,10 +1,10 @@ import { KeyboardArrowRight } from '@mui/icons-material'; import { TabPanelProps } from '@mui/lab'; import { Box, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Tab, Tabs } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useEffect, useState } from 'react'; import * as React from 'react'; import { Link, useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fullTextSearch, fullTextSearchByClass } from '../../../actions/fullTextSearch-action'; import Breadcrumbs from '../../../components/Breadcrumbs'; @@ -13,12 +13,11 @@ import { buildSearchPagination } from '../../../components/common/queryable/Quer import { Header } from '../../../components/common/SortHeadersList'; import { useFormatter } from '../../../components/i18n'; import ItemTags from '../../../components/ItemTags'; -import type { Theme } from '../../../components/Theme'; import type { FullTextSearchCountResult, FullTextSearchResult, SearchPaginationInput } from '../../../utils/api-types'; import useEntityIcon from '../../../utils/hooks/useEntityIcon'; import useEntityLink from './useEntityLink'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ container: { display: 'flex', }, @@ -66,7 +65,7 @@ const TabPanel = (props: TabPanelProps & { index: number; entity: string; search const { value, index, entity, searchPaginationInput } = props; // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Headers @@ -157,7 +156,7 @@ const TabPanel = (props: TabPanelProps & { index: number; entity: string; search const FullTextSearch = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [searchParams] = useSearchParams(); diff --git a/openbas-front/src/admin/components/settings/Parameters.tsx b/openbas-front/src/admin/components/settings/Parameters.tsx index 3c5ebe6e3f..89575b686b 100644 --- a/openbas-front/src/admin/components/settings/Parameters.tsx +++ b/openbas-front/src/admin/components/settings/Parameters.tsx @@ -1,5 +1,5 @@ import { Button, Grid, List, ListItem, ListItemText, Paper, Switch, TextField, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { fetchPlatformParameters, @@ -21,7 +21,7 @@ import EnterpriseEditionButton from '../common/entreprise_edition/EnterpriseEdit import ParametersForm from './ParametersForm'; import ThemeForm from './ThemeForm'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '0 0 60px 0', }, @@ -39,7 +39,7 @@ const useStyles = makeStyles(() => ({ })); const Parameters = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); const { settings }: { settings: PlatformSettings } = useHelper((helper: LoggedHelper) => ({ diff --git a/openbas-front/src/admin/components/settings/TaxonomiesMenu.tsx b/openbas-front/src/admin/components/settings/TaxonomiesMenu.tsx index fa77ac69e7..d1171f8d09 100644 --- a/openbas-front/src/admin/components/settings/TaxonomiesMenu.tsx +++ b/openbas-front/src/admin/components/settings/TaxonomiesMenu.tsx @@ -1,14 +1,14 @@ import { RouteOutlined, StyleOutlined } from '@mui/icons-material'; import { Drawer, ListItemIcon, ListItemText, MenuItem, MenuList } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { LockPattern } from 'mdi-material-ui'; import * as React from 'react'; import { Link, useLocation } from 'react-router'; +import { CSSObject } from 'tss-react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../components/i18n'; -import type { Theme } from '../../../components/Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ drawer: { minHeight: '100vh', width: 200, @@ -17,7 +17,7 @@ const useStyles = makeStyles((theme: Theme) => ({ padding: 0, backgroundColor: theme.palette.background.nav, }, - toolbar: theme.mixins.toolbar, + toolbar: theme.mixins.toolbar as CSSObject, item: { paddingTop: 10, paddingBottom: 10, @@ -26,7 +26,7 @@ const useStyles = makeStyles((theme: Theme) => ({ const DefinitionMenu: React.FC = () => { const location = useLocation(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); return ( ({ +const useStyles = makeStyles()(() => ({ field: { marginBottom: 20, }, @@ -36,7 +36,7 @@ const ThemeForm: React.FC = ({ }, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { diff --git a/openbas-front/src/admin/components/settings/attack_patterns/AttackPatterns.js b/openbas-front/src/admin/components/settings/attack_patterns/AttackPatterns.js index f8b7a81415..0dc1703e06 100644 --- a/openbas-front/src/admin/components/settings/attack_patterns/AttackPatterns.js +++ b/openbas-front/src/admin/components/settings/attack_patterns/AttackPatterns.js @@ -1,7 +1,7 @@ import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { LockPattern } from 'mdi-material-ui'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { searchAttackPatterns } from '../../../../actions/AttackPattern'; import Breadcrumbs from '../../../../components/Breadcrumbs'; @@ -14,7 +14,7 @@ import TaxonomiesMenu from '../TaxonomiesMenu'; import AttackPatternPopover from './AttackPatternPopover'; import CreateAttackPattern from './CreateAttackPattern'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -62,7 +62,7 @@ const inlineStyles = { const AttackPatterns = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const { killChainPhasesMap } = useHelper(helper => ({ killChainPhasesMap: helper.getKillChainPhasesMap(), diff --git a/openbas-front/src/admin/components/settings/attack_patterns/CreateAttackPattern.js b/openbas-front/src/admin/components/settings/attack_patterns/CreateAttackPattern.js index 178d62a32b..21e9e483d2 100644 --- a/openbas-front/src/admin/components/settings/attack_patterns/CreateAttackPattern.js +++ b/openbas-front/src/admin/components/settings/attack_patterns/CreateAttackPattern.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addAttackPattern } from '../../../../actions/AttackPattern'; import Drawer from '../../../../components/common/Drawer'; @@ -87,5 +87,5 @@ CreateAttackPattern.propTypes = { export default R.compose( connect(null, { addAttackPattern }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateAttackPattern); diff --git a/openbas-front/src/admin/components/settings/data_ingestion/XlsMappers.tsx b/openbas-front/src/admin/components/settings/data_ingestion/XlsMappers.tsx index 27d0bbb0f5..70758e5ea3 100644 --- a/openbas-front/src/admin/components/settings/data_ingestion/XlsMappers.tsx +++ b/openbas-front/src/admin/components/settings/data_ingestion/XlsMappers.tsx @@ -1,7 +1,7 @@ import { TableViewOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { searchMappers } from '../../../../actions/mapper/mapper-actions'; import Breadcrumbs from '../../../../components/Breadcrumbs'; @@ -17,7 +17,7 @@ import ImportUploaderMapper from './ImportUploaderMapper'; import XlsMapperCreation from './xls_mapper/XlsMapperCreation'; import XlsMapperPopover from './XlsMapperPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { padding: '0 200px 50px 0', }, @@ -53,7 +53,7 @@ const inlineStyles: Record = { const XlsMappers = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Headers diff --git a/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/MapperForm.tsx b/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/MapperForm.tsx index ebf3542eca..05fd828645 100644 --- a/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/MapperForm.tsx +++ b/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/MapperForm.tsx @@ -1,10 +1,10 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Add } from '@mui/icons-material'; import { Button, IconButton, TextField, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import * as React from 'react'; import { Controller, SubmitHandler, useFieldArray, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { useFormatter } from '../../../../../components/i18n'; @@ -14,7 +14,7 @@ import { zodImplement } from '../../../../../utils/Zod'; import RulesContractContent from './RulesContractContent'; import XlsMapperTestDialog from './XlsMapperTestDialog'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ importerStyle: { display: 'flex', alignItems: 'center', @@ -43,7 +43,7 @@ const MapperForm: React.FC = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const ruleAttributeZodObject = z.object({ rule_attribute_name: z.string().min(1, { message: t('Should not be empty') }), diff --git a/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/RulesContractContent.tsx b/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/RulesContractContent.tsx index 637e11b402..4de0478c83 100644 --- a/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/RulesContractContent.tsx +++ b/openbas-front/src/admin/components/settings/data_ingestion/xls_mapper/RulesContractContent.tsx @@ -16,12 +16,11 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; -import classNames from 'classnames'; import { CogOutline, InformationOutline } from 'mdi-material-ui'; import { useEffect, useState } from 'react'; import * as React from 'react'; import { Controller, FieldArrayWithId, useFieldArray, UseFieldArrayRemove, UseFormReturn } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { ContractElement, InjectorContractConverted } from '../../../../../actions/injector_contracts/InjectorContract'; import { directFetchInjectorContract } from '../../../../../actions/InjectorContracts'; @@ -30,7 +29,7 @@ import InjectContractComponent from '../../../../../components/InjectContractCom import RegexComponent from '../../../../../components/RegexComponent'; import type { ImportMapperAddInput } from '../../../../../utils/api-types'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ rulesArray: { gap: '10px', width: '100%', @@ -66,7 +65,7 @@ const RulesContractContent: React.FC = ({ remove, }) => { const { t, tPick } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); // Fetching data @@ -178,7 +177,7 @@ const RulesContractContent: React.FC = ({ key={field.id} variant="outlined" style={{ width: '100%', marginBottom: '10px' }} - className={classNames({ + className={cx({ [classes.red]: !!errors.import_mapper_inject_importers?.[index], })} > @@ -386,7 +385,6 @@ const RulesContractContent: React.FC = ({ - ({ +const useStyles = makeStyles()(() => ({ createButton: { position: 'fixed', bottom: 30, @@ -23,7 +23,7 @@ interface Props { } const XlsMapperCreation: React.FC = ({ onCreate }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/admin/components/settings/groups/CreateGroup.js b/openbas-front/src/admin/components/settings/groups/CreateGroup.js index 8e052df50c..43aabab3f4 100644 --- a/openbas-front/src/admin/components/settings/groups/CreateGroup.js +++ b/openbas-front/src/admin/components/settings/groups/CreateGroup.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addGroup } from '../../../../actions/Group'; import Drawer from '../../../../components/common/Drawer'; @@ -85,5 +85,5 @@ const select = state => ({ export default R.compose( connect(select, { addGroup }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateGroup); diff --git a/openbas-front/src/admin/components/settings/groups/Groups.js b/openbas-front/src/admin/components/settings/groups/Groups.js index 5e73fa9305..29d9528ba4 100644 --- a/openbas-front/src/admin/components/settings/groups/Groups.js +++ b/openbas-front/src/admin/components/settings/groups/Groups.js @@ -1,8 +1,8 @@ import { CheckCircleOutlined, GroupsOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { fetchExercises } from '../../../../actions/Exercise'; import { searchGroups } from '../../../../actions/Group'; @@ -19,7 +19,7 @@ import SecurityMenu from '../SecurityMenu'; import CreateGroup from './CreateGroup'; import GroupPopover from './GroupPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -77,7 +77,7 @@ const inlineStyles = { const Groups = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); useDataLoader(() => { diff --git a/openbas-front/src/admin/components/settings/kill_chain_phases/CreateKillChainPhase.js b/openbas-front/src/admin/components/settings/kill_chain_phases/CreateKillChainPhase.js index 0112dec5b5..ea7ce44e23 100644 --- a/openbas-front/src/admin/components/settings/kill_chain_phases/CreateKillChainPhase.js +++ b/openbas-front/src/admin/components/settings/kill_chain_phases/CreateKillChainPhase.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addKillChainPhase } from '../../../../actions/KillChainPhase'; import Drawer from '../../../../components/common/Drawer'; @@ -86,5 +86,5 @@ const select = state => ({ export default R.compose( connect(select, { addKillChainPhase }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateKillChainPhase); diff --git a/openbas-front/src/admin/components/settings/kill_chain_phases/KillChainPhases.js b/openbas-front/src/admin/components/settings/kill_chain_phases/KillChainPhases.js index 730888f6d0..4fb2a1c267 100644 --- a/openbas-front/src/admin/components/settings/kill_chain_phases/KillChainPhases.js +++ b/openbas-front/src/admin/components/settings/kill_chain_phases/KillChainPhases.js @@ -1,7 +1,7 @@ import { RouteOutlined } from '@mui/icons-material'; import { Chip, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { searchKillChainPhases } from '../../../../actions/KillChainPhase'; import Breadcrumbs from '../../../../components/Breadcrumbs'; @@ -13,7 +13,7 @@ import TaxonomiesMenu from '../TaxonomiesMenu'; import CreateKillChainPhase from './CreateKillChainPhase'; import KillChainPhasePopover from './KillChainPhasePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -65,7 +65,7 @@ const inlineStyles = { const KillChainPhases = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); // Headers diff --git a/openbas-front/src/admin/components/settings/policies/Policies.tsx b/openbas-front/src/admin/components/settings/policies/Policies.tsx index 810f104f3a..8fc5a0fb35 100644 --- a/openbas-front/src/admin/components/settings/policies/Policies.tsx +++ b/openbas-front/src/admin/components/settings/policies/Policies.tsx @@ -1,6 +1,6 @@ import { Grid, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchPlatformParameters, updatePlatformPolicies } from '../../../../actions/Application'; import type { LoggedHelper } from '../../../../actions/helper'; @@ -13,7 +13,7 @@ import useDataLoader from '../../../../utils/hooks/useDataLoader'; import SecurityMenu from '../SecurityMenu'; import PolicyForm from './PolicyForm'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -28,7 +28,7 @@ const useStyles = makeStyles(() => ({ })); const Policies: FunctionComponent = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); const { settings }: { settings: PlatformSettings } = useHelper((helper: LoggedHelper) => ({ diff --git a/openbas-front/src/admin/components/settings/tag_rules/TagRules.tsx b/openbas-front/src/admin/components/settings/tag_rules/TagRules.tsx index 49d8555fe6..6f5587db01 100644 --- a/openbas-front/src/admin/components/settings/tag_rules/TagRules.tsx +++ b/openbas-front/src/admin/components/settings/tag_rules/TagRules.tsx @@ -1,7 +1,7 @@ import { List, ListItem, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import { CSSProperties, useMemo, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { TagHelper, UserHelper } from '../../../../actions/helper'; import { searchTagRules } from '../../../../actions/tag_rules/tagrule-actions'; @@ -20,7 +20,7 @@ import { TagRuleOutput } from '../../../../utils/api-types'; import TagRuleCreate from './TagRuleCreate'; import TagRulePopover from './TagRulePopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -48,7 +48,7 @@ const inlineStyles: Record = { const TagRules = () => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const { userAdmin } = useHelper((helper: TagHelper & UserHelper) => ({ userAdmin: helper.getMe()?.user_admin ?? false, diff --git a/openbas-front/src/admin/components/settings/tags/CreateTag.js b/openbas-front/src/admin/components/settings/tags/CreateTag.js index b21de6e661..d7ee1c45c4 100644 --- a/openbas-front/src/admin/components/settings/tags/CreateTag.js +++ b/openbas-front/src/admin/components/settings/tags/CreateTag.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addTag } from '../../../../actions/Tag'; import Drawer from '../../../../components/common/Drawer'; @@ -82,5 +82,5 @@ CreateTag.propTypes = { export default R.compose( connect(null, { addTag }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateTag); diff --git a/openbas-front/src/admin/components/settings/tags/Tags.js b/openbas-front/src/admin/components/settings/tags/Tags.js index ad3de1330c..ef474a7593 100644 --- a/openbas-front/src/admin/components/settings/tags/Tags.js +++ b/openbas-front/src/admin/components/settings/tags/Tags.js @@ -1,7 +1,7 @@ import { LabelOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { searchTags } from '../../../../actions/Tag'; import Breadcrumbs from '../../../../components/Breadcrumbs'; @@ -13,7 +13,7 @@ import TaxonomiesMenu from '../TaxonomiesMenu'; import CreateTag from './CreateTag'; import TagPopover from './TagPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -51,7 +51,7 @@ const inlineStyles = { const Tags = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Headers diff --git a/openbas-front/src/admin/components/settings/users/CreateUser.js b/openbas-front/src/admin/components/settings/users/CreateUser.js index 1b931b3bd0..ebcff22ff8 100644 --- a/openbas-front/src/admin/components/settings/users/CreateUser.js +++ b/openbas-front/src/admin/components/settings/users/CreateUser.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Fab, Slide } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component, forwardRef } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addUser } from '../../../../actions/User'; import Drawer from '../../../../components/common/Drawer'; @@ -97,5 +97,5 @@ CreateUser.propTypes = { export default R.compose( connect(null, { addUser }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateUser); diff --git a/openbas-front/src/admin/components/settings/users/Users.js b/openbas-front/src/admin/components/settings/users/Users.js index ee818a7c61..e7b0c70780 100644 --- a/openbas-front/src/admin/components/settings/users/Users.js +++ b/openbas-front/src/admin/components/settings/users/Users.js @@ -1,8 +1,8 @@ import { CheckCircleOutlined, PersonOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { fetchOrganizations } from '../../../../actions/Organization'; import { searchUsers } from '../../../../actions/User'; @@ -18,7 +18,7 @@ import SecurityMenu from '../SecurityMenu'; import CreateUser from './CreateUser'; import UserPopover from './UserPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: 0, padding: '0 200px 50px 0', @@ -69,7 +69,7 @@ const inlineStyles = { const Users = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const { tagsMap, organizationsMap } = useHelper(helper => ({ diff --git a/openbas-front/src/admin/components/simulations/ExerciseList.tsx b/openbas-front/src/admin/components/simulations/ExerciseList.tsx index 26abc09750..bde4f4b776 100644 --- a/openbas-front/src/admin/components/simulations/ExerciseList.tsx +++ b/openbas-front/src/admin/components/simulations/ExerciseList.tsx @@ -1,9 +1,9 @@ import { HubOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; import { CSSProperties, FunctionComponent, useEffect, useState } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExercisesGlobalScores } from '../../../actions/exercises/exercise-action'; import { QueryableHelpers } from '../../../components/common/queryable/QueryableHelpers'; @@ -18,7 +18,7 @@ import type { ExercisesGlobalScoresOutput, ExerciseSimple, ExpectationResultsByT import AtomicTestingResult from '../atomic_testings/atomic_testing/AtomicTestingResult'; import ExerciseStatus from './simulation/ExerciseStatus'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -104,7 +104,7 @@ const ExerciseList: FunctionComponent = ({ isGlobalScoreAsync = false, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const inlineStyles = getInlineStyles(variant); const { nsdt, vnsdt } = useFormatter(); diff --git a/openbas-front/src/admin/components/simulations/simulation/AnimationMenu.tsx b/openbas-front/src/admin/components/simulations/simulation/AnimationMenu.tsx index 6c6da1fa7b..41344dbda4 100644 --- a/openbas-front/src/admin/components/simulations/simulation/AnimationMenu.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/AnimationMenu.tsx @@ -1,14 +1,14 @@ import { FactCheckOutlined, MailOutlined, NoteAltOutlined, TheatersOutlined } from '@mui/icons-material'; import { Drawer, ListItemIcon, ListItemText, MenuItem, MenuList } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; import { Link, useLocation } from 'react-router'; +import { CSSObject } from 'tss-react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import type { Exercise } from '../../../../utils/api-types'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ drawer: { minHeight: '100vh', width: 200, @@ -16,7 +16,7 @@ const useStyles = makeStyles(theme => ({ overflow: 'auto', padding: 0, }, - toolbar: theme.mixins.toolbar, + toolbar: theme.mixins.toolbar as CSSObject, item: { paddingTop: 10, paddingBottom: 10, @@ -29,7 +29,7 @@ interface Props { const AnimationMenu: React.FC = ({ exerciseId }) => { const location = useLocation(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); return ( diff --git a/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts b/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts index e7978a40a3..85f9746025 100644 --- a/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts +++ b/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts @@ -21,7 +21,7 @@ import type { InjectBulkProcessingInput, InjectBulkUpdateInputs, InjectsImportInput, - InjectTestStatus, + InjectTestStatusOutput, SearchPaginationInput, } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; @@ -71,7 +71,7 @@ const injectContextForExercise = (exercise: Exercise) => { onBulkDeleteInjects(param: InjectBulkProcessingInput): Promise { return bulkDeleteInjectsSimple(param).then((result: { data: Inject[] }) => result?.data); }, - bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatus[] }> { + bulkTestInjects(param: InjectBulkProcessingInput): Promise<{ uri: string; data: InjectTestStatusOutput[] }> { return bulkTestInjects(param).then(result => ({ uri: `/admin/simulations/${exercise.exercise_id}/tests`, data: result.data, diff --git a/openbas-front/src/admin/components/simulations/simulation/ExerciseDefinition.tsx b/openbas-front/src/admin/components/simulations/simulation/ExerciseDefinition.tsx index 89b1222408..9e93d7d63b 100644 --- a/openbas-front/src/admin/components/simulations/simulation/ExerciseDefinition.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/ExerciseDefinition.tsx @@ -1,6 +1,6 @@ import { Grid, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { ExercisesHelper } from '../../../../actions/exercises/exercise-helper'; import { useFormatter } from '../../../../components/i18n'; @@ -13,7 +13,7 @@ import ExerciseVariables from './variables/ExerciseVariables'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ gridContainer: { marginBottom: 20, }, @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => ({ const ExerciseDefinition = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { exerciseId } = useParams() as { exerciseId: Exercise['exercise_id'] }; // Fetching data diff --git a/openbas-front/src/admin/components/simulations/simulation/ExerciseHeader.tsx b/openbas-front/src/admin/components/simulations/simulation/ExerciseHeader.tsx index 7305c5ae4f..d11c648398 100644 --- a/openbas-front/src/admin/components/simulations/simulation/ExerciseHeader.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/ExerciseHeader.tsx @@ -1,14 +1,14 @@ import { CancelOutlined, PauseOutlined, PlayArrowOutlined, RestartAltOutlined } from '@mui/icons-material'; import { Button, Dialog, DialogActions, DialogContent, DialogContentText, Tooltip, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { useState } from 'react'; import { useNavigate, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { updateExerciseStatus } from '../../../../actions/Exercise'; import type { ExercisesHelper } from '../../../../actions/exercises/exercise-helper'; import Transition from '../../../../components/common/Transition'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import { useHelper } from '../../../../store'; import type { Exercise, Exercise as ExerciseType } from '../../../../utils/api-types'; import { usePermissions } from '../../../../utils/Exercise'; @@ -17,7 +17,7 @@ import { truncate } from '../../../../utils/String'; import ExercisePopover, { ExerciseActionPopover } from './ExercisePopover'; import ExerciseStatus from './ExerciseStatus'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ title: { float: 'left', marginRight: 10, @@ -188,8 +188,8 @@ const Buttons = ({ exerciseId, exerciseStatus, exerciseName }: { const ExerciseHeader = () => { // Standard hooks - const theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const navigate = useNavigate(); const { exerciseId } = useParams() as { exerciseId: ExerciseType['exercise_id'] }; diff --git a/openbas-front/src/admin/components/simulations/simulation/ExerciseStatus.tsx b/openbas-front/src/admin/components/simulations/simulation/ExerciseStatus.tsx index ab849b42b6..1b39f26dcd 100644 --- a/openbas-front/src/admin/components/simulations/simulation/ExerciseStatus.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/ExerciseStatus.tsx @@ -1,12 +1,12 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../components/i18n'; import { Exercise } from '../../../../utils/api-types'; import { inlineStylesColors } from '../../../../utils/Colors'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { marginTop: 2, fontSize: 14, @@ -39,7 +39,7 @@ const ExerciseStatus: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'list' ? classes.chipInList : classes.chip; switch (exerciseStatus) { case 'SCHEDULED': diff --git a/openbas-front/src/admin/components/simulations/simulation/Index.tsx b/openbas-front/src/admin/components/simulations/simulation/Index.tsx index 91ff72dcff..fac8e5d9c8 100644 --- a/openbas-front/src/admin/components/simulations/simulation/Index.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/Index.tsx @@ -1,7 +1,7 @@ import { Alert, AlertTitle, Box, Tab, Tabs } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, lazy, Suspense, useState } from 'react'; import { Link, Navigate, Route, Routes, useLocation, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExercise } from '../../../../actions/Exercise'; import type { ExercisesHelper } from '../../../../actions/exercises/exercise-helper'; @@ -34,7 +34,7 @@ const Logs = lazy(() => import('./logs/Logs')); const Chat = lazy(() => import('./chat/Chat')); const Validations = lazy(() => import('./validation/Validations')); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ scheduling: { display: 'flex', margin: '-35px 8px 0 0', @@ -48,7 +48,7 @@ const IndexComponent: FunctionComponent<{ exercise: ExerciseType }> = ({ }) => { const { t, fldt } = useFormatter(); const location = useLocation(); - const classes = useStyles(); + const { classes } = useStyles(); const permissionsContext: PermissionsContextType = { permissions: usePermissions(exercise.exercise_id), }; diff --git a/openbas-front/src/admin/components/simulations/simulation/chat/Chat.js b/openbas-front/src/admin/components/simulations/simulation/chat/Chat.js index f1bc4b8fec..c58f4a48c7 100644 --- a/openbas-front/src/admin/components/simulations/simulation/chat/Chat.js +++ b/openbas-front/src/admin/components/simulations/simulation/chat/Chat.js @@ -1,10 +1,10 @@ -import { makeStyles } from '@mui/styles'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../components/i18n'; import AnimationMenu from '../AnimationMenu'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '10px 0 50px 0', padding: '0 100px 0 0', @@ -12,7 +12,7 @@ const useStyles = makeStyles(() => ({ })); const Chat = () => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { exerciseId } = useParams(); return ( diff --git a/openbas-front/src/admin/components/simulations/simulation/controls/Comcheck.js b/openbas-front/src/admin/components/simulations/simulation/controls/Comcheck.js index e08645931d..e1e6ddda4e 100644 --- a/openbas-front/src/admin/components/simulations/simulation/controls/Comcheck.js +++ b/openbas-front/src/admin/components/simulations/simulation/controls/Comcheck.js @@ -1,9 +1,10 @@ import { CastOutlined, CheckCircleOutlineOutlined, HistoryToggleOffOutlined, PersonOutlined } from '@mui/icons-material'; import { Grid, LinearProgress, linearProgressClasses, List, ListItem, ListItemIcon, ListItemText, Paper, Typography } from '@mui/material'; -import { makeStyles, styled } from '@mui/styles'; +import { styled } from '@mui/material/styles'; import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchComcheck, fetchComcheckStatuses } from '../../../../../actions/Comcheck'; import { fetchOrganizations } from '../../../../../actions/Organization'; @@ -19,7 +20,7 @@ import TagsFilter from '../../../common/filters/TagsFilter'; import ComcheckState from './ComcheckState'; import ComcheckStatusState from './ComcheckStatusState'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ parameters: { padding: '20px 15px 0 15px', float: 'left', @@ -193,7 +194,7 @@ const iconStatus = (status) => { const Comcheck = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const [currentDate, setCurrentDate] = useState(new Date()); useEffect(() => { diff --git a/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckState.js b/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckState.js index 3fd8defbac..1cdfe70089 100644 --- a/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckState.js +++ b/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckState.js @@ -1,8 +1,8 @@ import { Chip } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import inject18n from '../../../../../components/i18n'; @@ -99,4 +99,4 @@ ComcheckState.propTypes = { state: PropTypes.string, }; -export default R.compose(inject18n, withStyles(styles))(ComcheckState); +export default R.compose(inject18n, Component => withStyles(Component, styles))(ComcheckState); diff --git a/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckStatusState.js b/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckStatusState.js index f7c9764489..e0e9d9e312 100644 --- a/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckStatusState.js +++ b/openbas-front/src/admin/components/simulations/simulation/controls/ComcheckStatusState.js @@ -1,8 +1,8 @@ import { Chip } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import inject18n from '../../../../../components/i18n'; @@ -98,4 +98,4 @@ ComcheckStatusState.propTypes = { state: PropTypes.string, }; -export default R.compose(inject18n, withStyles(styles))(ComcheckStatusState); +export default R.compose(inject18n, Component => withStyles(Component, styles))(ComcheckStatusState); diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.js b/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.js deleted file mode 100644 index ec3fdd6b6e..0000000000 --- a/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.js +++ /dev/null @@ -1,112 +0,0 @@ -import { Add } from '@mui/icons-material'; -import { Drawer, Fab } from '@mui/material'; -import { withStyles, withTheme } from '@mui/styles'; -import * as PropTypes from 'prop-types'; -import * as R from 'ramda'; -import { Component } from 'react'; -import { connect } from 'react-redux'; - -import { fetchExercises } from '../../../../../actions/Exercise'; -import { fetchInjectorContract } from '../../../../../actions/InjectorContracts'; -import { storeHelper } from '../../../../../actions/Schema'; -import inject18n from '../../../../../components/i18n'; -import QuickInject, { EMAIL_CONTRACT } from './QuickInject'; - -const styles = theme => ({ - createButton: { - position: 'fixed', - bottom: 30, - right: 230, - }, - text: { - fontSize: 15, - color: theme.palette.primary.main, - fontWeight: 500, - }, -}); - -class CreateQuickInject extends Component { - constructor(props) { - super(props); - this.state = { open: false }; - } - - componentDidMount() { - this.props.fetchInjectorContract(EMAIL_CONTRACT); - } - - handleOpen() { - this.setState({ open: true }); - } - - handleClose() { - this.setState({ open: false }); - } - - render() { - const { classes, exercise, injectorContract, exercisesMap, tagsMap } = this.props; - const { open } = this.state; - return ( - <> - - - - {injectorContract - && ( - - - - )} - - ); - } -} - -CreateQuickInject.propTypes = { - t: PropTypes.func, - exercise: PropTypes.object, - exercisesMap: PropTypes.object, - tagsMap: PropTypes.object, - injectorContract: PropTypes.object, -}; - -const select = (state) => { - const helper = storeHelper(state); - return { - exercisesMap: helper.getExercisesMap(), - tagsMap: helper.getTagsMap(), - injectorContract: helper.getInjectorContract(EMAIL_CONTRACT), - }; -}; - -export default R.compose( - connect(select, { - fetchExercises, - fetchInjectorContract, - }), - inject18n, - withTheme, - withStyles(styles), -)(CreateQuickInject); diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.tsx new file mode 100644 index 0000000000..97fcc5eb3b --- /dev/null +++ b/openbas-front/src/admin/components/simulations/simulation/injects/CreateQuickInject.tsx @@ -0,0 +1,75 @@ +import { Add } from '@mui/icons-material'; +import { Drawer, Fab } from '@mui/material'; +import { FunctionComponent, useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; + +import { InjectorContractHelper } from '../../../../../actions/injector_contracts/injector-contract-helper'; +import { fetchInjectorContract } from '../../../../../actions/InjectorContracts'; +import { useHelper } from '../../../../../store.js'; +import type { Exercise, InjectorContract } from '../../../../../utils/api-types'; +import { useAppDispatch } from '../../../../../utils/hooks.js'; +import QuickInject, { EMAIL_CONTRACT } from './QuickInject'; + +const useStyles = makeStyles()(theme => ({ + createButton: { + position: 'fixed', + bottom: 30, + right: 230, + }, + text: { + fontSize: 15, + color: theme.palette.primary.main, + fontWeight: 500, + }, +})); + +interface Props { + exercise: Exercise; +} + +const CreateQuickInject: FunctionComponent = ({ exercise }) => { + const dispatch = useAppDispatch(); + const { classes } = useStyles(); + const [open, setOpen] = useState(false); + const { injectorContract }: { injectorContract: InjectorContract } = useHelper((helper: InjectorContractHelper) => ({ + injectorContract: helper.getInjectorContract(EMAIL_CONTRACT), + })); + useEffect(() => { + dispatch(fetchInjectorContract(EMAIL_CONTRACT)); + }, []); + + return ( + <> + setOpen(true)} + color="primary" + aria-label="Add" + className={classes.createButton} + disabled={exercise.exercise_status !== 'RUNNING'} + > + + + {injectorContract + && ( + setOpen(false)} + elevation={1} + disableEnforceFocus={true} + > + setOpen(false)} + /> + + )} + + ); +}; + +export default CreateQuickInject; diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx index b979df9b24..3f54093328 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/injects/ExerciseInjects.tsx @@ -1,8 +1,8 @@ import { BarChartOutlined, ReorderOutlined, ViewTimelineOutlined } from '@mui/icons-material'; import { Grid, Paper, ToggleButton, ToggleButtonGroup, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useState } from 'react'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseArticles } from '../../../../../actions/channels/article-action'; import type { ArticlesHelper } from '../../../../../actions/channels/article-helper'; @@ -27,7 +27,7 @@ import ExerciseDistributionScoreOverTimeByTeam from '../overview/ExerciseDistrib import ExerciseDistributionScoreOverTimeByTeamInPercentage from '../overview/ExerciseDistributionScoreOverTimeByTeamInPercentage'; import teamContextForExercise from '../teams/teamContextForExercise'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paperChart: { position: 'relative', padding: '0 20px 0 0', @@ -39,7 +39,7 @@ const useStyles = makeStyles(() => ({ const ExerciseInjects: FunctionComponent = () => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const availableButtons = ['chain', 'list', 'distribution']; const { exerciseId } = useParams() as { exerciseId: Exercise['exercise_id'] }; diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/InjectIndex.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/InjectIndex.tsx index 1b9bba489a..263d8c2d3d 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/InjectIndex.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/injects/InjectIndex.tsx @@ -1,7 +1,7 @@ import { Box, Tab, Tabs } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, Suspense, useEffect, useState } from 'react'; import { Link, Route, Routes, useLocation, useParams, useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjectResultOverviewOutput } from '../../../../../actions/atomic_testings/atomic-testing-actions'; import { fetchExercise } from '../../../../../actions/Exercise'; @@ -24,7 +24,7 @@ import { InjectResultOverviewOutputContext } from '../../../atomic_testings/Inje import { PermissionsContext, PermissionsContextType } from '../../../common/Context'; import InjectHeader from '../../../injects/InjectHeader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 30, fontSize: 13, @@ -42,7 +42,7 @@ const InjectIndexComponent: FunctionComponent<{ exercise: ExerciseType; injectRe }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // Context const permissionsContext: PermissionsContextType = { diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/QuickInject.js b/openbas-front/src/admin/components/simulations/simulation/injects/QuickInject.js index d12b884f6d..eb552b2676 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/QuickInject.js +++ b/openbas-front/src/admin/components/simulations/simulation/injects/QuickInject.js @@ -25,7 +25,6 @@ import { Switch, Typography, } from '@mui/material'; -import { withStyles } from '@mui/styles'; import arrayMutators from 'final-form-arrays'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; @@ -33,6 +32,7 @@ import { Component, forwardRef } from 'react'; import { Form } from 'react-final-form'; import { FieldArray } from 'react-final-form-arrays'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../../../../actions/Document'; import { addInjectForExercise } from '../../../../../actions/Inject'; @@ -1447,8 +1447,6 @@ QuickInject.propTypes = { handleClose: PropTypes.func, injectorContract: PropTypes.object, fetchDocuments: PropTypes.func, - exercisesMap: PropTypes.object, - tagsMap: PropTypes.object, }; const select = (state, ownProps) => { @@ -1471,5 +1469,5 @@ export default R.compose( addInject: addInjectForExercise, }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(QuickInject); diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/asset_groups/InjectAddAssetGroups.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/asset_groups/InjectAddAssetGroups.tsx index 545756c425..0d977e67a1 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/asset_groups/InjectAddAssetGroups.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/injects/asset_groups/InjectAddAssetGroups.tsx @@ -1,14 +1,13 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import AssetGroupDialogAdding from '../../../../assets/asset_groups/AssetGroupDialogAdding'; import { PermissionsContext } from '../../../../common/Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -30,7 +29,7 @@ const InjectAddAssetGroups: FunctionComponent = ({ onSubmit, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/simulations/simulation/injects/endpoints/InjectAddEndpoints.tsx b/openbas-front/src/admin/components/simulations/simulation/injects/endpoints/InjectAddEndpoints.tsx index e571432de5..a605cad0d6 100644 --- a/openbas-front/src/admin/components/simulations/simulation/injects/endpoints/InjectAddEndpoints.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/injects/endpoints/InjectAddEndpoints.tsx @@ -1,14 +1,13 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import EndpointsDialogAdding from '../../../../assets/endpoints/EndpointsDialogAdding'; import { PermissionsContext } from '../../../../common/Context'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -36,7 +35,7 @@ const InjectAddEndpoints: FunctionComponent = ({ payloadArch, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/admin/components/simulations/simulation/logs/Logs.js b/openbas-front/src/admin/components/simulations/simulation/logs/Logs.js index 8d722be763..9ca6c73add 100644 --- a/openbas-front/src/admin/components/simulations/simulation/logs/Logs.js +++ b/openbas-front/src/admin/components/simulations/simulation/logs/Logs.js @@ -1,10 +1,11 @@ import { EditOutlined, ExpandMoreOutlined, RateReviewOutlined } from '@mui/icons-material'; import { Accordion, AccordionDetails, AccordionSummary, Card, CardContent, CardHeader, IconButton, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { useEffect, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { addLog, fetchLogs } from '../../../../../actions/Log'; import { fetchExerciseObjectives } from '../../../../../actions/Objective'; @@ -18,7 +19,7 @@ import AnimationMenu from '../AnimationMenu'; import LogForm from './LogForm'; import LogPopover from './LogPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ card: { width: '100%', height: '100%', @@ -33,7 +34,7 @@ const useStyles = makeStyles(() => ({ })); const Logs = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const theme = useTheme(); const { t, nsdt } = useFormatter(); diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/Communication.js b/openbas-front/src/admin/components/simulations/simulation/mails/Communication.js index 45edfc6786..da753df9eb 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/Communication.js +++ b/openbas-front/src/admin/components/simulations/simulation/mails/Communication.js @@ -1,16 +1,17 @@ import { AttachFileRounded, ExpandLess, ExpandMore } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, IconButton } from '@mui/material'; import { lightBlue } from '@mui/material/colors'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import purify from 'dompurify'; import parse from 'html-react-parser'; import { useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../../../components/i18n'; import TruncatedText from '../../../../../components/TruncatedText'; import { resolveUserNames, truncate } from '../../../../../utils/String'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ card: { margin: '0 0 20px 0', }, @@ -25,7 +26,7 @@ const Communication = (props) => { const [expand, setExpand] = useState(false); const expandContent = () => setExpand(!expand); const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const { t, nsdt } = useFormatter(); const limit = 200; let isHtml = false; diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/Inject.js b/openbas-front/src/admin/components/simulations/simulation/mails/Inject.js index e707c6357a..892881a507 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/Inject.js +++ b/openbas-front/src/admin/components/simulations/simulation/mails/Inject.js @@ -1,10 +1,10 @@ import { ReplyOutlined } from '@mui/icons-material'; import { Button, Dialog, DialogContent, DialogTitle, Grid, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchInjectCommunications } from '../../../../../actions/Communication'; import { executeInject, fetchExerciseInjects } from '../../../../../actions/Inject'; @@ -19,7 +19,7 @@ import AnimationMenu from '../AnimationMenu'; import Communication from './Communication'; import CommunicationForm from './CommunicationForm'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '0 0 50px 0', padding: '0 200px 0 0', @@ -34,7 +34,7 @@ const useStyles = makeStyles(() => ({ const Inject = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const [reply, setReply] = useState(null); const { t, fndt, fldt } = useFormatter(); diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByInject.tsx b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByInject.tsx index f91268ddfa..2cda8f587f 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByInject.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByInject.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import { fetchExerciseInjects } from '../../../../../actions/Inject'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, Inject } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -24,7 +23,7 @@ const MailDistributionByInject: FunctionComponent = ({ // Standard hooks const { t } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injects } = useHelper((helper: InjectHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByPlayer.tsx b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByPlayer.tsx index a9698ef0ea..888677fbaa 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByPlayer.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByPlayer.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -9,7 +9,6 @@ import type { UserHelper } from '../../../../../actions/helper'; import { fetchPlayers } from '../../../../../actions/User'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Communication, Exercise, User } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -27,7 +26,7 @@ const MailDistributionByPlayer: FunctionComponent = ({ // Standard hooks const { t } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { communications, usersMap } = useHelper((helper: CommunicationHelper & UserHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByTeam.tsx b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByTeam.tsx index 256a8a5938..369ebdc54b 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByTeam.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionByTeam.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import { fetchExerciseTeams } from '../../../../../actions/Exercise'; import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, Team } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -25,7 +24,7 @@ const MailDistributionByTeam: FunctionComponent = ({ // Standard hooks const { t } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { teams } = useHelper((helper: TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeChart.tsx b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeChart.tsx index 182c5754a9..01b9536dd5 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeChart.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeChart.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import { fetchExerciseCommunications } from '../../../../../actions/Communicatio import type { CommunicationHelper } from '../../../../../actions/communications/communication-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Communication, Exercise } from '../../../../../utils/api-types'; import { areaChartOptions } from '../../../../../utils/Charts'; @@ -24,7 +23,7 @@ const MailDistributionOverTimeChart: FunctionComponent = ({ // Standard hooks const { t, nsdt } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { communications } = useHelper((helper: CommunicationHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeLine.tsx b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeLine.tsx index 58f2c8a067..fc896c9f09 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeLine.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/mails/MailDistributionOverTimeLine.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import { fetchExerciseTeams } from '../../../../../actions/Exercise'; import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Communication, Exercise, Team } from '../../../../../utils/api-types'; import { lineChartOptions } from '../../../../../utils/Charts'; @@ -25,7 +24,7 @@ const MailDistributionOverTime: FunctionComponent = ({ // Standard hooks const { t, nsdt } = useFormatter(); const dispatch = useAppDispatch(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { teams } = useHelper((helper: TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/mails/Mails.js b/openbas-front/src/admin/components/simulations/simulation/mails/Mails.js index 9a850350a6..6c7f1b83f0 100644 --- a/openbas-front/src/admin/components/simulations/simulation/mails/Mails.js +++ b/openbas-front/src/admin/components/simulations/simulation/mails/Mails.js @@ -1,9 +1,9 @@ import { BarChartOutlined, KeyboardArrowRight, ReorderOutlined } from '@mui/icons-material'; import { Chip, Grid, List, ListItem, ListItemButton, ListItemIcon, ListItemSecondaryAction, ListItemText, Paper, ToggleButton, ToggleButtonGroup, Tooltip, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseInjects } from '../../../../../actions/Inject'; import { useFormatter } from '../../../../../components/i18n'; @@ -24,7 +24,7 @@ import MailDistributionByTeam from './MailDistributionByTeam'; import MailDistributionOverTimeChart from './MailDistributionOverTimeChart'; import MailDistributionOverTimeLine from './MailDistributionOverTimeLine'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { paddingLeft: 10, textTransform: 'uppercase', @@ -180,7 +180,7 @@ const inlineStyles = { const Mails = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t, fndt } = useFormatter(); const [viewMode, setViewMode] = useState('list'); diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/DistributionUtils.ts b/openbas-front/src/admin/components/simulations/simulation/overview/DistributionUtils.ts index 062909000d..7c949fe9ed 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/DistributionUtils.ts +++ b/openbas-front/src/admin/components/simulations/simulation/overview/DistributionUtils.ts @@ -1,6 +1,6 @@ +import { Theme } from '@mui/material'; import * as R from 'ramda'; -import type { Theme } from '../../../../../components/Theme'; import type { Organization, Team } from '../../../../../utils/api-types'; import { colors } from '../../../../../utils/Charts'; diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseComponent.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseComponent.tsx index 29419d8009..f945082f82 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseComponent.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseComponent.tsx @@ -1,8 +1,8 @@ import { Grid, Paper, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { useEffect, useState } from 'react'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseExpectationResult, fetchExerciseInjectExpectationResults, searchExerciseInjects } from '../../../../../actions/exercises/exercise-action'; import type { ExercisesHelper } from '../../../../../actions/exercises/exercise-helper'; @@ -22,7 +22,7 @@ import ExerciseDistribution from './ExerciseDistribution'; // Deprecated - https://mui.com/system/styles/basics/ // Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ gridContainer: { marginBottom: 20, }, @@ -37,7 +37,7 @@ const useStyles = makeStyles(() => ({ const ExerciseComponent = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Fetching data const { exerciseId } = useParams() as { exerciseId: Exercise['exercise_id'] }; @@ -96,7 +96,7 @@ const ExerciseComponent = () => { {injectResults && resultAttackPatternIds.length > 0 && ( - + {t('MITRE ATT&CK Results')} diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistribution.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistribution.tsx index 501d422f9c..d948bb9d2f 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistribution.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistribution.tsx @@ -1,6 +1,7 @@ import { Grid, Paper, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseInjectExpectations, fetchExerciseTeams } from '../../../../../actions/Exercise'; import type { ExercisesHelper } from '../../../../../actions/exercises/exercise-helper'; @@ -8,7 +9,6 @@ import { fetchExerciseInjects } from '../../../../../actions/Inject'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import { useFormatter } from '../../../../../components/i18n'; import Loader from '../../../../../components/Loader'; -import type { Theme } from '../../../../../components/Theme'; import arrowDark from '../../../../../static/images/misc/arrow_dark.png'; import arrowLight from '../../../../../static/images/misc/arrow_light.png'; import { useHelper } from '../../../../../store'; @@ -25,7 +25,7 @@ import ExerciseDistributionScoreOverTimeByInjectorContract from './ExerciseDistr import ExerciseDistributionScoreOverTimeByTeam from './ExerciseDistributionScoreOverTimeByTeam'; import ExerciseDistributionScoreOverTimeByTeamInPercentage from './ExerciseDistributionScoreOverTimeByTeamInPercentage'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ paperChart: { position: 'relative', padding: '0 20px 0 0', @@ -44,9 +44,9 @@ const ExerciseDistribution: FunctionComponent = ({ isReport = false, }) => { // Standard hooks - const theme = useTheme(); + const theme = useTheme(); const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const [loading, setLoading] = useState(true); diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionByInjectorContract.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionByInjectorContract.tsx index 5c8546a710..af6e55f93d 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionByInjectorContract.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionByInjectorContract.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectStore } from '../../../../../actions/injects/Inject'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -21,7 +20,7 @@ const ExerciseDistributionByInjectorContract: FunctionComponent = ({ }) => { // Standard hooks const { t, tPick } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectsMap, injectExpectations } = useHelper((helper: InjectHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByInject.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByInject.tsx index dd79566523..37c9434359 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByInject.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByInject.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -6,7 +6,6 @@ import Chart from 'react-apexcharts'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, Inject, InjectExpectation } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -20,7 +19,7 @@ const ExerciseDistributionScoreByInject: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectsMap, injectExpectations } = useHelper((helper: InjectHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByOrganization.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByOrganization.tsx index d46f6c51aa..6356e95490 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByOrganization.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByOrganization.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { OrganizationHelper, UserHelper } from '../../../../../actions/help import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation, Organization } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreByOrganization: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, organizations, organizationsMap, usersMap } = useHelper((helper: InjectHelper & OrganizationHelper & UserHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByPlayer.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByPlayer.tsx index 0d03290b36..a15c440a60 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByPlayer.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByPlayer.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { UserHelper } from '../../../../../actions/helper'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation, User } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreByPlayer: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, usersMap } = useHelper((helper: InjectHelper & UserHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeam.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeam.tsx index 6b42c870da..4f120ded36 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeam.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeam.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectHelper } from '../../../../../actions/injects/inject-helper' import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation, Team } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreByTeam: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, teams, teamsMap } = useHelper((helper: InjectHelper & TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeamInPercentage.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeamInPercentage.tsx index be54b926ec..0aaaf04a6d 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeamInPercentage.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreByTeamInPercentage.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectHelper } from '../../../../../actions/injects/inject-helper' import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation, Team } from '../../../../../utils/api-types'; import { horizontalBarsChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreByTeamInPercentage: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, teams, teamsMap } = useHelper((helper: InjectHelper & TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByInjectorContract.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByInjectorContract.tsx index d7b4f0ea0f..e61b360c5d 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByInjectorContract.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByInjectorContract.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectStore } from '../../../../../actions/injects/Inject'; import type { InjectHelper } from '../../../../../actions/injects/inject-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, Inject, InjectExpectation } from '../../../../../utils/api-types'; import { lineChartOptions } from '../../../../../utils/Charts'; @@ -21,7 +20,7 @@ const ExerciseDistributionScoreOverTimeByInjectorContract: FunctionComponent { // Standard hooks const { t, nsdt, tPick } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectsMap, injectExpectations }: { injectsMap: Record; injectExpectations: InjectExpectation[] } = useHelper((helper: InjectHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeam.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeam.tsx index a0371d0cdd..4b8b7c3356 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeam.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeam.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectHelper } from '../../../../../actions/injects/inject-helper' import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation } from '../../../../../utils/api-types'; import { lineChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreOverTimeByTeam: FunctionComponent = ({ }) => { // Standard hooks const { t, nsdt } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, teams, teamsMap } = useHelper((helper: InjectHelper & TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeamInPercentage.tsx b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeamInPercentage.tsx index 89bac49dbd..0467c8f59c 100644 --- a/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeamInPercentage.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/overview/ExerciseDistributionScoreOverTimeByTeamInPercentage.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -7,7 +7,6 @@ import type { InjectHelper } from '../../../../../actions/injects/inject-helper' import type { TeamsHelper } from '../../../../../actions/teams/team-helper'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import { useHelper } from '../../../../../store'; import type { Exercise, InjectExpectation } from '../../../../../utils/api-types'; import { lineChartOptions } from '../../../../../utils/Charts'; @@ -22,7 +21,7 @@ const ExerciseDistributionScoreOverTimeByTeamInPercentage: FunctionComponent { // Standard hooks const { t, nsdt } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); // Fetching data const { injectExpectations, teams, teamsMap } = useHelper((helper: InjectHelper & TeamsHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/tests/ExerciseTests.tsx b/openbas-front/src/admin/components/simulations/simulation/tests/ExerciseTests.tsx index a164b31364..23a46efb5b 100644 --- a/openbas-front/src/admin/components/simulations/simulation/tests/ExerciseTests.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/tests/ExerciseTests.tsx @@ -2,11 +2,11 @@ import { FunctionComponent } from 'react'; import { useParams } from 'react-router'; import { fetchInjectTestStatus, searchExerciseInjectTests } from '../../../../../actions/inject_test/inject-test-actions'; -import type { Exercise, InjectTestStatus } from '../../../../../utils/api-types'; +import type { Exercise, InjectTestStatusOutput } from '../../../../../utils/api-types'; import InjectTestList from '../../../injects/InjectTestList'; const ExerciseTests: FunctionComponent = () => { - const { exerciseId, statusId } = useParams() as { exerciseId: Exercise['exercise_id']; statusId: InjectTestStatus['status_id'] }; + const { exerciseId, statusId } = useParams() as { exerciseId: Exercise['exercise_id']; statusId: InjectTestStatusOutput['status_id'] }; return ( diff --git a/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeArea.tsx b/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeArea.tsx index cf0ec3120a..4cac672acf 100644 --- a/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeArea.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeArea.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -6,7 +6,6 @@ import Chart from 'react-apexcharts'; import type { InjectStore } from '../../../../../actions/injects/Inject'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import type { Inject } from '../../../../../utils/api-types'; import { areaChartOptions } from '../../../../../utils/Charts'; @@ -19,7 +18,7 @@ const InjectOverTimeArea: FunctionComponent = ({ }) => { // Standard hooks const { t, nsdt } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); let cumulation = 0; const injectsOverTime = R.pipe( diff --git a/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeLine.tsx b/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeLine.tsx index e1e70c62ad..414bd9c317 100644 --- a/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeLine.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/timeline/InjectOverTimeLine.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; import Chart from 'react-apexcharts'; @@ -6,7 +6,6 @@ import Chart from 'react-apexcharts'; import type { InjectStore } from '../../../../../actions/injects/Inject'; import Empty from '../../../../../components/Empty'; import { useFormatter } from '../../../../../components/i18n'; -import type { Theme } from '../../../../../components/Theme'; import type { Inject } from '../../../../../utils/api-types'; import { lineChartOptions } from '../../../../../utils/Charts'; @@ -19,7 +18,7 @@ const InjectOverTimeLine: FunctionComponent = ({ }) => { // Standard hooks const { t, nsdt } = useFormatter(); - const theme: Theme = useTheme(); + const theme = useTheme(); let cumulation = 0; const injectsOverTime = R.pipe( diff --git a/openbas-front/src/admin/components/simulations/simulation/timeline/TimelineOverview.tsx b/openbas-front/src/admin/components/simulations/simulation/timeline/TimelineOverview.tsx index bbb83dbd36..c4eefdae91 100644 --- a/openbas-front/src/admin/components/simulations/simulation/timeline/TimelineOverview.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/timeline/TimelineOverview.tsx @@ -9,9 +9,9 @@ import { Paper, Typography, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseTeams } from '../../../../../actions/Exercise'; import type { ExercisesHelper } from '../../../../../actions/exercises/exercise-helper'; @@ -41,7 +41,7 @@ import teamContextForExercise from '../teams/teamContextForExercise'; import InjectOverTimeArea from './InjectOverTimeArea'; import InjectOverTimeLine from './InjectOverTimeLine'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { width: '100%', margin: '-12px 0 50px 0', @@ -81,7 +81,7 @@ const useStyles = makeStyles(() => ({ })); const TimelineOverview = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { exerciseId } = useParams() as { exerciseId: Exercise['exercise_id'] }; const { t, fndt } = useFormatter(); @@ -288,8 +288,8 @@ const TimelineOverview = () => { {fndt(inject.inject_status?.tracking_sent_date)} {' '} { - inject.inject_status && inject.inject_status.tracking_total_execution_time - && (inject.inject_status.tracking_total_execution_time / 1000).toFixed(2) + inject.inject_status?.tracking_sent_date && inject.inject_status.tracking_end_date + && ((new Date(inject.inject_status.tracking_end_date).getTime() - new Date(inject.inject_status.tracking_sent_date).getTime()) / 1000).toFixed(2) } {t('s')}
diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/Validations.js b/openbas-front/src/admin/components/simulations/simulation/validation/Validations.js index 45d93b2e06..bfbfc6e2aa 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/Validations.js +++ b/openbas-front/src/admin/components/simulations/simulation/validation/Validations.js @@ -1,9 +1,9 @@ import { List, ListItem, ListItemIcon, ListItemText, Slide } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { forwardRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchExerciseInjectExpectations } from '../../../../../actions/Exercise'; import { fetchExerciseInjects } from '../../../../../actions/Inject'; @@ -24,7 +24,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 40, }, @@ -36,7 +36,7 @@ const useStyles = makeStyles(() => ({ })); const Validations = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { exerciseId } = useParams(); const [tags, setTags] = useState([]); diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/common/TeamOrAssetLine.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/common/TeamOrAssetLine.tsx index 49fde17948..75312024ad 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/common/TeamOrAssetLine.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/common/TeamOrAssetLine.tsx @@ -1,7 +1,7 @@ import { CastForEducationOutlined, DnsOutlined, LanOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchAssetGroups } from '../../../../../../actions/asset_groups/assetgroup-action'; import type { AssetGroupsHelper } from '../../../../../../actions/asset_groups/assetgroup-helper'; @@ -27,7 +27,7 @@ import ManualExpectations from '../expectations/ManualExpectations'; import TechnicalExpectationAsset from '../expectations/TechnicalExpectationAsset'; import TechnicalExpectationAssetGroup from '../expectations/TechnicalExpectationAssetGroup'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 40, }, @@ -56,7 +56,7 @@ const TeamOrAssetLine: FunctionComponent = ({ expectations, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/DetectionPreventionExpectationsValidationForm.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/DetectionPreventionExpectationsValidationForm.tsx index 0b030e3fdd..3fb79b6c07 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/DetectionPreventionExpectationsValidationForm.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/DetectionPreventionExpectationsValidationForm.tsx @@ -1,8 +1,8 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Button, TextField as MuiTextField, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import { Controller, useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import type { SecurityPlatformHelper } from '../../../../../../actions/assets/asset-helper'; @@ -12,7 +12,6 @@ import ExpandableText from '../../../../../../components/common/ExpendableText'; import SecurityPlatformField from '../../../../../../components/fields/SecurityPlatformField'; import { useFormatter } from '../../../../../../components/i18n'; import ItemResult from '../../../../../../components/ItemResult'; -import type { Theme } from '../../../../../../components/Theme'; import { useHelper } from '../../../../../../store'; import type { InjectExpectationResult, SecurityPlatform } from '../../../../../../utils/api-types'; import { useAppDispatch } from '../../../../../../utils/hooks'; @@ -20,7 +19,7 @@ import useDataLoader from '../../../../../../utils/hooks/useDataLoader'; import { zodImplement } from '../../../../../../utils/Zod'; import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ marginTop_2: { marginTop: theme.spacing(2), }, @@ -40,7 +39,7 @@ interface FormProps { } const DetectionPreventionExpectationsValidationForm: FunctionComponent = ({ expectation, result, sourceIds = [], onUpdate }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const { securityPlatformsMap }: { securityPlatformsMap: Record } = useHelper((helper: SecurityPlatformHelper) => ({ diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ExpectationLine.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ExpectationLine.tsx index 8be6b179cf..96f22d3df1 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ExpectationLine.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ExpectationLine.tsx @@ -1,12 +1,11 @@ import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, ReactElement } from 'react'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../../../../../../components/Theme'; import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; import ResultChip from './ResultChip'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { height: 40, }, @@ -42,7 +41,7 @@ const ExpectationLine: FunctionComponent = ({ gap, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); return ( <> diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectations.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectations.tsx index 331c065a1f..9676762cea 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectations.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectations.tsx @@ -14,10 +14,10 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { UserHelper } from '../../../../../../actions/helper'; import { fetchUsers } from '../../../../../../actions/User'; @@ -26,7 +26,6 @@ import Drawer from '../../../../../../components/common/Drawer'; import ExpandableText from '../../../../../../components/common/ExpendableText'; import Paper from '../../../../../../components/common/Paper'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import { useHelper } from '../../../../../../store'; import type { Inject, User } from '../../../../../../utils/api-types'; import { useAppDispatch } from '../../../../../../utils/hooks'; @@ -35,7 +34,7 @@ import { computeColorStyle, computeLabel, resolveUserName, truncate } from '../. import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; import ManualExpectationsValidationForm from './ManualExpectationsValidationForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { height: 40, }, @@ -84,7 +83,7 @@ const ManualExpectations: FunctionComponent = ({ inject, expectations, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [selectedItem, setSelectedItem] = useState(null); diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectationsValidationForm.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectationsValidationForm.tsx index 86bf8827ac..3ac5353bad 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectationsValidationForm.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ManualExpectationsValidationForm.tsx @@ -1,8 +1,9 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Button, Chip, Grid, MenuItem, Select, Slider, TextField as MuiTextField, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent, useEffect } from 'react'; import { useForm } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { z } from 'zod'; import { updateInjectExpectation } from '../../../../../../actions/Exercise'; @@ -11,7 +12,6 @@ import { fetchTeams } from '../../../../../../actions/teams/team-actions'; import type { TeamsHelper } from '../../../../../../actions/teams/team-helper'; import { fetchUsers } from '../../../../../../actions/User'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import { useHelper } from '../../../../../../store'; import type { Team, User } from '../../../../../../utils/api-types'; import { useAppDispatch } from '../../../../../../utils/hooks'; @@ -20,7 +20,7 @@ import { computeColorStyle, computeLabel, resolveUserName, truncate } from '../. import { zodImplement } from '../../../../../../utils/Zod'; import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ marginTop_2: { marginTop: theme.spacing(2), }, @@ -48,9 +48,9 @@ interface FormProps { } const ManualExpectationsValidationForm: FunctionComponent = ({ expectation, onUpdate, withSummary = true }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); - const theme = useTheme(); + const theme = useTheme(); const { teamsMap, usersMap }: { teamsMap: Record; usersMap: Record; diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ResultChip.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ResultChip.tsx index cc2e103146..bef0bda3a4 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ResultChip.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/ResultChip.tsx @@ -1,13 +1,13 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import colorStyles from '../../../../../../components/Color'; import { useFormatter } from '../../../../../../components/i18n'; import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chipInList: { height: 20, borderRadius: 4, @@ -30,7 +30,7 @@ const ResultChip: FunctionComponent = ({ expectation, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const result = !R.isEmpty(expectation.inject_expectation_results); diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAsset.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAsset.tsx index d242060fa1..5f7bd329d3 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAsset.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAsset.tsx @@ -1,20 +1,19 @@ import { KeyboardArrowRightOutlined } from '@mui/icons-material'; import { Alert, Button, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { Contract } from '../../../../../../actions/contract/contract'; import Drawer from '../../../../../../components/common/Drawer'; import { useFormatter } from '../../../../../../components/i18n'; -import type { Theme } from '../../../../../../components/Theme'; import type { InjectExpectationResult } from '../../../../../../utils/api-types'; import { truncate } from '../../../../../../utils/String'; import type { InjectExpectationsStore } from '../../../../common/injects/expectations/Expectation'; import { typeIcon } from '../../../../common/injects/expectations/ExpectationUtils'; import ExpectationLine from './ExpectationLine'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ buttons: { display: 'flex', placeContent: 'space-between', @@ -41,7 +40,7 @@ const TechnicalExpectationAsset: FunctionComponent = ({ injectContract, gap, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAssetGroup.tsx b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAssetGroup.tsx index a86c35cc36..6835914893 100644 --- a/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAssetGroup.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/validation/expectations/TechnicalExpectationAssetGroup.tsx @@ -1,7 +1,7 @@ import { DnsOutlined } from '@mui/icons-material'; import { ListItem, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { EndpointHelper } from '../../../../../../actions/assets/asset-helper'; import type { Contract } from '../../../../../../actions/contract/contract'; @@ -13,7 +13,7 @@ import ExpectationLine from './ExpectationLine'; import groupedByAsset from './ExpectationUtils'; import TechnicalExpectationAsset from './TechnicalExpectationAsset'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ item: { height: 40, }, @@ -40,7 +40,7 @@ const TechnicalExpectationAssetGroup: FunctionComponent = ({ assetGroup, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { diff --git a/openbas-front/src/admin/components/simulations/simulation/variables/AvailableVariablesDialog.tsx b/openbas-front/src/admin/components/simulations/simulation/variables/AvailableVariablesDialog.tsx index 8e5cb98aa9..05a9d918c2 100644 --- a/openbas-front/src/admin/components/simulations/simulation/variables/AvailableVariablesDialog.tsx +++ b/openbas-front/src/admin/components/simulations/simulation/variables/AvailableVariablesDialog.tsx @@ -1,10 +1,10 @@ import { CopyAllOutlined } from '@mui/icons-material'; import { TabContext, TabList, TabPanel } from '@mui/lab'; import { Alert, Button, Dialog, DialogActions, DialogContent, List, ListItem, ListItemButton, ListItemText, Tab } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useState } from 'react'; import * as React from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { Contract } from '../../../../../actions/contract/contract'; import type { UserHelper } from '../../../../../actions/helper'; @@ -61,7 +61,7 @@ const VariableChildItem: FunctionComponent = ({ ); }; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ button: { textTransform: 'none', height: 18, @@ -83,7 +83,7 @@ interface AvailableVariablesDialogProps { const AvailableVariablesDialog: FunctionComponent< AvailableVariablesDialogProps > = ({ open, handleClose, variables, injectorContract, uriVariable }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [tab, setTab] = useState('1'); diff --git a/openbas-front/src/admin/components/teams/Index.tsx b/openbas-front/src/admin/components/teams/Index.tsx index ba038477fc..b3fc64601c 100644 --- a/openbas-front/src/admin/components/teams/Index.tsx +++ b/openbas-front/src/admin/components/teams/Index.tsx @@ -1,6 +1,6 @@ -import { makeStyles } from '@mui/styles'; import { lazy, Suspense } from 'react'; import { Navigate, Route, Routes } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../../../components/Error'; import Loader from '../../../components/Loader'; @@ -10,14 +10,14 @@ const Players = lazy(() => import('./Players')); const Teams = lazy(() => import('./Teams')); const Organizations = lazy(() => import('./Organizations')); -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { flexGrow: 1, }, })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); return (
}> diff --git a/openbas-front/src/admin/components/teams/Organizations.tsx b/openbas-front/src/admin/components/teams/Organizations.tsx index 66e42de097..08dec6c8da 100644 --- a/openbas-front/src/admin/components/teams/Organizations.tsx +++ b/openbas-front/src/admin/components/teams/Organizations.tsx @@ -1,9 +1,9 @@ import { DomainOutlined, FileDownloadOutlined } from '@mui/icons-material'; import { IconButton, List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties } from 'react'; import { CSVLink } from 'react-csv'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { OrganizationHelper, TagHelper, UserHelper } from '../../../actions/helper'; import { fetchOrganizations } from '../../../actions/Organization'; @@ -11,7 +11,6 @@ import Breadcrumbs from '../../../components/Breadcrumbs'; import { useFormatter } from '../../../components/i18n'; import ItemTags from '../../../components/ItemTags'; import SearchFilter from '../../../components/SearchFilter'; -import type { Theme } from '../../../components/Theme'; import { useHelper } from '../../../store'; import type { Organization } from '../../../utils/api-types'; import { exportData } from '../../../utils/Environment'; @@ -23,7 +22,7 @@ import TagsFilter from '../common/filters/TagsFilter'; import CreateOrganization from './organizations/CreateOrganization'; import OrganizationPopover from './organizations/OrganizationPopover'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ parameters: { marginTop: -10, display: 'flex', @@ -95,7 +94,7 @@ const inlineStyles: Record = { const Organizations = () => { // Standard hooks const dispatch = useAppDispatch(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Fetching data diff --git a/openbas-front/src/admin/components/teams/Players.tsx b/openbas-front/src/admin/components/teams/Players.tsx index ea77281789..7704360b1a 100644 --- a/openbas-front/src/admin/components/teams/Players.tsx +++ b/openbas-front/src/admin/components/teams/Players.tsx @@ -1,8 +1,8 @@ import { PersonOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useMemo, useState } from 'react'; import { useSearchParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import type { OrganizationHelper, UserHelper } from '../../../actions/helper'; import { fetchOrganizations } from '../../../actions/Organization'; @@ -24,7 +24,7 @@ import useDataLoader from '../../../utils/hooks/useDataLoader'; import CreatePlayer from './players/CreatePlayer'; import PlayerPopover from './players/PlayerPopover'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ itemHead: { textTransform: 'uppercase', }, @@ -66,7 +66,7 @@ const inlineStyles: Record = { const Players = () => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); const { t } = useFormatter(); diff --git a/openbas-front/src/admin/components/teams/organizations/CreateOrganization.js b/openbas-front/src/admin/components/teams/organizations/CreateOrganization.js index 2805431897..aaf3063156 100644 --- a/openbas-front/src/admin/components/teams/organizations/CreateOrganization.js +++ b/openbas-front/src/admin/components/teams/organizations/CreateOrganization.js @@ -1,10 +1,10 @@ import { Add } from '@mui/icons-material'; import { Dialog, DialogContent, DialogTitle, Fab, Slide } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { Component, forwardRef } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addOrganization } from '../../../../actions/Organization'; import inject18n from '../../../../components/i18n'; @@ -89,5 +89,5 @@ CreateOrganization.propTypes = { export default R.compose( connect(null, { addOrganization }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(CreateOrganization); diff --git a/openbas-front/src/admin/components/teams/players/CreatePlayer.tsx b/openbas-front/src/admin/components/teams/players/CreatePlayer.tsx index 6d114975cb..a4a7388dfd 100644 --- a/openbas-front/src/admin/components/teams/players/CreatePlayer.tsx +++ b/openbas-front/src/admin/components/teams/players/CreatePlayer.tsx @@ -1,21 +1,20 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { addPlayer } from '../../../../actions/User'; import ButtonCreate from '../../../../components/common/ButtonCreate'; import Dialog from '../../../../components/common/Dialog'; import Drawer from '../../../../components/common/Drawer'; import { useFormatter } from '../../../../components/i18n'; -import type { Theme } from '../../../../components/Theme'; import type { PlayerInput } from '../../../../utils/api-types'; import { useAppDispatch } from '../../../../utils/hooks'; import { Option } from '../../../../utils/Option'; import type { PlayerInputForm, UserStore } from './Player'; import PlayerForm from './PlayerForm'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ text: { fontSize: theme.typography.h2.fontSize, color: theme.palette.primary.main, @@ -33,7 +32,7 @@ const CreatePlayer: FunctionComponent = ({ onCreate, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/components/AppThemeProvider.tsx b/openbas-front/src/components/AppThemeProvider.tsx index 63a2af6091..b41c60f80c 100644 --- a/openbas-front/src/components/AppThemeProvider.tsx +++ b/openbas-front/src/components/AppThemeProvider.tsx @@ -1,6 +1,5 @@ import { enUS, esES, frFR, Localization, zhCN } from '@mui/material/locale'; import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { ThemeOptions } from '@mui/material/styles/createTheme'; import { ReactNode, useEffect, useState } from 'react'; import * as React from 'react'; @@ -56,7 +55,7 @@ const AppThemeProvider: React.FC = ({ dark?.primary_color, dark?.secondary_color, dark?.accent_color, - ) as ThemeOptions, + ), muiLocale, ); if (theme === 'light') { @@ -70,7 +69,7 @@ const AppThemeProvider: React.FC = ({ light?.primary_color, light?.secondary_color, light?.accent_color, - ) as ThemeOptions, + ), muiLocale, ); } diff --git a/openbas-front/src/components/AttackPatternField.tsx b/openbas-front/src/components/AttackPatternField.tsx index a56c9d83a8..cc9a73104d 100644 --- a/openbas-front/src/components/AttackPatternField.tsx +++ b/openbas-front/src/components/AttackPatternField.tsx @@ -1,8 +1,8 @@ import { AddOutlined, RouteOutlined } from '@mui/icons-material'; import { Autocomplete, Box, Dialog, DialogContent, DialogTitle, IconButton, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AttackPatternHelper } from '../actions/attack_patterns/attackpattern-helper'; import { addAttackPattern } from '../actions/AttackPattern'; @@ -15,7 +15,7 @@ import { useAppDispatch } from '../utils/hooks'; import { Option } from '../utils/Option'; import { useFormatter } from './i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -46,7 +46,7 @@ const AttackPatternField: FunctionComponent = ({ onChange, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/components/Autocomplete.js b/openbas-front/src/components/Autocomplete.js index 8954065105..ada6f2b677 100644 --- a/openbas-front/src/components/Autocomplete.js +++ b/openbas-front/src/components/Autocomplete.js @@ -22,6 +22,11 @@ const renderAutocomplete = ({ clearOnBlur={false} clearOnEscape={false} disableClearable + slotProps={{ + paper: { + elevation: 2, + }, + }} onInputChange={(_event, value) => { if (others.freeSolo) { onChange(value); @@ -32,7 +37,7 @@ const renderAutocomplete = ({ }} {...inputProps} {...others} - isOptionEqualToValue={(option, value) => value === undefined || value === '' || option.id === value.id} + isOptionEqualToValue={(option, value) => value === undefined && value === '' && option.id === value.id} renderInput={params => ( openCreate()} > diff --git a/openbas-front/src/components/Breadcrumbs.tsx b/openbas-front/src/components/Breadcrumbs.tsx index 704e190d0e..a081f24a5f 100644 --- a/openbas-front/src/components/Breadcrumbs.tsx +++ b/openbas-front/src/components/Breadcrumbs.tsx @@ -1,7 +1,7 @@ import { Breadcrumbs as MUIBreadcrumbs, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { truncate } from '../utils/String'; @@ -19,9 +19,7 @@ interface BreadcrumbsProps { elements: BreadcrumbsElement[]; } -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ breadcrumbsList: { marginTop: -5, marginBottom: 15, @@ -36,7 +34,7 @@ const useStyles = makeStyles(() => ({ })); const Breadcrumbs: FunctionComponent = ({ elements, variant }) => { - const classes = useStyles(); + const { classes } = useStyles(); let className = classes.breadcrumbsStandard; if (variant === 'list') { className = classes.breadcrumbsList; diff --git a/openbas-front/src/components/ChainedTimeline.tsx b/openbas-front/src/components/ChainedTimeline.tsx index 0c3bedc3b7..f3c7741fa9 100644 --- a/openbas-front/src/components/ChainedTimeline.tsx +++ b/openbas-front/src/components/ChainedTimeline.tsx @@ -1,6 +1,6 @@ import { CropFree, UnfoldLess, UnfoldMore } from '@mui/icons-material'; import { Tooltip } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Connection, ConnectionLineType, @@ -21,6 +21,7 @@ import { import moment from 'moment-timezone'; import { FunctionComponent, useEffect, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { AssetGroupsHelper } from '../actions/asset_groups/assetgroup-helper'; import type { EndpointHelper } from '../actions/assets/asset-helper'; @@ -39,9 +40,8 @@ import { useFormatter } from './i18n'; import nodeTypes from './nodes'; import { NodeInject } from './nodes/NodeInject'; import NodePhantom from './nodes/NodePhantom'; -import type { Theme } from './Theme'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { marginTop: 30, paddingRight: 40, @@ -82,8 +82,8 @@ const ChainedTimelineFlow: FunctionComponent = ({ onUpdate, onDelete }) => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const [nodes, setNodes, onNodesChange] = useNodesState([]); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const [draggingOnGoing, setDraggingOnGoing] = useState(false); diff --git a/openbas-front/src/components/CountryField.js b/openbas-front/src/components/CountryField.js index c13fc9d364..6903930325 100644 --- a/openbas-front/src/components/CountryField.js +++ b/openbas-front/src/components/CountryField.js @@ -1,8 +1,8 @@ import { FlagOutlined } from '@mui/icons-material'; import { Box } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as R from 'ramda'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; import { countryOptions } from '../utils/Option'; import Autocomplete from './Autocomplete'; @@ -55,4 +55,4 @@ class CountryField extends Component { /** * @deprecated The component use old form libnary react-final-form */ -export default R.compose(inject18n, withStyles(styles))(CountryField); +export default R.compose(inject18n, Component => withStyles(Component, styles))(CountryField); diff --git a/openbas-front/src/components/CustomTimelineBackground.tsx b/openbas-front/src/components/CustomTimelineBackground.tsx index 6e24d2e78f..7f8dda75df 100644 --- a/openbas-front/src/components/CustomTimelineBackground.tsx +++ b/openbas-front/src/components/CustomTimelineBackground.tsx @@ -1,11 +1,9 @@ -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { type BackgroundProps, type ReactFlowState, useStore } from '@xyflow/react'; import cc from 'classcat'; import { CSSProperties, memo, useRef } from 'react'; import { shallow } from 'zustand/shallow'; -import type { Theme } from './Theme'; - interface Props extends BackgroundProps { minutesPerGap: number; } @@ -30,7 +28,7 @@ function BackgroundComponent({ style, className, }: Props) { - const theme: Theme = useTheme(); + const theme = useTheme(); const ref = useRef(null); const { transform, patternId } = useStore(selector, shallow); diff --git a/openbas-front/src/components/CustomTimelinePanel.tsx b/openbas-front/src/components/CustomTimelinePanel.tsx index 49abba5714..6d6f8014a7 100644 --- a/openbas-front/src/components/CustomTimelinePanel.tsx +++ b/openbas-front/src/components/CustomTimelinePanel.tsx @@ -1,16 +1,16 @@ -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { type BackgroundProps, Panel, type ReactFlowState, useStore, Viewport } from '@xyflow/react'; import moment from 'moment-timezone'; import { CSSProperties, memo, useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { shallow } from 'zustand/shallow'; import { useFormatter } from './i18n'; -import type { Theme } from './Theme'; const selector = (s: ReactFlowState) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` }); // @ts-expect-error pointer events is important and is mandatory -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ panel: { pointerEvents: 'none !important', width: '100%', @@ -50,8 +50,8 @@ function BackgroundComponent({ viewportData, startDate = undefined, }: Props) { - const theme: Theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const { ft, fld, vnsdt } = useFormatter(); const { transform } = useStore(selector, shallow); diff --git a/openbas-front/src/components/DocumentField.js b/openbas-front/src/components/DocumentField.js index 535ea43a15..1ab9a8a6ba 100644 --- a/openbas-front/src/components/DocumentField.js +++ b/openbas-front/src/components/DocumentField.js @@ -1,9 +1,9 @@ import { Box } from '@mui/material'; -import { withStyles } from '@mui/styles'; import { FileOutline } from 'mdi-material-ui'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addDocument, fetchDocuments } from '../actions/Document'; import { storeHelper } from '../actions/Schema'; @@ -78,5 +78,5 @@ const select = (state) => { export default R.compose( connect(select, { fetchDocuments, addDocument }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(DocumentField); diff --git a/openbas-front/src/components/ExerciseField.js b/openbas-front/src/components/ExerciseField.js index ab8afaef7d..c8d4848d61 100644 --- a/openbas-front/src/components/ExerciseField.js +++ b/openbas-front/src/components/ExerciseField.js @@ -1,14 +1,14 @@ import { Kayaking } from '@mui/icons-material'; import { Box } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { fetchExercises } from '../actions/Exercise'; import { useHelper } from '../store'; import useDataLoader from '../utils/hooks/useDataLoader'; import Autocomplete from './Autocomplete'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -27,7 +27,7 @@ const useStyles = makeStyles(() => ({ * @deprecated The component use old form libnary react-final-form */ const ExerciseField = (props) => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const exercises = useHelper(helper => helper.getExercises()); useDataLoader(() => { diff --git a/openbas-front/src/components/InjectContractComponent.tsx b/openbas-front/src/components/InjectContractComponent.tsx index 55772a17fc..2583cfcddc 100644 --- a/openbas-front/src/components/InjectContractComponent.tsx +++ b/openbas-front/src/components/InjectContractComponent.tsx @@ -1,8 +1,8 @@ import { Autocomplete, SelectChangeEvent, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useEffect, useState } from 'react'; import * as React from 'react'; import { FieldError } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { searchInjectorContracts } from '../actions/InjectorContracts'; import InjectIcon from '../admin/components/common/injects/InjectIcon'; @@ -11,7 +11,7 @@ import { isNotEmptyField } from '../utils/utils'; import { initSorting, Page } from './common/queryable/Page'; import { useFormatter } from './i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -37,7 +37,7 @@ const InjectContractComponent: FunctionComponent = ({ fieldValue, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t, tPick } = useFormatter(); // Pagination diff --git a/openbas-front/src/components/ItemBoolean.js b/openbas-front/src/components/ItemBoolean.js index 14e3735a9a..a6fe5d8ede 100644 --- a/openbas-front/src/components/ItemBoolean.js +++ b/openbas-front/src/components/ItemBoolean.js @@ -1,7 +1,8 @@ import { Chip, CircularProgress, Tooltip } from '@mui/material'; -import { useTheme, withStyles } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as PropTypes from 'prop-types'; import { compose } from 'ramda'; +import { withStyles } from 'tss-react/mui'; import inject18n from './i18n'; @@ -129,4 +130,4 @@ ItemBoolean.propTypes = { reverse: PropTypes.bool, }; -export default compose(inject18n, withStyles(styles))(ItemBoolean); +export default compose(inject18n, Component => withStyles(Component, styles))(ItemBoolean); diff --git a/openbas-front/src/components/ItemCopy.tsx b/openbas-front/src/components/ItemCopy.tsx index 16dc6e75d0..0263945bc2 100644 --- a/openbas-front/src/components/ItemCopy.tsx +++ b/openbas-front/src/components/ItemCopy.tsx @@ -1,15 +1,12 @@ import { ContentCopyOutlined } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { truncate } from '../utils/String'; import { copyToClipboard } from '../utils/utils'; import { useFormatter } from './i18n'; -import type { Theme } from './Theme'; -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ containerInline: { position: 'relative', padding: '2px 25px 2px 5px', @@ -56,7 +53,7 @@ const ItemCopy: FunctionComponent = ({ limit = null, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); return (
withStyles(Component, styles))(ItemNumberDifference); diff --git a/openbas-front/src/components/ItemResult.tsx b/openbas-front/src/components/ItemResult.tsx index 1d394fda00..864c3cdf2b 100644 --- a/openbas-front/src/components/ItemResult.tsx +++ b/openbas-front/src/components/ItemResult.tsx @@ -1,10 +1,8 @@ import { Chip, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -89,7 +87,7 @@ const ItemStatus: FunctionComponent = ({ status, variant, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'inList' ? classes.chipInList : classes.chip; const classStyle = computeStatusStyle(status); return ( diff --git a/openbas-front/src/components/ItemSeverity.tsx b/openbas-front/src/components/ItemSeverity.tsx index 3f4c07c990..bcec990f06 100644 --- a/openbas-front/src/components/ItemSeverity.tsx +++ b/openbas-front/src/components/ItemSeverity.tsx @@ -1,10 +1,8 @@ import { Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -73,7 +71,7 @@ const ItemSeverity: FunctionComponent = ({ severity, variant, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'inList' ? classes.chipInList : classes.chip; const classStyle = computeSeverityStyle(severity); return ( diff --git a/openbas-front/src/components/ItemStatus.tsx b/openbas-front/src/components/ItemStatus.tsx index 8f95869103..dd6a2ae0fd 100644 --- a/openbas-front/src/components/ItemStatus.tsx +++ b/openbas-front/src/components/ItemStatus.tsx @@ -1,12 +1,10 @@ import { Chip, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from './i18n'; -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ chip: { fontSize: 12, height: 25, @@ -72,6 +70,8 @@ const computeStatusStyle = (status: string | undefined | null) => { switch (status) { case 'ERROR': return inlineStyles.red; + case 'ASSET_INACTIVE': + return inlineStyles.red; case 'MAYBE_PREVENTED': return inlineStyles.purple; case 'MAYBE_PARTIAL_PREVENTED': @@ -98,7 +98,7 @@ const ItemStatus: FunctionComponent = ({ isInject = false, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const style = variant === 'inList' ? classes.chipInList : classes.chip; const classStyle = computeStatusStyle(status); let finalLabel = label; diff --git a/openbas-front/src/components/ItemTags.js b/openbas-front/src/components/ItemTags.js index 51b14d718f..9452df6909 100644 --- a/openbas-front/src/components/ItemTags.js +++ b/openbas-front/src/components/ItemTags.js @@ -1,8 +1,9 @@ import { Chip, Slide, Tooltip } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as PropTypes from 'prop-types'; import * as R from 'ramda'; import { forwardRef } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useHelper } from '../store'; import { hexToRGB } from '../utils/Colors'; @@ -14,7 +15,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ inline: { display: 'inline', alignItems: 'center', @@ -38,7 +39,7 @@ const ItemTags = (props) => { const { tags, variant, limit = 2 } = props; const { t } = useFormatter(); const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); let style = classes.tag; let truncateLimit = 15; diff --git a/openbas-front/src/components/ItemTargets.tsx b/openbas-front/src/components/ItemTargets.tsx index 0ead3e5c24..86e26e113d 100644 --- a/openbas-front/src/components/ItemTargets.tsx +++ b/openbas-front/src/components/ItemTargets.tsx @@ -1,13 +1,13 @@ import { DevicesOtherOutlined, Groups3Outlined, HorizontalRule } from '@mui/icons-material'; import { Chip, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { SelectGroup } from 'mdi-material-ui'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { TargetSimple } from '../utils/api-types'; import { getLabelOfRemainingItems, getRemainingItemsCount, getVisibleItems, truncate } from '../utils/String'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ inline: { display: 'inline-block', }, @@ -30,7 +30,7 @@ const ItemTargets: FunctionComponent = ({ variant, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); let truncateLimit = 15; if (variant === 'reduced-view') { truncateLimit = 6; diff --git a/openbas-front/src/components/KillChainPhaseField.js b/openbas-front/src/components/KillChainPhaseField.js index 19164a0711..9ca7e0789e 100644 --- a/openbas-front/src/components/KillChainPhaseField.js +++ b/openbas-front/src/components/KillChainPhaseField.js @@ -1,9 +1,9 @@ import { RouteOutlined } from '@mui/icons-material'; import { Box, Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addKillChainPhase } from '../actions/KillChainPhase'; import { storeHelper } from '../actions/Schema'; @@ -132,5 +132,5 @@ const select = (state) => { export default R.compose( connect(select, { addKillChainPhase }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(KillChainPhaseField); diff --git a/openbas-front/src/components/Loader.js b/openbas-front/src/components/Loader.js index f762cc7eca..64fc6410df 100644 --- a/openbas-front/src/components/Loader.js +++ b/openbas-front/src/components/Loader.js @@ -1,7 +1,7 @@ import { CircularProgress } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import { Component } from 'react'; +import { withStyles } from 'tss-react/mui'; const styles = () => ({ container: { @@ -100,4 +100,4 @@ Loader.propTypes = { size: PropTypes.string, }; -export default withStyles(styles)(Loader); +export default withStyles(Loader, styles); diff --git a/openbas-front/src/components/MarkdownDisplay.tsx b/openbas-front/src/components/MarkdownDisplay.tsx index 21e99cf7bb..a8ec338d74 100644 --- a/openbas-front/src/components/MarkdownDisplay.tsx +++ b/openbas-front/src/components/MarkdownDisplay.tsx @@ -1,4 +1,5 @@ -import { useTheme } from '@mui/styles'; +import { Theme } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent, SyntheticEvent, useState } from 'react'; import Markdown from 'react-markdown'; import type { PluggableList } from 'react-markdown/lib'; @@ -9,7 +10,6 @@ import remarkParse from 'remark-parse'; import { truncate } from '../utils/String'; import ExternalLinkPopover from './ExternalLinkPopover'; import FieldOrEmpty from './FieldOrEmpty'; -import type { Theme } from './Theme'; export const MarkDownComponents = ( theme: Theme, @@ -72,7 +72,7 @@ const MarkdownDisplay: FunctionComponent< removeLineBreaks, remarkPlugins, }) => { - const theme = useTheme(); + const theme = useTheme(); const [displayExternalLink, setDisplayExternalLink] = useState(false); const [externalLink, setExternalLink] = useState( undefined, diff --git a/openbas-front/src/components/OldAttackPatternField.js b/openbas-front/src/components/OldAttackPatternField.js index 9403189bc4..e4d38820e6 100644 --- a/openbas-front/src/components/OldAttackPatternField.js +++ b/openbas-front/src/components/OldAttackPatternField.js @@ -1,9 +1,9 @@ import { RouteOutlined } from '@mui/icons-material'; import { Box, Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addAttackPattern, fetchAttackPatterns } from '../actions/AttackPattern'; import { storeHelper } from '../actions/Schema'; @@ -145,5 +145,5 @@ const select = (state) => { export default R.compose( connect(select, { fetchAttackPatterns, addAttackPattern }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(OldAttackPatternField); diff --git a/openbas-front/src/components/OrganizationField.js b/openbas-front/src/components/OrganizationField.js index 7ecb5ecb01..25233b301e 100644 --- a/openbas-front/src/components/OrganizationField.js +++ b/openbas-front/src/components/OrganizationField.js @@ -1,9 +1,9 @@ import { DomainOutlined } from '@mui/icons-material'; import { Box, Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { addOrganization, fetchOrganizations } from '../actions/Organization'; import { storeHelper } from '../actions/Schema'; @@ -73,7 +73,7 @@ class OrganizationField extends Component { organizations, ); return ( -
+ <> -
+ ); } } @@ -123,5 +123,5 @@ const select = (state) => { export default R.compose( connect(select, { fetchOrganizations, addOrganization }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(OrganizationField); diff --git a/openbas-front/src/components/PlatformField.tsx b/openbas-front/src/components/PlatformField.tsx index 301de8e636..2189292377 100644 --- a/openbas-front/src/components/PlatformField.tsx +++ b/openbas-front/src/components/PlatformField.tsx @@ -1,13 +1,13 @@ import { Autocomplete, Box, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import { FieldError } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { Option } from '../utils/Option'; import { useFormatter } from './i18n'; import PlatformIcon from './PlatformIcon'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -36,7 +36,7 @@ const PlatformField: FunctionComponent = ({ error, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const platformsOptions: Option[] = [ diff --git a/openbas-front/src/components/PlatformIcon.tsx b/openbas-front/src/components/PlatformIcon.tsx index d22115e099..7f3e527a8a 100644 --- a/openbas-front/src/components/PlatformIcon.tsx +++ b/openbas-front/src/components/PlatformIcon.tsx @@ -1,5 +1,5 @@ import { PaletteMode, Tooltip } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; import browserDark from '../static/images/platforms/browser-dark.png'; @@ -16,7 +16,6 @@ import unknownDark from '../static/images/platforms/unknown-dark.png'; import unknownLight from '../static/images/platforms/unknown-light.png'; import windowsDark from '../static/images/platforms/windows-dark.png'; import windowsLight from '../static/images/platforms/windows-light.png'; -import type { Theme } from './Theme'; interface PlatformIconProps { platform: string; @@ -37,9 +36,8 @@ const platformIcons: Record { - const theme = useTheme(); + const theme = useTheme(); const { mode } = theme.palette; - // @ts-expect-error Need a proper enum const src = platformIcons[platform]?.[mode] || platformIcons.Unknown[mode]; return {platform}; }; diff --git a/openbas-front/src/components/PlayerField.js b/openbas-front/src/components/PlayerField.js deleted file mode 100644 index 0fc912be4f..0000000000 --- a/openbas-front/src/components/PlayerField.js +++ /dev/null @@ -1,140 +0,0 @@ -import { PersonOutlined } from '@mui/icons-material'; -import { Box, Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { withStyles } from '@mui/styles'; -import * as R from 'ramda'; -import { Component } from 'react'; -import { connect } from 'react-redux'; - -import { storeHelper } from '../actions/Schema'; -import { addPlayer, fetchPlayers } from '../actions/User'; -import PlayerForm from '../admin/components/teams/players/PlayerForm'; -import { resolveUserName } from '../utils/String'; -import Autocomplete from './Autocomplete'; -import inject18n from './i18n'; - -const styles = () => ({ - icon: { - paddingTop: 4, - display: 'inline-block', - }, - text: { - display: 'inline-block', - flexGrow: 1, - marginLeft: 10, - }, - autoCompleteIndicator: { - display: 'none', - }, -}); - -class PlayerField extends Component { - constructor(props) { - super(props); - this.state = { userCreation: false, userInput: '' }; - } - - componentDidMount() { - this.props.fetchPlayers(); - } - - handleOpenUserCreation() { - this.setState({ userCreation: true }); - } - - handleCloseUserCreation() { - this.setState({ userCreation: false }); - } - - onSubmit(data) { - const { name, setFieldValue, values } = this.props; - this.props.addPlayer(data).then((result) => { - if (result.result) { - const newUser = result.entities.users[result.result]; - const users = R.append( - { - id: newUser.user_id, - label: resolveUserName(newUser), - }, - values[name], - ); - setFieldValue(name, users); - return this.handleCloseUserCreation(); - } - return result; - }); - } - - render() { - const { - t, - name, - users, - classes, - onKeyDown, - style, - label, - placeholder, - noMargin, - } = this.props; - const usersOptions = R.map( - n => ({ - id: n.user_id, - label: resolveUserName(n), - }), - users, - ); - return ( -
- ( - -
- -
-
{option.label}
-
- )} - classes={{ clearIndicator: classes.autoCompleteIndicator }} - /> - - {t('Create a new user')} - - - - -
- ); - } -} - -const select = (state) => { - const helper = storeHelper(state); - return { - users: helper.getUsers(), - }; -}; - -export default R.compose( - connect(select, { fetchPlayers, addPlayer }), - inject18n, - withStyles(styles), -)(PlayerField); diff --git a/openbas-front/src/components/ScenarioField.jsx b/openbas-front/src/components/ScenarioField.jsx index 4f9ad24573..029a99a495 100644 --- a/openbas-front/src/components/ScenarioField.jsx +++ b/openbas-front/src/components/ScenarioField.jsx @@ -1,6 +1,6 @@ import { Kayaking } from '@mui/icons-material'; import { Box } from '@mui/material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { fetchScenarios } from '../actions/scenarios/scenario-actions'; import { useHelper } from '../store'; @@ -8,7 +8,7 @@ import { useAppDispatch } from '../utils/hooks'; import useDataLoader from '../utils/hooks/useDataLoader'; import Autocomplete from './Autocomplete'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -25,7 +25,7 @@ const useStyles = makeStyles(() => ({ const ScenarioField = (props) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data const scenarios = useHelper(helper => helper.getScenarios()); diff --git a/openbas-front/src/components/SearchFilter.tsx b/openbas-front/src/components/SearchFilter.tsx index 0a63c5825b..bc4ac47302 100644 --- a/openbas-front/src/components/SearchFilter.tsx +++ b/openbas-front/src/components/SearchFilter.tsx @@ -1,13 +1,12 @@ import { Search } from '@mui/icons-material'; import { InputAdornment, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { debounce } from '../utils/utils'; import { useFormatter } from './i18n'; -import type { Theme } from './Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ searchRoot: { borderRadius: 4, padding: '0 10px 0 10px', @@ -80,7 +79,7 @@ const SearchInput: React.FC = ({ placeholder, debounceMs, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); diff --git a/openbas-front/src/components/TagField.js b/openbas-front/src/components/TagField.js index 3f837c71c9..a49269fe96 100644 --- a/openbas-front/src/components/TagField.js +++ b/openbas-front/src/components/TagField.js @@ -1,9 +1,9 @@ import { LabelOutlined } from '@mui/icons-material'; import { Box, Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { withStyles } from '@mui/styles'; import * as R from 'ramda'; import { Component } from 'react'; import { connect } from 'react-redux'; +import { withStyles } from 'tss-react/mui'; import { storeHelper } from '../actions/Schema'; import { addTag } from '../actions/Tag'; @@ -137,5 +137,5 @@ const select = (state) => { export default R.compose( connect(select, { addTag }), inject18n, - withStyles(styles), + Component => withStyles(Component, styles), )(TagField); diff --git a/openbas-front/src/components/Theme.d.ts b/openbas-front/src/components/Theme.d.ts deleted file mode 100644 index 954f385b5f..0000000000 --- a/openbas-front/src/components/Theme.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { PaletteColorOptions, PaletteOptions, TypeBackground } from '@mui/material'; -import { Theme as MuiTheme, ThemeOptions } from '@mui/material/styles/createTheme'; - -declare module '@mui/material/IconButton' { - interface IconButtonPropsColorOverrides { - ee: true; - } -} - -declare module '@mui/material/Button' { - interface ButtonPropsColorOverrides { - ee: true; - } -} - -declare module '@mui/material/Button' { - interface ChipPropsColorOverrides { - ee: true; - } -} - -declare module '@mui/material/SvgIcon' { - interface SvgIconPropsColorOverrides { - ee: true; - } -} - -interface ExtendedColor extends PaletteColorOptions { - main: string; - dark: string; - palette: ExtendedPaletteOptions; - text: Partial; - mode: PaletteMode; - background: string; - lightBackground: string; - contrastText: string; -} - -interface ExtendedBackground extends TypeBackground { - nav: string; - accent: string; - shadow: string; -} - -interface ExtendedPaletteOptions extends PaletteOptions { - common: Partial; - background: Partial; - primary: Partial; - error: Partial; - success: Partial; - warning: Partial; - chip: Partial; - ee: Partial; - secondary: Partial; - mode: PaletteMode; -} - -interface ExtendedThemeOptions extends ThemeOptions { - logo: string | null; - logo_collapsed: string | null; - palette: ExtendedPaletteOptions; - borderRadius: number; -} - -export interface Theme extends MuiTheme { - logo: string | undefined; - logo_collapsed: string | undefined; - borderRadius: number; - palette: ExtendedPaletteOptions; -} diff --git a/openbas-front/src/components/Theme.ts b/openbas-front/src/components/Theme.ts new file mode 100644 index 0000000000..75240bb905 --- /dev/null +++ b/openbas-front/src/components/Theme.ts @@ -0,0 +1,61 @@ +import { + PaletteColorOptions, +} from '@mui/material'; + +declare module '@mui/material/IconButton' { + interface IconButtonPropsColorOverrides { + ee: true; + } +} + +declare module '@mui/material/Button' { + interface ButtonPropsColorOverrides { + ee: true; + } +} + +declare module '@mui/material/Button' { + interface ChipPropsColorOverrides { + ee: true; + } +} + +declare module '@mui/material/SvgIcon' { + interface SvgIconPropsColorOverrides { + ee: true; + } +} + +declare module '@mui/material/styles' { + interface TypeBackground { + nav: string; + accent: string; + shadow: string; + } + interface PaletteColor { + background: string; + lightBackground: string; + } + interface SimplePaletteColorOptions { + background?: string; + lightBackground?: string; + } + interface Palette { + chip: PaletteColor; + ee: PaletteColor; + } + interface PaletteOptions { + chip: PaletteColorOptions; + ee: PaletteColorOptions; + } + interface Theme { + logo: string | undefined; + logo_collapsed: string | undefined; + borderRadius: number; + } + interface ThemeOptions { + logo: string | undefined; + logo_collapsed: string | undefined; + borderRadius: number; + } +} diff --git a/openbas-front/src/components/ThemeDark.ts b/openbas-front/src/components/ThemeDark.ts index e4236d03dd..396e571b1f 100644 --- a/openbas-front/src/components/ThemeDark.ts +++ b/openbas-front/src/components/ThemeDark.ts @@ -1,8 +1,9 @@ +import { ThemeOptions } from '@mui/material'; + import LogoCollapsed from '../static/images/logo_dark.png'; import LogoText from '../static/images/logo_text_dark.png'; import { hexToRGB } from '../utils/Colors'; import { fileUri } from '../utils/Environment'; -import type { ExtendedThemeOptions } from './Theme'; const EE_COLOR = '#00f1bd'; @@ -22,7 +23,7 @@ const ThemeDark = ( primary: string | null = null, secondary: string | null = null, accent: string | null = null, -): ExtendedThemeOptions => ({ +): ThemeOptions => ({ logo: logo || fileUri(LogoText), logo_collapsed: logo_collapsed || fileUri(LogoCollapsed), borderRadius: 4, diff --git a/openbas-front/src/components/ThemeLight.ts b/openbas-front/src/components/ThemeLight.ts index 9ca9dac3c3..e0de3daf65 100644 --- a/openbas-front/src/components/ThemeLight.ts +++ b/openbas-front/src/components/ThemeLight.ts @@ -1,8 +1,9 @@ +import { ThemeOptions } from '@mui/material'; + import LogoCollapsed from '../static/images/logo_light.png'; import LogoText from '../static/images/logo_text_light.png'; import { hexToRGB } from '../utils/Colors'; import { fileUri } from '../utils/Environment'; -import type { ExtendedThemeOptions } from './Theme'; const EE_COLOR = '#0c7e69'; @@ -22,7 +23,7 @@ const ThemeLight = ( primary: string | null = null, secondary: string | null = null, accent: string | null = null, -): ExtendedThemeOptions => ({ +): ThemeOptions => ({ logo: logo || fileUri(LogoText), logo_collapsed: logo_collapsed || fileUri(LogoCollapsed), borderRadius: 4, diff --git a/openbas-front/src/components/Timeline.tsx b/openbas-front/src/components/Timeline.tsx index 475f97d46a..f05e66f529 100644 --- a/openbas-front/src/components/Timeline.tsx +++ b/openbas-front/src/components/Timeline.tsx @@ -1,7 +1,8 @@ import { CastForEducationOutlined, CastOutlined } from '@mui/icons-material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { Fragment, FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { InjectStore } from '../actions/injects/Inject'; import InjectIcon from '../admin/components/common/injects/InjectIcon'; @@ -11,9 +12,8 @@ import { truncate } from '../utils/String'; import { splitDuration } from '../utils/Time'; import { isNotEmptyField } from '../utils/utils'; import { useFormatter } from './i18n'; -import type { Theme } from './Theme'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { marginTop: 60, paddingRight: 40, @@ -93,8 +93,8 @@ interface Props { const Timeline: FunctionComponent = ({ injects, onSelectInject, teams }) => { // Standard hooks - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const { t } = useFormatter(); // Retrieve data diff --git a/openbas-front/src/components/common/ButtonCreate.tsx b/openbas-front/src/components/common/ButtonCreate.tsx index 8047523967..3d32368d43 100644 --- a/openbas-front/src/components/common/ButtonCreate.tsx +++ b/openbas-front/src/components/common/ButtonCreate.tsx @@ -1,9 +1,9 @@ import { Add } from '@mui/icons-material'; import { Fab } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ createButton: { position: 'fixed', bottom: 30, @@ -19,7 +19,7 @@ const ButtonCreate: FunctionComponent = ({ onClick, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); return ( ({ +const useStyles = makeStyles()(() => ({ chipInList: { fontSize: 12, lineHeight: '12px', @@ -26,7 +26,7 @@ const ChipInList: FunctionComponent = ({ style, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); return ( diff --git a/openbas-front/src/components/common/CodeBlock.tsx b/openbas-front/src/components/common/CodeBlock.tsx index b9923cbd35..27d05bf78a 100644 --- a/openbas-front/src/components/common/CodeBlock.tsx +++ b/openbas-front/src/components/common/CodeBlock.tsx @@ -1,5 +1,4 @@ -import { Theme } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { a11yDark, coy } from 'react-syntax-highlighter/dist/esm/styles/prism'; @@ -11,7 +10,7 @@ interface CodeBlockProps { } const CodeBlock: FunctionComponent = ({ language, code, maxHeight }) => { - const theme = useTheme(); + const theme = useTheme(); return ( (theme => ({ +const useStyles = makeStyles()(theme => ({ box: { 'width': '100%', 'marginTop': '0.2rem', 'paddingBottom': '0.35rem', - 'borderBottom': `0.1rem solid ${theme.palette.grey['400']}`, + 'borderBottom': `0.1rem solid ${theme.palette.grey[500]}`, 'cursor': 'default', '&:hover': { borderBottom: '0.1rem solid white', @@ -61,7 +59,7 @@ const CustomFileUploader: FunctionComponent = ({ errors, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); const [fileNameForDisplay, setFileNameForDisplay] = useState(''); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [errorText, setErrorText] = useState>>(''); @@ -108,38 +106,40 @@ const CustomFileUploader: FunctionComponent = ({ }; return ( -
- - {label ? t(label) : t('Associated file')} - - - - - {fileNameForDisplay || t('No file selected.')} - - - {!!errorText && ( -
- {t(errorText)} -
- )} -
+ + + {fileNameForDisplay || t('No file selected.')} + + + {!!errorText && ( +
+ {t(errorText)} +
+ )} +
+ ) ); }; diff --git a/openbas-front/src/components/common/DialogWithCross.tsx b/openbas-front/src/components/common/DialogWithCross.tsx index cdc302e85a..af57d9945c 100644 --- a/openbas-front/src/components/common/DialogWithCross.tsx +++ b/openbas-front/src/components/common/DialogWithCross.tsx @@ -1,13 +1,12 @@ import { Close } from '@mui/icons-material'; import { Breakpoint, Dialog as DialogMUI, DialogContent, DialogTitle, IconButton } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../Theme'; import Transition from './Transition'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ header: { backgroundColor: theme.palette.background.nav, display: 'inline-flex', @@ -39,80 +38,81 @@ const DialogWithCross: FunctionComponent = ({ component = React.cloneElement(children as React.ReactElement); } } - const classes = useStyles(); + const { classes } = useStyles(); return ( - -
- - - - {title} -
- - {component} -
+ ( + +
+ + + + {title} +
+ {component} +
+ ) /* - - - - - Modal title - - theme.palette.grey[500], - }} + + + - - - - - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, - dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac - consectetur ac, vestibulum at eros. - - - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. - Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. - - - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus - magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec - ullamcorper nulla non metus auctor fringilla. - - - - - - - */ + + Modal title + + theme.palette.grey[500], + }} + > + + + + + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, + dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac + consectetur ac, vestibulum at eros. + + + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. + + + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus + magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec + ullamcorper nulla non metus auctor fringilla. + + + + + + + */ ); }; diff --git a/openbas-front/src/components/common/Drawer.tsx b/openbas-front/src/components/common/Drawer.tsx index 668929da45..0f0e7c13ca 100644 --- a/openbas-front/src/components/common/Drawer.tsx +++ b/openbas-front/src/components/common/Drawer.tsx @@ -1,14 +1,13 @@ import { Close } from '@mui/icons-material'; import { Drawer as DrawerMUI, IconButton, type PaperProps, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { computeBannerSettings } from '../../public/components/systembanners/utils'; import useAuth from '../../utils/hooks/useAuth'; -import type { Theme } from '../Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ drawerPaperHalf: { minHeight: '100vh', width: '50%', @@ -72,7 +71,7 @@ const Drawer: FunctionComponent = ({ const { settings } = useAuth(); const { bannerHeightNumber } = computeBannerSettings(settings); - const classes = useStyles({ variant }); + const { classes } = useStyles(); let component; if (children) { if (typeof children === 'function') { diff --git a/openbas-front/src/components/common/ListItemButtonCreate.tsx b/openbas-front/src/components/common/ListItemButtonCreate.tsx index 52ff9e9438..1054b8ef04 100644 --- a/openbas-front/src/components/common/ListItemButtonCreate.tsx +++ b/openbas-front/src/components/common/ListItemButtonCreate.tsx @@ -1,11 +1,9 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../Theme'; - -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ text: { fontSize: 15, color: theme.palette.primary.main, @@ -23,7 +21,7 @@ const ListItemButtonCreate: FunctionComponent = ({ onClick, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); return ( ({ +const useStyles = makeStyles()(() => ({ paper: { padding: 20, marginBottom: 30, @@ -16,7 +16,7 @@ const useStyles = makeStyles(() => ({ })); const Paper: FunctionComponent = ({ children }) => { - const classes = useStyles(); + const { classes } = useStyles(); return ( diff --git a/openbas-front/src/components/common/SortHeadersList.tsx b/openbas-front/src/components/common/SortHeadersList.tsx index 21c4a9d071..f8db1aecae 100644 --- a/openbas-front/src/components/common/SortHeadersList.tsx +++ b/openbas-front/src/components/common/SortHeadersList.tsx @@ -1,12 +1,12 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { CSSProperties, FunctionComponent, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ iconSort: { position: 'absolute', margin: '0 0 0 5px', @@ -42,7 +42,7 @@ const SortHeadersList: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const [sortBy, setSortBy] = useState(initialSortBy); const [sortAsc, setSortAsc] = useState(true); diff --git a/openbas-front/src/components/common/chips/ClickableChip.tsx b/openbas-front/src/components/common/chips/ClickableChip.tsx index 3469324119..2b8c577320 100644 --- a/openbas-front/src/components/common/chips/ClickableChip.tsx +++ b/openbas-front/src/components/common/chips/ClickableChip.tsx @@ -1,14 +1,12 @@ import { Box, Chip, SelectChangeEvent, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; -import classNames from 'classnames'; import { FunctionComponent, useRef, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../i18n'; -import type { Theme } from '../../Theme'; import convertOperatorToIcon from './ChipUtils'; import ClickableChipPopover from './ClickableChipPopover'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ mode: { display: 'inline-block', height: '100%', @@ -64,7 +62,7 @@ const ClickableChip: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); const chipRef = useRef(null); const [open, setOpen] = useState(!pristine); @@ -113,7 +111,7 @@ const ClickableChip: FunctionComponent = ({ let or = <>; if (idx > 0) { or = ( -
({ +const useStyles = makeStyles()(theme => ({ mode: { borderRadius: 4, fontFamily: 'Consolas, monaco, monospace', @@ -33,7 +31,7 @@ const ClickableModeChip: FunctionComponent = ({ mode, }) => { // Standard hooks - const classes = useStyles(); + const { classes, cx } = useStyles(); const { t } = useFormatter(); if (!mode) { @@ -41,15 +39,17 @@ const ClickableModeChip: FunctionComponent = ({ } return ( -
- {t(mode.toUpperCase())} -
+ ( +
+ {t(mode.toUpperCase())} +
+ ) ); }; diff --git a/openbas-front/src/components/common/menu/RightMenu.tsx b/openbas-front/src/components/common/menu/RightMenu.tsx index 3d841e0089..bb02d62c99 100644 --- a/openbas-front/src/components/common/menu/RightMenu.tsx +++ b/openbas-front/src/components/common/menu/RightMenu.tsx @@ -1,14 +1,16 @@ import { Drawer, ListItemIcon, ListItemText, MenuItem, MenuList } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent } from 'react'; import * as React from 'react'; import { Link, useLocation } from 'react-router'; +import { CSSObject } from 'tss-react'; +import { makeStyles } from 'tss-react/mui'; import { isNotEmptyField } from '../../../utils/utils'; import { useFormatter } from '../../i18n'; -import type { Theme } from '../../Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +// TODO jss-to-tss-react codemod: Unable to handle style definition reliably. Unsupported arrow function syntax. +// Unexpected value type of MemberExpression. +const useStyles = makeStyles()(theme => ({ drawer: { minHeight: '100vh', width: 200, @@ -17,7 +19,7 @@ const useStyles = makeStyles((theme: Theme) => ({ padding: 0, backgroundColor: theme.palette.background.nav, }, - toolbar: theme.mixins.toolbar, + toolbar: theme.mixins.toolbar as CSSObject, item: { paddingTop: 10, paddingBottom: 10, @@ -36,7 +38,7 @@ const RightMenu: FunctionComponent<{ entries: RightMenuEntry[] }> = ({ }) => { // Standard hooks const location = useLocation(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); return ( (theme => ({ +const useStyles = makeStyles()(theme => ({ button: { marginRight: theme.spacing(2), padding: '0 5px 0 5px', @@ -31,7 +30,7 @@ const TopMenu: FunctionComponent<{ entries: TopMenuEntry[]; contextual?: boolean }) => { // Standard hooks const location = useLocation(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const buttons = () => ( diff --git a/openbas-front/src/components/common/menu/leftmenu/LeftMenu.tsx b/openbas-front/src/components/common/menu/leftmenu/LeftMenu.tsx index 9abf0f3e6e..4d40f1eb6c 100644 --- a/openbas-front/src/components/common/menu/leftmenu/LeftMenu.tsx +++ b/openbas-front/src/components/common/menu/leftmenu/LeftMenu.tsx @@ -1,11 +1,10 @@ import { Divider, Drawer, MenuList, Toolbar } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as React from 'react'; import { FunctionComponent } from 'react'; import { computeBannerSettings } from '../../../../public/components/systembanners/utils'; import useAuth from '../../../../utils/hooks/useAuth'; -import type { Theme } from '../../../Theme'; import { hasHref, LeftMenuEntries } from './leftmenu-model'; import MenuItemGroup from './MenuItemGroup'; import MenuItemLogo from './MenuItemLogo'; @@ -17,7 +16,7 @@ const LeftMenu: FunctionComponent<{ entries: LeftMenuEntries[] }> = ({ entries = [], }) => { // Standard hooks - const theme = useTheme(); + const theme = useTheme(); const { settings } = useAuth(); const { bannerHeightNumber } = computeBannerSettings(settings); diff --git a/openbas-front/src/components/common/menu/leftmenu/MenuItemLogo.tsx b/openbas-front/src/components/common/menu/leftmenu/MenuItemLogo.tsx index 106ced5e12..b946cb6e25 100644 --- a/openbas-front/src/components/common/menu/leftmenu/MenuItemLogo.tsx +++ b/openbas-front/src/components/common/menu/leftmenu/MenuItemLogo.tsx @@ -1,5 +1,5 @@ import { ListItemIcon, MenuItem, Tooltip } from '@mui/material'; -import { useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import React from 'react'; import logoFiligranDark from '../../../../static/images/logo_filigran_dark.png'; @@ -7,7 +7,6 @@ import logoFiligranLight from '../../../../static/images/logo_filigran_light.png import logoFiligranTextDark from '../../../../static/images/logo_filigran_text_dark.png'; import logoFiligranTextLight from '../../../../static/images/logo_filigran_text_light.png'; import { fileUri } from '../../../../utils/Environment'; -import type { Theme } from '../../../Theme'; interface Props { navOpen: boolean; @@ -19,7 +18,7 @@ const MenuItemLogo: React.FC = ({ onClick, }) => { // Standard hooks - const theme = useTheme(); + const theme = useTheme(); const { palette } = theme; const isDarkMode = palette.mode === 'dark'; diff --git a/openbas-front/src/components/common/pagination/PaginationComponent.tsx b/openbas-front/src/components/common/pagination/PaginationComponent.tsx index 4d057b3209..e62d4f6ea7 100644 --- a/openbas-front/src/components/common/pagination/PaginationComponent.tsx +++ b/openbas-front/src/components/common/pagination/PaginationComponent.tsx @@ -1,7 +1,7 @@ import { Button, Chip, TablePagination, ToggleButtonGroup } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useEffect, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import MitreFilter, { MITRE_FILTER_KEY } from '../../../admin/components/common/filters/MitreFilter'; import mitreAttack from '../../../static/images/misc/attack.png'; @@ -14,7 +14,7 @@ import { FilterHelpers } from '../queryable/filter/FilterHelpers'; import { isEmptyFilter } from '../queryable/filter/FilterUtils'; import type { Page } from '../queryable/Page'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', alignItems: 'center', @@ -70,7 +70,7 @@ const PaginationComponent = ({ children, }: Props) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); // Pagination diff --git a/openbas-front/src/components/common/pagination/SortHeadersComponent.tsx b/openbas-front/src/components/common/pagination/SortHeadersComponent.tsx index 65cbef7a0a..d8d7c3c694 100644 --- a/openbas-front/src/components/common/pagination/SortHeadersComponent.tsx +++ b/openbas-front/src/components/common/pagination/SortHeadersComponent.tsx @@ -1,11 +1,11 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { SearchPaginationInput } from '../../../utils/api-types'; import { useFormatter } from '../../i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ sortableHeaderItem: { display: 'flex', fontSize: 12, @@ -57,7 +57,7 @@ const SortHeadersComponent: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const [sortBy, setSortBy] = useState(searchPaginationInput.sorts?.[0].property ?? ''); const [sortAsc, setSortAsc] = useState(defaultSortAsc); diff --git a/openbas-front/src/components/common/queryable/filter/FilterAutocomplete.tsx b/openbas-front/src/components/common/queryable/filter/FilterAutocomplete.tsx index 36b8fbb6b5..4f487265a2 100644 --- a/openbas-front/src/components/common/queryable/filter/FilterAutocomplete.tsx +++ b/openbas-front/src/components/common/queryable/filter/FilterAutocomplete.tsx @@ -1,7 +1,7 @@ import { FilterListOffOutlined } from '@mui/icons-material'; import { Autocomplete as MuiAutocomplete, IconButton, TextField, Tooltip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { Filter, FilterGroup } from '../../../../utils/api-types'; import { Option } from '../../../../utils/Option'; @@ -9,7 +9,7 @@ import { useFormatter } from '../../../i18n'; import { FilterHelpers } from './FilterHelpers'; import { buildEmptyFilter } from './FilterUtils'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', gap: 10, @@ -34,7 +34,7 @@ const FilterAutocomplete: FunctionComponent = ({ style, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [inputValue, setInputValue] = useState(''); diff --git a/openbas-front/src/components/common/queryable/filter/FilterChipValues.tsx b/openbas-front/src/components/common/queryable/filter/FilterChipValues.tsx index 45ff32766a..1852e70c45 100644 --- a/openbas-front/src/components/common/queryable/filter/FilterChipValues.tsx +++ b/openbas-front/src/components/common/queryable/filter/FilterChipValues.tsx @@ -1,16 +1,14 @@ import { Box } from '@mui/material'; -import { makeStyles } from '@mui/styles'; -import classNames from 'classnames'; import { Fragment, FunctionComponent, useEffect } from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { Filter, PropertySchemaDTO } from '../../../../utils/api-types'; import { Option } from '../../../../utils/Option'; import { useFormatter } from '../../../i18n'; -import type { Theme } from '../../../Theme'; import { convertOperatorToIcon } from './FilterUtils'; import useRetrieveOptions from './useRetrieveOptions'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ mode: { display: 'inline-block', height: '100%', @@ -48,7 +46,7 @@ const FilterChipValues: FunctionComponent = ({ }) => { // Standard hooks const { t, fldt } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); const { options, searchOptions } = useRetrieveOptions(); @@ -80,7 +78,7 @@ const FilterChipValues: FunctionComponent = ({ return ( <> {t(filter.key)} @@ -109,19 +107,21 @@ const FilterChipValues: FunctionComponent = ({ } return ( - - - {t(filter.key)} - {convertOperatorToIcon(t, filter.operator)} - - {' '} - - {toValues(options)} - - + ( + + + {t(filter.key)} + {convertOperatorToIcon(t, filter.operator)} + + {' '} + + {toValues(options)} + + + ) ); }; diff --git a/openbas-front/src/components/common/queryable/pagination/PaginationComponentV2.tsx b/openbas-front/src/components/common/queryable/pagination/PaginationComponentV2.tsx index b50b61de4e..96fd623734 100644 --- a/openbas-front/src/components/common/queryable/pagination/PaginationComponentV2.tsx +++ b/openbas-front/src/components/common/queryable/pagination/PaginationComponentV2.tsx @@ -1,7 +1,7 @@ import { Box, Button, Chip } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; import { useEffect, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import InjectorContractSwitchFilter from '../../../../admin/components/common/filters/InjectorContractSwitchFilter'; import MitreFilter, { MITRE_FILTER_KEY } from '../../../../admin/components/common/filters/MitreFilter'; @@ -19,7 +19,7 @@ import { QueryableHelpers } from '../QueryableHelpers'; import TextSearchComponent from '../textSearch/TextSearchComponent'; import TablePaginationComponentV2 from './TablePaginationComponentV2'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ topbar: { display: 'flex', alignItems: 'center', @@ -65,7 +65,7 @@ const PaginationComponentV2 = ({ reloadContentCount = 0, }: Props) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [properties, setProperties] = useState([]); diff --git a/openbas-front/src/components/common/queryable/pagination/TablePaginationComponent.tsx b/openbas-front/src/components/common/queryable/pagination/TablePaginationComponent.tsx index 7730f963bc..1906dd2e80 100644 --- a/openbas-front/src/components/common/queryable/pagination/TablePaginationComponent.tsx +++ b/openbas-front/src/components/common/queryable/pagination/TablePaginationComponent.tsx @@ -1,12 +1,12 @@ import { TablePagination, ToggleButtonGroup } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import ExportButton, { ExportProps } from '../../ExportButton'; import { PaginationHelpers } from './PaginationHelpers'; import { ROWS_PER_PAGE_OPTIONS } from './usPaginationState'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { display: 'flex', alignItems: 'center', @@ -29,7 +29,7 @@ const TablePaginationComponent = ({ children, }: Props) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const handleChangePage = ( _event: React.MouseEvent | null, diff --git a/openbas-front/src/components/common/queryable/sort/SortHeadersComponentV2.tsx b/openbas-front/src/components/common/queryable/sort/SortHeadersComponentV2.tsx index 96439a8fa4..a9e94965de 100644 --- a/openbas-front/src/components/common/queryable/sort/SortHeadersComponentV2.tsx +++ b/openbas-front/src/components/common/queryable/sort/SortHeadersComponentV2.tsx @@ -1,12 +1,12 @@ import { ArrowDropDownOutlined, ArrowDropUpOutlined } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../i18n'; import { Header } from '../../SortHeadersList'; import { SortHelpers } from './SortHelpers'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ sortableHeaderItem: { display: 'flex', fontSize: 12, @@ -44,7 +44,7 @@ const SortHeadersComponentV2: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const sortComponent = (asc: boolean) => { return asc ? () : (); diff --git a/openbas-front/src/components/fields/DocumentField.tsx b/openbas-front/src/components/fields/DocumentField.tsx index 4708aabe5b..ff19877578 100644 --- a/openbas-front/src/components/fields/DocumentField.tsx +++ b/openbas-front/src/components/fields/DocumentField.tsx @@ -1,8 +1,8 @@ import { Autocomplete as MuiAutocomplete, Box, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FileOutline } from 'mdi-material-ui'; import { CSSProperties, FunctionComponent } from 'react'; import { FieldErrors } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../actions/Document'; import type { DocumentHelper } from '../../actions/helper'; @@ -11,7 +11,7 @@ import type { Document } from '../../utils/api-types'; import { useAppDispatch } from '../../utils/hooks'; import useDataLoader from '../../utils/hooks/useDataLoader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -45,7 +45,7 @@ const DocumentField: FunctionComponent = ({ style, extensions = [], }) => { - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { documents }: { documents: [Document] } = useHelper((helper: DocumentHelper) => ({ diff --git a/openbas-front/src/components/fields/FileLoader.tsx b/openbas-front/src/components/fields/FileLoader.tsx index d68b6b6451..4d20979fc3 100644 --- a/openbas-front/src/components/fields/FileLoader.tsx +++ b/openbas-front/src/components/fields/FileLoader.tsx @@ -1,8 +1,8 @@ import { AttachmentOutlined, ControlPointOutlined } from '@mui/icons-material'; import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Typography } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, useEffect, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../actions/Document'; import type { DocumentHelper } from '../../actions/helper'; @@ -14,10 +14,9 @@ import useDataLoader from '../../utils/hooks/useDataLoader'; import ButtonPopover, { PopoverEntry } from '../common/ButtonPopover'; import { useFormatter } from '../i18n'; import ItemTags from '../ItemTags'; -import type { Theme } from '../Theme'; import FileTransferDialog from './FileTransferDialog'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ bodyItem: { height: '100%', fontSize: 13, @@ -99,7 +98,7 @@ const FileLoader: React.FC = ({ InputLabelProps, error, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); diff --git a/openbas-front/src/components/fields/FileTransferDialog.tsx b/openbas-front/src/components/fields/FileTransferDialog.tsx index a8637ffd39..9bb27d73a3 100644 --- a/openbas-front/src/components/fields/FileTransferDialog.tsx +++ b/openbas-front/src/components/fields/FileTransferDialog.tsx @@ -1,8 +1,8 @@ import { DescriptionOutlined } from '@mui/icons-material'; import { Box, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, Grid, List, ListItem, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useEffect, useState } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { DocumentHelper, UserHelper } from '../../actions/helper'; import TagsFilter from '../../admin/components/common/filters/TagsFilter'; @@ -14,9 +14,8 @@ import Transition from '../common/Transition'; import { useFormatter } from '../i18n'; import ItemTags from '../ItemTags'; import SearchFilter from '../SearchFilter'; -import type { Theme } from '../Theme'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ box: { width: '100%', minHeight: '100%', @@ -58,7 +57,7 @@ const FileTransferDialog: React.FC = ({ initialDocumentIds = [], onSubmitAddDocuments, }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [keyword, setKeyword] = useState(''); diff --git a/openbas-front/src/components/fields/MultipleFileLoader.tsx b/openbas-front/src/components/fields/MultipleFileLoader.tsx index 510580f41a..c5805c40f7 100644 --- a/openbas-front/src/components/fields/MultipleFileLoader.tsx +++ b/openbas-front/src/components/fields/MultipleFileLoader.tsx @@ -1,7 +1,7 @@ import { ControlPointOutlined } from '@mui/icons-material'; import { ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, useContext, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { fetchDocuments } from '../../actions/Document'; import { PermissionsContext } from '../../admin/components/common/Context'; @@ -9,10 +9,9 @@ import type { RawDocument } from '../../utils/api-types'; import { useAppDispatch } from '../../utils/hooks'; import useDataLoader from '../../utils/hooks/useDataLoader'; import { useFormatter } from '../i18n'; -import type { Theme } from '../Theme'; import FileTransferDialog from './FileTransferDialog'; -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()(theme => ({ item: { paddingLeft: 10, height: 50, @@ -36,7 +35,7 @@ const MultipleFileLoader: FunctionComponent = ({ initialDocumentIds, }) => { // Standard hooks - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const dispatch = useAppDispatch(); const { permissions } = useContext(PermissionsContext); diff --git a/openbas-front/src/components/fields/OldMarkDownField.tsx b/openbas-front/src/components/fields/OldMarkDownField.tsx index 376ad5125c..6bac83f331 100644 --- a/openbas-front/src/components/fields/OldMarkDownField.tsx +++ b/openbas-front/src/components/fields/OldMarkDownField.tsx @@ -5,7 +5,6 @@ import { Field, FieldInputProps, FieldMetaState } from 'react-final-form'; import TextFieldAskAI from '../../admin/components/common/form/TextFieldAskAI'; import { useFormatter } from '../i18n'; -import type { Theme } from '../Theme'; interface Props { label: string; @@ -29,7 +28,7 @@ const MarkDownFieldBase: React.FC = ({ inArticle, }) => { const { t } = useFormatter(); - const theme = useTheme(); + const theme = useTheme(); return (
({ +const useStyles = makeStyles()(theme => ({ errorColor: { color: theme.palette.error.main, }, @@ -25,47 +24,49 @@ const RichTextFieldBase = ({ context, }) => { const { t } = useFormatter(); - const classes = useStyles(); + const { classes, cx } = useStyles(); return ( -
- - {label} - - { - onChange(editor.getData()); - }} - onBlur={event => onBlur(event)} - disabled={disabled} - /> - {touched && invalid - && ( - - {(error && t(error)) || (submitError && t(submitError))} - - )} - {askAi && ( - { - onChange(val); + ( +
+ + {label} + + { + onChange(editor.getData()); }} - format="html" - variant="ckeditor" + onBlur={event => onBlur(event)} disabled={disabled} - inInject={inInject} - context={context} /> - )} -
+ {touched && invalid + && ( + + {(error && t(error)) || (submitError && t(submitError))} + + )} + {askAi && ( + { + onChange(val); + }} + format="html" + variant="ckeditor" + disabled={disabled} + inInject={inInject} + context={context} + /> + )} +
+ ) ); }; diff --git a/openbas-front/src/components/fields/SecurityPlatformField.tsx b/openbas-front/src/components/fields/SecurityPlatformField.tsx index 37f7103793..ccddce858a 100644 --- a/openbas-front/src/components/fields/SecurityPlatformField.tsx +++ b/openbas-front/src/components/fields/SecurityPlatformField.tsx @@ -1,7 +1,8 @@ import { Autocomplete as MuiAutocomplete, Box, TextField } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { CSSProperties, FunctionComponent } from 'react'; import { FieldErrors } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { SecurityPlatformHelper } from '../../actions/assets/asset-helper'; import { fetchSecurityPlatforms } from '../../actions/assets/securityPlatform-actions'; @@ -9,9 +10,8 @@ import { useHelper } from '../../store'; import type { SecurityPlatform } from '../../utils/api-types'; import { useAppDispatch } from '../../utils/hooks'; import useDataLoader from '../../utils/hooks/useDataLoader'; -import type { Theme } from '../Theme'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -59,8 +59,8 @@ const SecurityPlatformField: FunctionComponent = ({ editing, }) => { // Standard hooks - const theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const dispatch = useAppDispatch(); // Fetching data diff --git a/openbas-front/src/components/fields/TagField.tsx b/openbas-front/src/components/fields/TagField.tsx index 90e439cc50..186a2a916a 100644 --- a/openbas-front/src/components/fields/TagField.tsx +++ b/openbas-front/src/components/fields/TagField.tsx @@ -1,9 +1,9 @@ import { AddOutlined, LabelOutlined } from '@mui/icons-material'; import { Autocomplete as MuiAutocomplete, Box, Dialog, DialogContent, DialogTitle, IconButton, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import * as R from 'ramda'; import { CSSProperties, FunctionComponent, useState } from 'react'; import { FieldErrors } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { TagHelper, UserHelper } from '../../actions/helper'; import { addTag } from '../../actions/Tag'; @@ -13,7 +13,7 @@ import type { Tag } from '../../utils/api-types'; import { useAppDispatch } from '../../utils/hooks'; import { useFormatter } from '../i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -47,7 +47,7 @@ const TagField: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { tags, userAdmin }: { tags: [Tag]; userAdmin: boolean } = useHelper((helper: TagHelper & UserHelper) => ({ diff --git a/openbas-front/src/components/fields/TagFieldSingle.tsx b/openbas-front/src/components/fields/TagFieldSingle.tsx index adca3a7e1e..1a6c62f931 100644 --- a/openbas-front/src/components/fields/TagFieldSingle.tsx +++ b/openbas-front/src/components/fields/TagFieldSingle.tsx @@ -1,8 +1,8 @@ import { AddOutlined, LabelOutlined } from '@mui/icons-material'; import { Autocomplete as MuiAutocomplete, Box, Dialog, DialogContent, DialogTitle, IconButton, TextField } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { CSSProperties, FunctionComponent, useState } from 'react'; import { FieldErrors } from 'react-hook-form'; +import { makeStyles } from 'tss-react/mui'; import type { TagHelper, UserHelper } from '../../actions/helper'; import { addTag } from '../../actions/Tag'; @@ -12,7 +12,7 @@ import type { Tag } from '../../utils/api-types'; import { useAppDispatch } from '../../utils/hooks'; import { useFormatter } from '../i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ icon: { paddingTop: 4, display: 'inline-block', @@ -50,7 +50,7 @@ const TagFieldSingle: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); // Fetching data const { tags, userAdmin }: { tags: [Tag]; userAdmin: boolean } = useHelper((helper: TagHelper & UserHelper) => ({ diff --git a/openbas-front/src/components/nodes/NodeInject.tsx b/openbas-front/src/components/nodes/NodeInject.tsx index a979c5eedb..6a87c2f84f 100644 --- a/openbas-front/src/components/nodes/NodeInject.tsx +++ b/openbas-front/src/components/nodes/NodeInject.tsx @@ -1,20 +1,18 @@ import { Tooltip } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { Handle, Node, NodeProps, OnConnect, Position, XYPosition } from '@xyflow/react'; import moment from 'moment'; import { memo } from 'react'; import * as React from 'react'; +import { makeStyles } from 'tss-react/mui'; import type { InjectOutputType, InjectStore } from '../../actions/injects/Inject'; import InjectIcon from '../../admin/components/common/injects/InjectIcon'; import InjectPopover from '../../admin/components/common/injects/InjectPopover'; import { isNotEmptyField } from '../../utils/utils'; import { useFormatter } from '../i18n'; -import type { Theme } from '../Theme'; -// Deprecated - https://mui.com/system/styles/basics/ -// Do not use it for new code. -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ node: { position: 'relative', border: @@ -110,8 +108,8 @@ export type NodeInject = Node<{ * @constructor */ const NodeInjectComponent = ({ data }: NodeProps) => { - const classes = useStyles(); - const theme: Theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const { ft, fld } = useFormatter(); /** diff --git a/openbas-front/src/components/nodes/NodePhantom.tsx b/openbas-front/src/components/nodes/NodePhantom.tsx index d29f06cfb2..3cf7b64d7f 100644 --- a/openbas-front/src/components/nodes/NodePhantom.tsx +++ b/openbas-front/src/components/nodes/NodePhantom.tsx @@ -1,10 +1,8 @@ import { AddCircleOutline } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; import { FunctionComponent, memo } from 'react'; +import { makeStyles } from 'tss-react/mui'; -import type { Theme } from '../Theme'; - -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ node: { 'border': '2px dashed rgba(255, 255, 255, 0.12)', 'borderLeft': '2px solid rgba(255, 255, 255, 0.3)', @@ -49,7 +47,7 @@ interface Props { * @constructor */ const NodePhantomComponent: FunctionComponent = (props) => { - const classes = useStyles(); + const { classes } = useStyles(); return ( <> diff --git a/openbas-front/src/components/scalebar/ScaleBar.tsx b/openbas-front/src/components/scalebar/ScaleBar.tsx index 3c841fd995..7daf56ffa1 100644 --- a/openbas-front/src/components/scalebar/ScaleBar.tsx +++ b/openbas-front/src/components/scalebar/ScaleBar.tsx @@ -1,11 +1,11 @@ -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { FunctionComponent } from 'react'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../i18n'; -import type { Theme } from '../Theme'; import { Scale } from './Tick'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ scaleBar: { position: 'relative', }, @@ -57,8 +57,8 @@ const ScaleBar: FunctionComponent = ({ }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); - const theme = useTheme(); + const { classes } = useStyles(); + const theme = useTheme(); const scale: Scale = { min: { value: 0, diff --git a/openbas-front/src/private/Index.tsx b/openbas-front/src/private/Index.tsx index 204451aa51..a526165659 100644 --- a/openbas-front/src/private/Index.tsx +++ b/openbas-front/src/private/Index.tsx @@ -1,14 +1,14 @@ -import { makeStyles } from '@mui/styles'; import { Route, Routes } from 'react-router'; +import { CSSObject } from 'tss-react'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../components/Error'; import NotFound from '../components/NotFound'; -import type { Theme } from '../components/Theme'; import useDataLoader from '../utils/hooks/useDataLoader'; import Dashboard from './components/Dashboard'; import TopBar from './components/nav/TopBar'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ root: { minWidth: 1280, height: '100%', @@ -20,11 +20,11 @@ const useStyles = makeStyles(theme => ({ padding: '24px 24px 24px 204px', minWidth: 0, }, - toolbar: theme.mixins.toolbar, + toolbar: theme.mixins.toolbar as CSSObject, })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); useDataLoader(); return (
diff --git a/openbas-front/src/private/components/Dashboard.js b/openbas-front/src/private/components/Dashboard.js deleted file mode 100644 index 11d5f336cc..0000000000 --- a/openbas-front/src/private/components/Dashboard.js +++ /dev/null @@ -1,25 +0,0 @@ -import { withStyles, withTheme } from '@mui/styles'; -import * as PropTypes from 'prop-types'; -import * as R from 'ramda'; - -import inject18n, { useFormatter } from '../../components/i18n'; - -const styles = () => ({ - root: { - flexGrow: 1, - }, -}); - -const Dashboard = (props) => { - const { classes } = props; - const { t } = useFormatter(); - return
{t('Player dashboard!')}
; -}; - -Dashboard.propTypes = { - classes: PropTypes.object, - theme: PropTypes.object, - t: PropTypes.func, -}; - -export default R.compose(inject18n, withTheme, withStyles(styles))(Dashboard); diff --git a/openbas-front/src/private/components/Dashboard.tsx b/openbas-front/src/private/components/Dashboard.tsx new file mode 100644 index 0000000000..b7a85a59cf --- /dev/null +++ b/openbas-front/src/private/components/Dashboard.tsx @@ -0,0 +1,17 @@ +import { makeStyles } from 'tss-react/mui'; + +import { useFormatter } from '../../components/i18n'; + +const useStyles = makeStyles()({ + root: { + flexGrow: 1, + }, +}); + +const Dashboard = () => { + const { classes } = useStyles(); + const { t } = useFormatter(); + return
{t('Player dashboard!')}
; +}; + +export default Dashboard; diff --git a/openbas-front/src/private/components/nav/TopBar.tsx b/openbas-front/src/private/components/nav/TopBar.tsx index dbd1edd73c..d27283fb05 100644 --- a/openbas-front/src/private/components/nav/TopBar.tsx +++ b/openbas-front/src/private/components/nav/TopBar.tsx @@ -1,16 +1,16 @@ import { AccountCircleOutlined } from '@mui/icons-material'; import { AppBar, IconButton, Menu, MenuItem, MenuProps, Toolbar } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { useState } from 'react'; import * as React from 'react'; import { Link, useNavigate } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { logout } from '../../../actions/Application'; import { useFormatter } from '../../../components/i18n'; -import type { Theme } from '../../../components/Theme'; import { useAppDispatch } from '../../../utils/hooks'; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ appBar: { width: '100%', zIndex: theme.zIndex.drawer + 1, @@ -35,8 +35,8 @@ const useStyles = makeStyles(theme => ({ })); const TopBar: React.FC = () => { - const theme = useTheme(); - const classes = useStyles(); + const theme = useTheme(); + const { classes } = useStyles(); const { t } = useFormatter(); const navigate = useNavigate(); const [open, setOpen] = useState(false); diff --git a/openbas-front/src/public/Index.tsx b/openbas-front/src/public/Index.tsx index 987da8e8e1..97f8b8db42 100644 --- a/openbas-front/src/public/Index.tsx +++ b/openbas-front/src/public/Index.tsx @@ -1,11 +1,10 @@ -import { makeStyles } from '@mui/styles'; import * as PropTypes from 'prop-types'; import { lazy, Suspense } from 'react'; import { Route, Routes } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { errorWrapper } from '../components/Error'; import Loader from '../components/Loader'; -import type { Theme } from '../components/Theme'; import Reset from './components/login/Reset'; const Login = lazy(() => import('./components/login/Login')); @@ -15,7 +14,7 @@ const Challenges = lazy(() => import('./components/challenges/Challenges')); const ExerciseViewLessons = lazy(() => import('./components/lessons/ExerciseViewLessons')); const ScenarioViewLessons = lazy(() => import('./components/lessons/ScenarioViewLessons')); -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles()(theme => ({ root: { minWidth: 1280, height: '100%', @@ -31,7 +30,7 @@ const useStyles = makeStyles(theme => ({ })); const Index = () => { - const classes = useStyles(); + const { classes } = useStyles(); return (
diff --git a/openbas-front/src/public/components/challenges/ChallengesPlayer.js b/openbas-front/src/public/components/challenges/ChallengesPlayer.js index 92a55c22df..667b6ba949 100644 --- a/openbas-front/src/public/components/challenges/ChallengesPlayer.js +++ b/openbas-front/src/public/components/challenges/ChallengesPlayer.js @@ -30,12 +30,13 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { useEffect, useState } from 'react'; import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchMe } from '../../../actions/Application'; import { fetchPlayerChallenges, validateChallenge } from '../../../actions/Challenge'; @@ -52,7 +53,7 @@ import { useHelper } from '../../../store'; import { useQueryParameter } from '../../../utils/Environment'; import { usePermissions } from '../../../utils/Exercise'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -156,7 +157,7 @@ const inlineStyles = { const ChallengesPlayer = () => { const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const [currentChallengeEntry, setCurrentChallengeEntry] = useState(null); diff --git a/openbas-front/src/public/components/challenges/ChallengesPreview.js b/openbas-front/src/public/components/challenges/ChallengesPreview.js index 0f29875c64..6c286248c8 100644 --- a/openbas-front/src/public/components/challenges/ChallengesPreview.js +++ b/openbas-front/src/public/components/challenges/ChallengesPreview.js @@ -28,12 +28,13 @@ import { Tooltip, Typography, } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { useEffect, useState } from 'react'; import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchMe } from '../../../actions/Application'; import { fetchObserverChallenges, tryChallenge } from '../../../actions/Challenge'; @@ -50,7 +51,7 @@ import { useHelper } from '../../../store'; import { useQueryParameter } from '../../../utils/Environment'; import { usePermissions } from '../../../utils/Exercise'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -154,7 +155,7 @@ const inlineStyles = { const ChallengesPreview = () => { const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const [currentChallenge, setCurrentChallenge] = useState(null); diff --git a/openbas-front/src/public/components/channels/ChannelMicroblogging.js b/openbas-front/src/public/components/channels/ChannelMicroblogging.js index a8ea08fde3..47d73b8e58 100644 --- a/openbas-front/src/public/components/channels/ChannelMicroblogging.js +++ b/openbas-front/src/public/components/channels/ChannelMicroblogging.js @@ -1,6 +1,7 @@ import { ChatBubbleOutlineOutlined, FavoriteBorderOutlined, ShareOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, CardMedia, Grid, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../components/Empty'; import ExpandableMarkdown from '../../../components/ExpandableMarkdown'; @@ -8,7 +9,7 @@ import { useFormatter } from '../../../components/i18n'; import { useHelper } from '../../../store'; import { useQueryParameter } from '../../../utils/Environment'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '0 auto', width: 900, @@ -31,7 +32,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelMicroblogging = ({ channelReader }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const [userId] = useQueryParameter(['user']); const { t, fldt } = useFormatter(); diff --git a/openbas-front/src/public/components/channels/ChannelNewspaper.js b/openbas-front/src/public/components/channels/ChannelNewspaper.js index b0ec005489..b3c8348e4f 100644 --- a/openbas-front/src/public/components/channels/ChannelNewspaper.js +++ b/openbas-front/src/public/components/channels/ChannelNewspaper.js @@ -1,8 +1,9 @@ import { ChatBubbleOutlineOutlined, FavoriteBorderOutlined, MoreHorizOutlined, ShareOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, CardMedia, Dialog, DialogContent, DialogTitle, Grid, Slide, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { forwardRef, useState } from 'react'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../components/Empty'; import ExpandableMarkdown from '../../../components/ExpandableMarkdown'; @@ -15,7 +16,7 @@ const Transition = forwardRef((props, ref) => ( )); Transition.displayName = 'TransitionSlide'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '0 auto', width: 1200, @@ -37,7 +38,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelNewspaper = ({ channelReader }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const { t, fldt } = useFormatter(); const [userId] = useQueryParameter(['user']); diff --git a/openbas-front/src/public/components/channels/ChannelPlayer.js b/openbas-front/src/public/components/channels/ChannelPlayer.js index af93bd5935..a01c9684d2 100644 --- a/openbas-front/src/public/components/channels/ChannelPlayer.js +++ b/openbas-front/src/public/components/channels/ChannelPlayer.js @@ -1,8 +1,8 @@ import { Button } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchMe } from '../../../actions/Application'; import { fetchPlayerChannel } from '../../../actions/channels/channel-action'; @@ -16,7 +16,7 @@ import ChannelMicroblogging from './ChannelMicroblogging'; import ChannelNewspaper from './ChannelNewspaper'; import ChannelTvChannel from './ChannelTvChannel'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -25,7 +25,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelPlayer = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const [userId, articleId] = useQueryParameter(['user', 'article']); diff --git a/openbas-front/src/public/components/channels/ChannelPreview.js b/openbas-front/src/public/components/channels/ChannelPreview.js index 4317dfd01d..249f4eb977 100644 --- a/openbas-front/src/public/components/channels/ChannelPreview.js +++ b/openbas-front/src/public/components/channels/ChannelPreview.js @@ -1,8 +1,8 @@ import { Button } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { Link, useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchMe } from '../../../actions/Application'; import { fetchObserverChannel } from '../../../actions/channels/channel-action'; @@ -16,7 +16,7 @@ import ChannelMicroblogging from './ChannelMicroblogging'; import ChannelNewspaper from './ChannelNewspaper'; import ChannelTvChannel from './ChannelTvChannel'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -25,7 +25,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelPreview = () => { - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { t } = useFormatter(); const [userId, articleId] = useQueryParameter(['user', 'article']); diff --git a/openbas-front/src/public/components/channels/ChannelTvChannel.js b/openbas-front/src/public/components/channels/ChannelTvChannel.js index 8f92ae54c5..4e2ccad305 100644 --- a/openbas-front/src/public/components/channels/ChannelTvChannel.js +++ b/openbas-front/src/public/components/channels/ChannelTvChannel.js @@ -1,7 +1,8 @@ import { ChatBubbleOutlineOutlined, FavoriteBorderOutlined, ShareOutlined } from '@mui/icons-material'; import { Avatar, Button, Card, CardContent, CardHeader, CardMedia, Grid, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../components/Empty'; import ExpandableMarkdown from '../../../components/ExpandableMarkdown'; @@ -9,7 +10,7 @@ import { useFormatter } from '../../../components/i18n'; import { useHelper } from '../../../store'; import { useQueryParameter } from '../../../utils/Environment'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { margin: '0 auto', width: 1200, @@ -31,7 +32,7 @@ const useStyles = makeStyles(() => ({ })); const ChannelTvChannel = ({ channelReader }) => { - const classes = useStyles(); + const { classes } = useStyles(); const theme = useTheme(); const { t, fldt } = useFormatter(); const [userId] = useQueryParameter(['user']); diff --git a/openbas-front/src/public/components/comcheck/Comcheck.js b/openbas-front/src/public/components/comcheck/Comcheck.js index 1930330b4b..ffa19ccdf7 100644 --- a/openbas-front/src/public/components/comcheck/Comcheck.js +++ b/openbas-front/src/public/components/comcheck/Comcheck.js @@ -1,15 +1,16 @@ import { CheckCircleOutlineOutlined } from '@mui/icons-material'; import { AppBar, Paper, Toolbar } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useParams } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { fetchComcheckStatus } from '../../../actions/Comcheck'; import { useFormatter } from '../../../components/i18n'; import { useHelper } from '../../../store'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { textAlign: 'center', margin: '0 auto', @@ -37,7 +38,7 @@ const useStyles = makeStyles(() => ({ const Comcheck = () => { const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const dispatch = useDispatch(); const { fldt, t } = useFormatter(); const { statusId } = useParams(); diff --git a/openbas-front/src/public/components/lessons/LessonsPlayer.js b/openbas-front/src/public/components/lessons/LessonsPlayer.js index a5a5d278a1..9ff27756da 100644 --- a/openbas-front/src/public/components/lessons/LessonsPlayer.js +++ b/openbas-front/src/public/components/lessons/LessonsPlayer.js @@ -1,9 +1,10 @@ import { Button, Dialog, DialogActions, DialogContent, DialogContentText, Grid, Paper, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { useContext, useState } from 'react'; import { Form } from 'react-final-form'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import { ViewLessonContext } from '../../../admin/components/common/Context'; import Transition from '../../../components/common/Transition'; @@ -13,7 +14,7 @@ import SliderField from '../../../components/fields/SliderField'; import { useFormatter } from '../../../components/i18n'; import Loader from '../../../components/Loader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -40,7 +41,7 @@ const LessonsPlayer = (props) => { } = props; const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const [openValidate, setOpenValidate] = useState(false); diff --git a/openbas-front/src/public/components/lessons/LessonsPreview.js b/openbas-front/src/public/components/lessons/LessonsPreview.js index 6215254fb1..a531bca7d6 100644 --- a/openbas-front/src/public/components/lessons/LessonsPreview.js +++ b/openbas-front/src/public/components/lessons/LessonsPreview.js @@ -1,8 +1,9 @@ import { Button, Grid, Paper, Typography } from '@mui/material'; -import { makeStyles, useTheme } from '@mui/styles'; +import { useTheme } from '@mui/material/styles'; import * as R from 'ramda'; import { Form } from 'react-final-form'; import { Link } from 'react-router'; +import { makeStyles } from 'tss-react/mui'; import Empty from '../../../components/Empty'; import OldTextField from '../../../components/fields/OldTextField'; @@ -10,7 +11,7 @@ import SliderField from '../../../components/fields/SliderField'; import { useFormatter } from '../../../components/i18n'; import Loader from '../../../components/Loader'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ root: { position: 'relative', flexGrow: 1, @@ -40,7 +41,7 @@ const LessonsPreview = (props) => { } = props; const theme = useTheme(); - const classes = useStyles(); + const { classes } = useStyles(); const { t } = useFormatter(); const validate = (values) => { diff --git a/openbas-front/src/public/components/login/Login.js b/openbas-front/src/public/components/login/Login.tsx similarity index 75% rename from openbas-front/src/public/components/login/Login.js rename to openbas-front/src/public/components/login/Login.tsx index aa76cdb106..31311a8751 100644 --- a/openbas-front/src/public/components/login/Login.js +++ b/openbas-front/src/public/components/login/Login.tsx @@ -1,36 +1,32 @@ import { Box, Checkbox, Paper } from '@mui/material'; -import { useTheme, withStyles } from '@mui/styles'; -import * as PropTypes from 'prop-types'; -import * as R from 'ramda'; +import { useTheme } from '@mui/material/styles'; import { useEffect, useState } from 'react'; import Markdown from 'react-markdown'; -import { connect } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { askToken, checkKerberos, fetchPlatformParameters } from '../../../actions/Application'; -import { storeHelper } from '../../../actions/Schema'; -import inject18n from '../../../components/i18n'; +import type { LoggedHelper } from '../../../actions/helper'; +import { useFormatter } from '../../../components/i18n'; import byFiligranDark from '../../../static/images/by_filigran_dark.png'; import byFiligranLight from '../../../static/images/by_filigran_light.png'; import logoDark from '../../../static/images/logo_text_dark.png'; import logoLight from '../../../static/images/logo_text_light.png'; +import { useHelper } from '../../../store'; import { fileUri } from '../../../utils/Environment'; +import { useAppDispatch } from '../../../utils/hooks'; import { isNotEmptyField } from '../../../utils/utils'; import LoginError from './LoginError'; import LoginForm from './LoginForm'; import LoginSSOButton from './LoginSSOButton'; import Reset from './Reset'; -const styles = () => ({ +const useStyles = makeStyles()(() => ({ container: { textAlign: 'center', margin: '0 auto', width: '80%', paddingBottom: 50, }, - appBar: { - borderTopLeftRadius: '10px', - borderTopRightRadius: '10px', - }, login: { textAlign: 'center', margin: '0 auto', @@ -51,20 +47,26 @@ const styles = () => ({ textAlign: 'center', maxWidth: 500, }, -}); +})); -const Login = (props) => { +const Login = () => { const theme = useTheme(); - const { classes, parameters, t } = props; + const { classes } = useStyles(); + const { t } = useFormatter(); + const dispatch = useAppDispatch(); + const { settings } = useHelper((helper: LoggedHelper) => { + return { settings: helper.getPlatformSettings() }; + }); + const { auth_openid_enable: isOpenId, auth_saml2_enable: isSaml2, auth_local_enable: isLocal, - } = parameters; + } = settings; const { platform_openid_providers: openidProviders, platform_saml2_providers: saml2Providers, - } = parameters; + } = settings; const [reset, setReset] = useState(false); const [dimension, setDimension] = useState({ width: window.innerWidth, @@ -78,10 +80,10 @@ const Login = (props) => { return () => window.removeEventListener('resize', updateWindowDimensions); }); useEffect(() => { - props.fetchPlatformParameters(); - props.checkKerberos(); - }, []); - const onSubmit = data => props.askToken(data.username, data.password); + dispatch(fetchPlatformParameters()); + dispatch(checkKerberos()); + }); + const onSubmit = (data: { username: string; password: string }) => dispatch(askToken(data.username, data.password)); let loginHeight = 320; if ((isOpenId || isSaml2) && isLocal) { loginHeight = 440; @@ -90,17 +92,17 @@ const Login = (props) => { } const marginTop = dimension.height / 2 - loginHeight / 2 - 100; const loginLogo = theme.palette.mode === 'dark' - ? parameters?.platform_dark_theme?.logo_login_url - : parameters?.platform_light_theme?.logo_login_url; + ? settings?.platform_dark_theme?.logo_login_url + : settings?.platform_light_theme?.logo_login_url; - const isWhitemarkEnable = parameters.platform_whitemark === 'true' - && parameters.platform_enterprise_edition === 'true'; + const isWhitemarkEnable = settings.platform_whitemark === 'true' + && settings.platform_enterprise_edition === 'true'; // POLICIES - const loginMessage = parameters.platform_policies?.platform_login_message; - const consentMessage = parameters.platform_policies?.platform_consent_message; - const consentConfirmText = parameters.platform_policies?.platform_consent_confirm_text - ? parameters.platform_policies.platform_consent_confirm_text + const loginMessage = settings.platform_policies?.platform_login_message; + const consentMessage = settings.platform_policies?.platform_consent_message; + const consentConfirmText = settings.platform_policies?.platform_consent_confirm_text + ? settings.platform_policies.platform_consent_confirm_text : t('I have read and comply with the above statement'); const isLoginMessage = isNotEmptyField(loginMessage); const isConsentMessage = isNotEmptyField(consentMessage); @@ -129,7 +131,7 @@ const Login = (props) => { style={{ marginBottom: isWhitemarkEnable ? 20 : 0 }} /> {!isWhitemarkEnable && ( -
+
{ ); }; -Login.propTypes = { - t: PropTypes.func, - demo: PropTypes.string, - askToken: PropTypes.func, - checkKerberos: PropTypes.func, - classes: PropTypes.object, - parameters: PropTypes.object, -}; - -const select = (state) => { - const helper = storeHelper(state); - const parameters = helper.getPlatformSettings() ?? {}; - return { parameters }; -}; - -export default R.compose( - connect(select, { askToken, checkKerberos, fetchPlatformParameters }), - inject18n, - withStyles(styles), -)(Login); +export default Login; diff --git a/openbas-front/src/public/components/login/Reset.js b/openbas-front/src/public/components/login/Reset.js index 6a8689a221..d627822f24 100644 --- a/openbas-front/src/public/components/login/Reset.js +++ b/openbas-front/src/public/components/login/Reset.js @@ -1,14 +1,14 @@ import { Button, Paper } from '@mui/material'; -import { makeStyles } from '@mui/styles'; import { useState } from 'react'; import { Form } from 'react-final-form'; import { useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; import { askReset, resetPassword, validateResetToken } from '../../../actions/Application'; import OldTextField from '../../../components/fields/OldTextField'; import { useFormatter } from '../../../components/i18n'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles()(() => ({ container: { textAlign: 'center', margin: '0 auto', @@ -30,7 +30,7 @@ const STEP_ASK_RESET = 'ask'; const STEP_VALIDATE_TOKEN = 'validate'; const STEP_RESET_PASSWORD = 'reset'; const Reset = ({ onCancel }) => { - const classes = useStyles(); + const { classes } = useStyles(); const { t, locale } = useFormatter(); const dispatch = useDispatch(); const [step, setStep] = useState(STEP_ASK_RESET); diff --git a/openbas-front/src/public/components/systembanners/SystemBanners.tsx b/openbas-front/src/public/components/systembanners/SystemBanners.tsx index cceb1c75b6..5f09af9a5e 100644 --- a/openbas-front/src/public/components/systembanners/SystemBanners.tsx +++ b/openbas-front/src/public/components/systembanners/SystemBanners.tsx @@ -1,15 +1,14 @@ import { ReportProblem } from '@mui/icons-material'; -import { makeStyles } from '@mui/styles'; +import { makeStyles } from 'tss-react/mui'; import { useFormatter } from '../../../components/i18n'; -import type { Theme } from '../../../components/Theme'; import { isEmptyField, recordEntries, recordKeys } from '../../../utils/utils'; export const SYSTEM_BANNER_HEIGHT_PER_MESSAGE = 18; /* eslint-disable */ /* Avoid auto-lint removal using --fix with false positive finding of: */ -const useStyles = makeStyles((theme: Theme) => ({ +const useStyles = makeStyles()((theme) => ({ banner: { position: 'fixed', zIndex: 2000, @@ -55,7 +54,7 @@ const SystemBanners = (settings: { }) => { // Standard hooks const { t } = useFormatter(); - const classes = useStyles(); + const { classes } = useStyles(); const bannerLevel = settings.settings.platform_banner_by_level; let numberOfElements = 0; if (settings.settings.platform_banner_by_level !== undefined) { diff --git a/openbas-front/src/utils/Charts.ts b/openbas-front/src/utils/Charts.ts index 6f4dfc1936..4b7f527856 100644 --- a/openbas-front/src/utils/Charts.ts +++ b/openbas-front/src/utils/Charts.ts @@ -1,8 +1,7 @@ +import { Theme } from '@mui/material'; import * as C from '@mui/material/colors'; import { ApexOptions } from 'apexcharts'; -import type { Theme } from '../components/Theme'; - type Temp = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800; export const colors = (temp: Temp): string[] => { diff --git a/openbas-front/src/utils/Localization.js b/openbas-front/src/utils/Localization.js index 3201f12d5d..81168c3b38 100644 --- a/openbas-front/src/utils/Localization.js +++ b/openbas-front/src/utils/Localization.js @@ -79,6 +79,7 @@ const i18n = { 'Notes': 'Notes', 'Please note that if you change the "Reply to" address, the email interaction functionality in the platform will be disabled.': 'Veuillez noter que si vous modifiez l\'adresse « Répondre à », la fonctionnalité d\'interaction par mail dans la plateforme sera désactivée.', 'If you remove the default email address, the email reception for this simulation / scenario will be disabled.': 'Si vous supprimez l\'adresse e-mail par défaut, la réception des e-mails pour cette simulation / ce scénario sera désactivée.', + 'Execution Time': 'Temps d\'exécution', 'Start date': 'Date de début', 'End date': 'Date de fin', 'To': 'A', @@ -266,7 +267,7 @@ const i18n = { 'Add target teams in this inject': 'Ajouter des équipes cibles dans ce stimuli', 'Modify target teams in this inject': - 'Modifier les équipes cibles dans ce stimuli', + 'Modifier les équipes cibles dans ce stimuli', 'Targeted teams': 'Equipes ciblées', 'Test the inject': 'Tester le stimuli', 'All teams': 'Toutes les équipes', @@ -310,6 +311,12 @@ const i18n = { 'This group will have planner permission on new simulations.': 'Ce groupe aura la permission de planificateur sur les nouvelles simulations.', 'Processed injects': 'Stimulis traités', + 'START': 'Commencement', + 'PREREQUISITE_CHECK': 'Commande de vérification des prérequis', + 'PREREQUISITE_EXECUTION': 'Commande d\'obtention des prérequis', + 'EXECUTION': 'Commande d\'attaque', + 'CLEANUP_EXECUTION': 'Commande de nettoyage', + 'COMPLETE': 'Dernière trace', 'Pending injects': 'Stimulis en attente', 'No team': 'Aucune équipe', 'No processed injects in this simulation.': @@ -823,6 +830,7 @@ const i18n = { // Assets 'Agents Privileges': 'Privilèges des agents', 'Endpoints': 'Endpoints', + 'Endpoint': 'Endpoint', 'Endpoint Information': 'Informations sur endpoint', 'asset': 'actif', 'Rules': 'Règles', @@ -863,7 +871,7 @@ const i18n = { 'Update the asset group': 'Modifier l\'asset group', 'Manage assets': 'Gérer les actifs', 'Add assets in this asset group': 'Ajouter des actifs dans ce groupe d\'actifs', - 'Remove from the asset group': 'Retirer de ce groupe d\'asset', + 'Remove from the asset group': 'Retirer de ce groupe d\'actifs', 'Targeted assets': 'Assets ciblés', 'Targeted asset groups': 'Groupes d\'assets ciblés', 'Modify target asset groups': 'Modifier des groupes d\'assets', @@ -884,6 +892,7 @@ const i18n = { + 'Il peut contenir des espaces ou des tirets ( – ) ou des parenthèses.\n', 'Instantiate a simulation': 'Créer une nouvelle simulation', 'Do you want to delete the asset group ?': 'Voulez-vous supprimer le groupe d\'actifs ?', + 'Do you want to remove the endpoint from the asset group?': 'Voulez-vous retirer cet endpoint du groupe d\'actifs ?', // -- FILTERS -- 'Add filter': 'Ajout d\'un filtre', 'Clear filters': 'Supprimer les filtres', @@ -1020,14 +1029,7 @@ const i18n = { 'Target': 'Cible', 'This atomic testing and its previous results will be deleted': 'Ce test atomique et ses résultats précédants seront supprimés', 'Traces': 'Traces', - 'Tracking Sent Date': 'Date d\'envoi', - 'Tracking Ack Date': 'Date de réception', - 'Tracking End Date': 'Date de fin', - 'Tracking Total Execution': 'Durée totale d\'exécution', 'Time': 'Temps', - 'Tracking Total Count': 'Nombre total d\'exécutions', - 'Tracking Total Error': 'Nombre total d\'échecs', - 'Tracking Total Success': 'Nombre total de succès', 'global-crisis': 'Crise mondiale', 'attack-scenario': 'Scénario d\'attaque', 'media-pressure': 'Pression médiatique', @@ -1400,7 +1402,7 @@ const i18n = { 'Inject test has been sent, you can view test logs details on {itsDedicatedPage}.': 'Le test du stimuli a été envoyé, vous pouvez visualiser les logs de test sur {itsDedicatedPage}.', 'its dedicated page': 'sa page dédiée', 'Test for inject {injectTitle} has been sent': 'Le test pour le stimuli {injectTitle} a été envoyé', - '{testNumber} test(s) sent': '{testNumber} test(s) envoyé(s)', + 'Test(s) sent': 'Test(s) envoyé(s)', 'Value that signifies that all teams are targeted. A regex can be used.': 'Valeur indiquant que l\'injecteur s\'applique à toutes les équipes. Il est possible d\'utiliser une expression régulière.', 'Fit view': 'Ajuster la vue', 'Increase time interval': 'Augmenter l\'intervalle de temps', @@ -1528,11 +1530,13 @@ const i18n = { 'You will not be able to change this setting later.': '你后续将无法更改此设定.', 'Search these results': '搜索这些结果', + 'Test(s) sent': '發送嘅測試', 'Stop': '停止', 'Name': '名称', 'Subtitle': '小标题', 'Notes': '笔记', 'Please note that if you change the "Reply to" address, the email interaction functionality in the platform will be disabled.': '请注意,如果您更改了\'回复 \'地址,平台中的电子邮件互动功能将被禁用。', + 'Execution Time': '执行时间', 'Start date': '开始日期', 'End date': '结束日期', 'To': '收件人', @@ -1724,7 +1728,7 @@ const i18n = { 'Add target teams in this inject': '在这个注入里添加目标团队', 'Modify target teams in this inject': - '在此注入中修改目标团队', + '在此注入中修改目标团队', 'Targeted teams': '目标团队', 'Test the inject': '测试注入', 'All teams': '所有团队', @@ -2256,6 +2260,7 @@ const i18n = { // Assets 'Agents Privileges': '代理权限', 'Endpoints': '终端', + 'Endpoint': '端点', 'Endpoint Information': '终端信息', 'Rules': '规则', 'Rule': '规则', @@ -2315,6 +2320,7 @@ const i18n = { 'phone_number_tooltip': '电话号码应以加号 ( + )开头\n' + '它可以包含空格、连字符( - ) 或括号.\n', 'Instantiate a simulation': '实例化模拟', + 'Do you want to remove the endpoint from the asset group?': '您想从资产组中删除端点吗?', // -- FILTERS -- 'Add filter': '添加过滤器', 'Clear filters': '清除过滤器', @@ -2444,14 +2450,7 @@ const i18n = { 'Target': '目标', 'This atomic testing and its previous results will be deleted': '此原子测试及其之前的结果将被删除', 'Traces': '跟踪', - 'Tracking Sent Date': '跟踪发送日期', - 'Tracking Ack Date': '跟踪响应日期', - 'Tracking End Date': '跟踪结束日期', - 'Tracking Total Execution': '跟踪总体执行情况', 'Time': '时间', - 'Tracking Total Count': '跟踪总计数', - 'Tracking Total Error': '跟踪总错误', - 'Tracking Total Success': '跟踪总成功', 'global-crisis': '全局危机', 'attack-scenario': '攻击场景', 'media-pressure': '媒体', @@ -2682,6 +2681,12 @@ const i18n = { 'Cleanup executor': '清理执行器', 'Cleanup command': '清理命令', 'Document': '文档', + 'START': '开始', + 'PREREQUISITE_CHECK': '检查先决条件命令', + 'PREREQUISITE_EXECUTION': '获取先决条件命令', + 'EXECUTION': '攻击命令', + 'CLEANUP_EXECUTION': '清理命令', + 'COMPLETE': '完全的', // Policies 'Platform login message': '平台登录信息', 'Platform consent message': '平台许可信息', @@ -2910,6 +2915,7 @@ const i18n = { + 'It may contain white spaces or hyphens ( – ) or parenthesis.\n', 'Exercise': 'Simulation', 'Scheduling_time': 'Time', + 'Do you want to remove the endpoint from the asset group?': 'Do you want to remove the endpoint from the asset group?', // -- FILTERS -- // Asset 'asset_tags': 'Tags', @@ -3012,7 +3018,7 @@ const i18n = { 'Do you want to test these {count} injects?', 'Inject test has been sent, you can view test logs details on {itsDedicatedPage}.': 'Inject test has been sent, you can view test logs details on {itsDedicatedPage}.', 'its dedicated page': 'its dedicated page', - '{testNumber} test(s) sent': '{testNumber} test(s) sent', + 'Test(s) sent': 'Test(s) sent', 'Test for {injectTitle} has been sent': 'Test for {injectTitle} has been sent', // Platform Banner 'IMAP service is not responding, your injectors may be impacted.': 'IMAP service is not responding, your injectors may be impacted.', @@ -3040,6 +3046,12 @@ const i18n = { 'Select a Tag': 'Select a Tag', 'asset rule': 'asset rule', 'Remove from the Asset Rule': 'Remove from the Asset Rule', + 'START': 'Start', + 'PREREQUISITE_CHECK': 'Check prerequisites command', + 'PREREQUISITE_EXECUTION': 'Get prerequisites command', + 'EXECUTION': 'Attack command', + 'CLEANUP_EXECUTION': 'Cleanup command', + 'COMPLETE': 'Final Trace', }, }, }; diff --git a/openbas-front/src/utils/api-types.d.ts b/openbas-front/src/utils/api-types.d.ts index 657044cc94..85726f8725 100644 --- a/openbas-front/src/utils/api-types.d.ts +++ b/openbas-front/src/utils/api-types.d.ts @@ -52,6 +52,27 @@ export interface AgentOutput { agent_privilege?: "admin" | "standard"; } +/** Represents the output result details of an agent execution */ +export interface AgentStatusOutput { + agent_executor_name?: string; + agent_executor_type?: string; + agent_id: string; + agent_name?: string; + /** + * Execution status of the agent + * @example "SUCCESS, ERROR, MAYBE_PREVENTED..." + */ + agent_status_name?: string; + /** List of agent execution traces */ + agent_traces?: ExecutionTracesOutput[]; + /** Endpoint ID */ + asset_id: string; + /** @format date-time */ + tracking_end_date?: string; + /** @format date-time */ + tracking_sent_date?: string; +} + export interface AiGenericTextInput { ai_content: string; ai_format?: string; @@ -368,7 +389,9 @@ export interface ChallengesReader { } export interface ChangePasswordInput { + /** The new password */ password: string; + /** The new password again to validate it's been typed well */ password_validation: string; } @@ -423,18 +446,22 @@ export interface ChannelUpdateLogoInput { } export interface CheckExerciseRulesInput { + /** List of tag that will be applied to the simulation */ new_tags?: string[]; } export interface CheckExerciseRulesOutput { + /** Are there rules that can be applied? */ rules_found: boolean; } export interface CheckScenarioRulesInput { + /** List of tag that will be applied to the scenario */ new_tags?: string[]; } export interface CheckScenarioRulesOutput { + /** Are there rules that can be applied? */ rules_found: boolean; } @@ -540,6 +567,7 @@ export interface Command { typeEnum?: "COMMAND" | "EXECUTABLE" | "FILE_DROP" | "DNS_RESOLUTION" | "NETWORK_TRAFFIC"; } +/** List of communications of this team */ export interface Communication { communication_ack?: boolean; communication_animation?: boolean; @@ -568,12 +596,19 @@ export interface Condition { } export interface CreateUserInput { + /** True if the user is admin */ user_admin?: boolean; + /** The email of the user */ user_email: string; + /** First name of the user */ user_firstname?: string; + /** Last name of the user */ user_lastname?: string; + /** Organization of the user */ user_organization?: string; + /** Password of the user as plain text */ user_plain_password?: string; + /** Tags of the user */ user_tags?: string[]; } @@ -801,6 +836,74 @@ export interface Executable { typeEnum?: "COMMAND" | "EXECUTABLE" | "FILE_DROP" | "DNS_RESOLUTION" | "NETWORK_TRAFFIC"; } +export interface ExecutionTraces { + agent?: string; + execution_action?: + | "START" + | "PREREQUISITE_CHECK" + | "PREREQUISITE_EXECUTION" + | "EXECUTION" + | "CLEANUP_EXECUTION" + | "COMPLETE"; + execution_context_identifiers?: string[]; + /** @format date-time */ + execution_created_at: string; + execution_message: string; + execution_status?: + | "SUCCESS" + | "ERROR" + | "MAYBE_PREVENTED" + | "COMMAND_NOT_FOUND" + | "COMMAND_CANNOT_BE_EXECUTED" + | "WARNING" + | "PARTIAL" + | "MAYBE_PARTIAL_PREVENTED" + | "ASSET_INACTIVE" + | "INFO"; + /** @format date-time */ + execution_time?: string; + execution_trace_id: string; + /** @format date-time */ + execution_updated_at: string; + injectStatus?: string; + injectTestStatus?: string; + listened?: boolean; +} + +/** Represents a single execution trace detail */ +export interface ExecutionTracesOutput { + /** + * The action that created this execution trace + * @example "START, PREREQUISITE_CHECK, PREREQUISITE_EXECUTION, EXECUTION, CLEANUP_EXECUTION or COMPLETE" + */ + execution_action: + | "START" + | "PREREQUISITE_CHECK" + | "PREREQUISITE_EXECUTION" + | "EXECUTION" + | "CLEANUP_EXECUTION" + | "COMPLETE"; + /** A detailed message describing the execution */ + execution_message: string; + /** + * The status of the execution trace + * @example "SUCCESS, ERROR, COMMAND_NOT_FOUND, WARNING, COMMAND_CANNOT_BE_EXECUTED.." + */ + execution_status: + | "SUCCESS" + | "ERROR" + | "MAYBE_PREVENTED" + | "COMMAND_NOT_FOUND" + | "COMMAND_CANNOT_BE_EXECUTED" + | "WARNING" + | "PARTIAL" + | "MAYBE_PARTIAL_PREVENTED" + | "ASSET_INACTIVE" + | "INFO"; + /** @format date-time */ + execution_time: string; +} + export interface Executor { /** @format date-time */ executor_created_at: string; @@ -890,6 +993,7 @@ export interface Exercise { exercise_users?: string[]; /** @format int64 */ exercise_users_number?: number; + exercise_variables?: string[]; listened?: boolean; } @@ -1338,14 +1442,23 @@ export interface InjectDocumentInput { } export interface InjectExecutionInput { - execution_context_identifiers?: string[]; + execution_action?: + | "prerequisite_check" + | "prerequisite_execution" + | "cleanup_execution" + | "command_execution" + | "dns_resolution" + | "file_execution" + | "file_drop" + | "complete"; /** @format int32 */ execution_duration?: number; - execution_message?: string; + execution_message: string; execution_status: string; } export interface InjectExpectation { + inject_expectation_agent?: string; inject_expectation_article?: string; inject_expectation_asset?: string; inject_expectation_asset_group?: string; @@ -1554,68 +1667,30 @@ export interface InjectStatus { | "SUCCESS" | "ERROR" | "MAYBE_PREVENTED" + | "PARTIAL" + | "MAYBE_PARTIAL_PREVENTED" | "DRAFT" | "QUEUING" | "EXECUTING" - | "PENDING" - | "PARTIAL" - | "MAYBE_PARTIAL_PREVENTED"; + | "PENDING"; status_payload_output?: StatusPayload; - status_traces?: InjectStatusExecution[]; - /** @format date-time */ - tracking_ack_date?: string; + status_traces?: ExecutionTraces[]; /** @format date-time */ tracking_end_date?: string; /** @format date-time */ tracking_sent_date?: string; - /** @format int32 */ - tracking_total_count?: number; - /** @format int32 */ - tracking_total_error?: number; - /** @format int64 */ - tracking_total_execution_time?: number; - /** @format int32 */ - tracking_total_success?: number; -} - -export interface InjectStatusExecution { - execution_category?: string; - execution_context_identifiers?: string[]; - /** @format int32 */ - execution_duration?: number; - execution_message?: string; - execution_status?: - | "SUCCESS" - | "ERROR" - | "MAYBE_PREVENTED" - | "INFO" - | "COMMAND_NOT_FOUND" - | "COMMAND_CANNOT_BE_EXECUTED" - | "WARNING" - | "ASSET_INACTIVE"; - /** @format date-time */ - execution_time?: string; } /** status */ export interface InjectStatusOutput { status_id: string; + status_main_traces?: ExecutionTracesOutput[]; status_name?: string; - status_traces?: InjectStatusExecution[]; - /** @format date-time */ - tracking_ack_date?: string; + status_traces_by_agent?: AgentStatusOutput[]; /** @format date-time */ tracking_end_date?: string; /** @format date-time */ tracking_sent_date?: string; - /** @format int32 */ - tracking_total_count?: number; - /** @format int32 */ - tracking_total_error?: number; - /** @format int64 */ - tracking_total_execution_time?: number; - /** @format int32 */ - tracking_total_success?: number; } /** Status */ @@ -1633,49 +1708,25 @@ export interface InjectTargetWithResult { id: string; name?: string; platformType?: "Linux" | "Windows" | "MacOS" | "Container" | "Service" | "Generic" | "Internal" | "Unknown"; - targetType?: "ASSETS" | "ASSETS_GROUPS" | "PLAYER" | "TEAMS"; + targetType?: "AGENT" | "ASSETS" | "ASSETS_GROUPS" | "PLAYER" | "TEAMS"; } export interface InjectTeamsInput { inject_teams?: string[]; } -export interface InjectTestStatus { - inject_id?: string; - /** @format date-time */ - inject_test_status_created_at?: string; - /** @format date-time */ - inject_test_status_updated_at?: string; - inject_title?: string; +export interface InjectTestStatusOutput { + inject_id: string; + inject_title: string; inject_type?: string; - injector_contract?: InjectorContract; - listened?: boolean; - status_id?: string; - status_name: - | "SUCCESS" - | "ERROR" - | "MAYBE_PREVENTED" - | "DRAFT" - | "QUEUING" - | "EXECUTING" - | "PENDING" - | "PARTIAL" - | "MAYBE_PARTIAL_PREVENTED"; - status_traces?: InjectStatusExecution[]; - /** @format date-time */ - tracking_ack_date?: string; + status_id: string; + status_main_traces?: ExecutionTracesOutput[]; + status_name?: string; + status_traces_by_agent?: AgentStatusOutput[]; /** @format date-time */ tracking_end_date?: string; /** @format date-time */ tracking_sent_date?: string; - /** @format int32 */ - tracking_total_count?: number; - /** @format int32 */ - tracking_total_error?: number; - /** @format int64 */ - tracking_total_execution_time?: number; - /** @format int32 */ - tracking_total_success?: number; } export interface InjectUpdateActivationInput { @@ -2104,7 +2155,9 @@ export interface LogCreateInput { } export interface LoginUserInput { + /** The identifier of the user */ login: string; + /** The password of the user */ password: string; } @@ -2181,6 +2234,7 @@ export interface NetworkTraffic { typeEnum?: "COMMAND" | "EXECUTABLE" | "FILE_DROP" | "DNS_RESOLUTION" | "NETWORK_TRAFFIC"; } +/** List of Saml2 providers */ export interface OAuthProvider { provider_login?: string; provider_name?: string; @@ -2381,8 +2435,8 @@ export interface PageInjectResultOutput { totalPages?: number; } -export interface PageInjectTestStatus { - content?: InjectTestStatus[]; +export interface PageInjectTestStatusOutput { + content?: InjectTestStatusOutput[]; empty?: boolean; first?: boolean; last?: boolean; @@ -2782,51 +2836,103 @@ export interface PayloadsDeprecateInput { } export interface PlatformSettings { + /** True if Saml2 is enabled */ auth_saml2_enable?: boolean; + /** List of Saml2 providers */ platform_saml2_providers?: OAuthProvider[]; + /** True if local authentication is enabled */ auth_local_enable?: boolean; + /** True if OpenID is enabled */ auth_openid_enable?: boolean; + /** Sender mail to use by default for injects */ default_mailer?: string; + /** Reply to mail to use by default for injects */ default_reply_to?: string; + /** List of enabled dev features */ enabled_dev_features?: "_RESERVED"[]; + /** True if the Caldera Executor is enabled */ executor_caldera_enable?: boolean; + /** Url of the Caldera Executor */ executor_caldera_public_url?: string; + /** True if the Tanium Executor is enabled */ executor_tanium_enable?: boolean; - /** @format int64 */ + /** + * Time to wait before article time has expired + * @format int64 + */ expectation_article_expiration_time: number; - /** @format int64 */ + /** + * Time to wait before challenge time has expired + * @format int64 + */ expectation_challenge_expiration_time: number; - /** @format int64 */ + /** + * Time to wait before detection time has expired + * @format int64 + */ expectation_detection_expiration_time: number; - /** @format int32 */ + /** + * Default score for manuel expectation + * @format int32 + */ expectation_manual_default_score_value: number; - /** @format int64 */ + /** + * Time to wait before manual expectation time has expired + * @format int64 + */ expectation_manual_expiration_time: number; - /** @format int64 */ + /** + * Time to wait before prevention time has expired + * @format int64 + */ expectation_prevention_expiration_time: number; + /** Current version of Java */ java_version?: string; + /** URL of the server containing the map tile with dark theme */ map_tile_server_dark?: string; + /** URL of the server containing the map tile with light theme */ map_tile_server_light?: string; + /** Agent URL of the platform */ platform_agent_url?: string; + /** True if AI is enabled for the platform */ platform_ai_enabled?: boolean; + /** True if we have an AI token */ platform_ai_has_token?: boolean; + /** Chosen model of AI */ platform_ai_model?: string; + /** Type of AI (mistralai or openai) */ platform_ai_type?: string; + /** Map of the messages to display on the screen by their level (the level available are DEBUG, INFO, WARN, ERROR, FATAL) */ platform_banner_by_level?: Record; + /** Base URL of the platform */ platform_base_url?: string; + /** Definition of the dark theme */ platform_dark_theme?: ThemeInput; + /** 'true' if the platform has Enterprise Edition activated */ platform_enterprise_edition?: string; + /** Language of the platform */ platform_lang?: string; + /** Definition of the dark theme */ platform_light_theme?: ThemeInput; + /** Name of the platform */ platform_name?: string; + /** List of OpenID providers */ platform_openid_providers?: OAuthProvider[]; + /** Policies of the platform */ platform_policies?: PolicyInput; + /** Theme of the platform */ platform_theme?: string; + /** Current version of the platform */ platform_version?: string; + /** 'true' if the platform has the whitemark activated */ platform_whitemark?: string; + /** Current version of the PostgreSQL */ postgre_version?: string; + /** Current version of RabbitMQ */ rabbitmq_version?: string; + /** True if connection with OpenCTI is enabled */ xtm_opencti_enable?: boolean; + /** Url of OpenCTI */ xtm_opencti_url?: string; } @@ -2875,9 +2981,13 @@ export interface PlayerOutput { user_tags?: string[]; } +/** Policies of the platform */ export interface PolicyInput { + /** Consent confirmation message */ platform_consent_confirm_text?: string; + /** Consent message to show at login */ platform_consent_message?: string; + /** Message to show at login */ platform_login_message?: string; } @@ -3254,16 +3364,21 @@ export interface SecurityPlatformUpsertInput { } export interface SettingsEnterpriseEditionUpdateInput { + /** 'true' if enterprise edition is activated */ platform_enterprise_edition: string; } export interface SettingsPlatformWhitemarkUpdateInput { + /** The whitemark of the platform */ platform_whitemark: string; } export interface SettingsUpdateInput { + /** Language of the platform */ platform_lang: string; + /** Name of the platform */ platform_name: string; + /** Theme of the platform */ platform_theme: string; } @@ -3294,8 +3409,8 @@ export interface StatisticElement { export interface StatusPayload { dns_resolution_hostname?: string; - executable_file?: Document; - file_drop_file?: Document; + executable_file?: StatusPayloadDocument; + file_drop_file?: StatusPayloadDocument; network_traffic_ip_dst: string; network_traffic_ip_src: string; /** @format int32 */ @@ -3306,15 +3421,23 @@ export interface StatusPayload { payload_arguments?: PayloadArgument[]; payload_cleanup_executor?: string; payload_command_blocks?: PayloadCommandBlock[]; + payload_description?: string; payload_external_id?: string; + payload_name?: string; payload_prerequisites?: PayloadPrerequisite[]; + payload_type?: string; +} + +export interface StatusPayloadDocument { + document_id: string; + document_name: string; } export interface StatusPayloadOutput { dns_resolution_hostname?: string; executable_arch?: "x86_64" | "arm64" | "ALL_ARCHITECTURES"; - executable_file?: Document; - file_drop_file?: Document; + executable_file?: StatusPayloadDocument; + file_drop_file?: StatusPayloadDocument; network_traffic_ip_dst: string; network_traffic_ip_src: string; /** @format int32 */ @@ -3340,129 +3463,208 @@ export interface StatusPayloadOutput { export interface Tag { listened?: boolean; + /** Color of the tag */ tag_color?: string; + /** ID of the tag */ tag_id: string; + /** Name of the tag */ tag_name: string; } export interface TagCreateInput { + /** Color of the tag */ tag_color: string; + /** Name of the tag */ tag_name: string; } export interface TagRuleInput { + /** Asset groups of the tag rule */ asset_groups?: string[]; + /** Name of the tag */ tag_name: string; } export interface TagRuleOutput { + /** Asset groups of the tag rule */ asset_groups?: Record; + /** Name of the tag associated with the tag rule */ tag_name: string; + /** ID of the tag rule */ tag_rule_id: string; } export interface TagUpdateInput { + /** Color of the tag */ tag_color: string; + /** Name of the tag */ tag_name: string; } export interface TargetSimple { target_id: string; target_name?: string; - target_type?: "ASSETS" | "ASSETS_GROUPS" | "PLAYER" | "TEAMS"; + target_type?: "AGENT" | "ASSETS" | "ASSETS_GROUPS" | "PLAYER" | "TEAMS"; } export interface Team { listened?: boolean; + /** List of communications of this team */ team_communications?: Communication[]; + /** True if the team is contextual (exists only in the scenario/simulation it is linked to) */ team_contextual?: boolean; - /** @format date-time */ + /** + * Creation date of the team + * @format date-time + */ team_created_at: string; + /** Description of the team */ team_description?: string; team_exercise_injects?: string[]; - /** @format int64 */ + /** + * Number of injects of all simulations of the team + * @format int64 + */ team_exercise_injects_number?: number; team_exercises?: string[]; team_exercises_users?: string[]; + /** ID of the team */ team_id: string; team_inject_expectations?: string[]; - /** @format int64 */ + /** + * Number of expectations linked to this team + * @format int64 + */ team_injects_expectations_number?: number; - /** @format double */ + /** + * Total expected score of expectations linked to this team + * @format double + */ team_injects_expectations_total_expected_score: number; + /** Total expected score of expectations by simulation linked to this team */ team_injects_expectations_total_expected_score_by_exercise: Record; - /** @format double */ + /** + * Total score of expectations linked to this team + * @format double + */ team_injects_expectations_total_score: number; + /** Total score of expectations by simulation linked to this team */ team_injects_expectations_total_score_by_exercise: Record; + /** Name of the team */ team_name: string; + /** Organization of the team */ team_organization?: string; team_scenario_injects?: string[]; - /** @format int64 */ + /** + * Number of injects of all scenarios of the team + * @format int64 + */ team_scenario_injects_number?: number; team_scenarios?: string[]; team_tags?: string[]; - /** @format date-time */ + /** + * Update date of the team + * @format date-time + */ team_updated_at: string; team_users?: string[]; - /** @format int64 */ + /** + * Number of users of the team + * @format int64 + */ team_users_number?: number; } export interface TeamCreateInput { + /** True if the team is contextual (exists only in the scenario/simulation it is linked to) */ team_contextual?: boolean; + /** Description of the team */ team_description?: string; + /** Id of the simulations linked to the team */ team_exercises?: string[]; + /** Name of the team */ team_name: string; + /** ID of the organization of the team */ team_organization?: string; + /** Id of the scenarios linked to the team */ team_scenarios?: string[]; + /** IDs of the tags of the team */ team_tags?: string[]; } export interface TeamOutput { + /** True if the team is contextual (exists only in the scenario/simulation it is linked to) */ team_contextual?: boolean; + /** Description of the team */ team_description?: string; /** - * exercise ids + * Simulation ids linked to this team * @uniqueItems true */ team_exercises: string[]; + /** ID of the team */ team_id: string; + /** Name of the team */ team_name: string; + /** Organization of the team */ team_organization?: string; /** - * scenario ids + * Scenario ids linked to this team * @uniqueItems true */ team_scenarios: string[]; - /** @uniqueItems true */ + /** + * List of tags of the team + * @uniqueItems true + */ team_tags?: string[]; - /** @format date-time */ + /** + * Update date of the team + * @format date-time + */ team_updated_at: string; /** - * user ids + * User ids of the team * @uniqueItems true */ team_users?: string[]; - /** @format int64 */ + /** + * Number of users of the team + * @format int64 + */ team_users_number?: number; } export interface TeamUpdateInput { + /** Description of the team */ team_description?: string; + /** Name of the team */ team_name: string; + /** ID of the organization of the team */ team_organization?: string; + /** IDs of the tags of the team */ team_tags?: string[]; } +/** Definition of the dark theme */ export interface ThemeInput { + /** Accent color of the theme */ accent_color?: string; + /** Background color of the theme */ background_color?: string; + /** Url of the login logo */ logo_login_url?: string; + /** Url of the logo */ logo_url?: string; + /** 'true' if the logo needs to be collapsed */ logo_url_collapsed?: string; + /** Navigation color of the theme */ navigation_color?: string; + /** Paper color of the theme */ paper_color?: string; + /** Primary color of the theme */ primary_color?: string; + /** Secondary color of the theme */ secondary_color?: string; } @@ -3535,82 +3737,146 @@ export interface UpdateUserInfoInput { } export interface UpdateUserInput { - /** @pattern ^\+[\d\s\-.()]+$ */ + /** + * Secondary phone of the user + * @pattern ^\+[\d\s\-.()]+$ + */ user_phone2?: string; + /** True if the user is admin */ user_admin?: boolean; + /** The email of the user */ user_email?: string; + /** First name of the user */ user_firstname?: string; + /** Last name of the user */ user_lastname?: string; + /** Organization of the user */ user_organization?: string; + /** PGP key of the user */ user_pgp_key?: string; - /** @pattern ^\+[\d\s\-.()]+$ */ + /** + * Phone of the user + * @pattern ^\+[\d\s\-.()]+$ + */ user_phone?: string; + /** Tags of the user */ user_tags?: string[]; } export interface UpdateUsersTeamInput { + /** The list of users the team contains */ team_users?: string[]; } export interface User { + /** Secondary phone number of the user */ user_phone2?: string; listened?: boolean; + /** True if the user is admin */ user_admin?: boolean; + /** City of the user */ user_city?: string; user_communications?: string[]; + /** Country of the user */ user_country?: string; - /** @format date-time */ + /** + * Creation date of the user + * @format date-time + */ user_created_at: string; + /** Email of the user */ user_email: string; + /** First name of the user */ user_firstname?: string; + /** Gravatar of the user */ user_gravatar?: string; user_groups?: string[]; + /** User ID */ user_id: string; + /** True if the user is external */ user_is_external?: boolean; + /** True if the user is manager */ user_is_manager?: boolean; + /** True if the user is observer */ user_is_observer?: boolean; + /** True if the user is only a player */ user_is_only_player?: boolean; + /** True if the user is planner */ user_is_planner?: boolean; + /** True if the user is player */ user_is_player?: boolean; + /** Language of the user */ user_lang?: string; - /** @format date-time */ + /** + * Last communication date of the user + * @format date-time + */ user_last_comcheck?: string; + /** Last name of the user */ user_lastname?: string; + /** Organization ID of the user */ user_organization?: string; + /** PGP key of the user */ user_pgp_key?: string; + /** Phone number of the user */ user_phone?: string; - /** @format int32 */ + /** + * Status of the user + * @format int32 + */ user_status: number; user_tags?: string[]; user_teams?: string[]; + /** Theme of the user */ user_theme?: string; - /** @format date-time */ + /** + * Update date of the user + * @format date-time + */ user_updated_at: string; } export interface UserOutput { + /** True if the user is admin */ user_admin?: boolean; + /** Email of the user */ user_email: string; + /** First name of the user */ user_firstname?: string; + /** User ID */ user_id: string; + /** Last name of the user */ user_lastname?: string; + /** Organization of the user */ user_organization_name?: string; - /** @uniqueItems true */ + /** + * Tags of the user + * @uniqueItems true + */ user_tags?: string[]; } +/** Map of errors by input */ export interface ValidationContent { + /** A list of errors */ errors?: string[]; } +/** Errors raised */ export interface ValidationError { + /** Map of errors by input */ children?: Record; } export interface ValidationErrorBag { - /** @format int32 */ + /** + * Return code + * @format int32 + */ code?: number; + /** Errors raised */ errors?: ValidationError; + /** Return message */ message?: string; } @@ -3638,7 +3904,10 @@ export interface VariableInput { } export interface ViolationErrorBag { + /** The error */ error?: string; + /** The message of the error */ message?: string; + /** The type of error */ type?: string; } diff --git a/openbas-front/src/utils/inject/injectUtils.ts b/openbas-front/src/utils/inject/injectUtils.ts index d8f03bc5c5..b32c834a87 100644 --- a/openbas-front/src/utils/inject/injectUtils.ts +++ b/openbas-front/src/utils/inject/injectUtils.ts @@ -1,7 +1,7 @@ import type { InjectResultOverviewOutput } from '../api-types'; const isInjectWithPayloadInfo = (injectResultOverviewOutput: InjectResultOverviewOutput) => { - return injectResultOverviewOutput.inject_type !== undefined && !['openbas_email', 'openbas_ovh_sms', 'openbas_mastodon', 'openbas_http_query'].includes(injectResultOverviewOutput.inject_type); + return injectResultOverviewOutput.inject_type !== undefined && !['openbas_email', 'openbas_channel', 'openbas_challenge', 'openbas_ovh_sms', 'openbas_mastodon', 'openbas_http_query'].includes(injectResultOverviewOutput.inject_type); }; export default isInjectWithPayloadInfo; diff --git a/openbas-front/yarn.lock b/openbas-front/yarn.lock index 4ee8f032c9..8eb4874564 100644 --- a/openbas-front/yarn.lock +++ b/openbas-front/yarn.lock @@ -15,17 +15,20 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/code-frame@npm:7.25.9" +"@asamuzakjp/css-color@npm:^2.8.2": + version: 2.8.3 + resolution: "@asamuzakjp/css-color@npm:2.8.3" dependencies: - "@babel/highlight": "npm:^7.25.9" - picocolors: "npm:^1.0.0" - checksum: 10c0/88562eba0eeb5960b7004e108790aa00183d90cbbe70ce10dad01c2c48141d2ef54d6dcd0c678cc1e456de770ffeb68e28559f4d222c01a110c79aea8733074b + "@csstools/css-calc": "npm:^2.1.1" + "@csstools/css-color-parser": "npm:^3.0.7" + "@csstools/css-parser-algorithms": "npm:^3.0.4" + "@csstools/css-tokenizer": "npm:^3.0.3" + lru-cache: "npm:^10.4.3" + checksum: 10c0/e108c92ee5de6d8510c9aaca8375c0aeab730dc9b6d4bd287aea2a0379cfbaa09f0814dcacb3e2ddc5c79d7deedf3f82ec8d1ce0effd4a8fac8415b1fe553798 languageName: node linkType: hard -"@babel/code-frame@npm:^7.26.0": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.2": version: 7.26.2 resolution: "@babel/code-frame@npm:7.26.2" dependencies: @@ -36,71 +39,59 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/compat-data@npm:7.25.9" - checksum: 10c0/8d9fc2074311ce61aaf5bccf740a808644d19d4859caf5fa46d8a7186a1ee0b0d8cbbc23f9371f8b397e84a885bdeab58d5f22d6799ddde55973252aac351a27 +"@babel/compat-data@npm:^7.26.5": + version: 7.26.5 + resolution: "@babel/compat-data@npm:7.26.5" + checksum: 10c0/9d2b41f0948c3dfc5de44d9f789d2208c2ea1fd7eb896dfbb297fe955e696728d6f363c600cd211e7f58ccbc2d834fe516bb1e4cf883bbabed8a32b038afc1a0 languageName: node linkType: hard "@babel/core@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/core@npm:7.26.0" + version: 7.26.7 + resolution: "@babel/core@npm:7.26.7" dependencies: "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.26.0" - "@babel/generator": "npm:^7.26.0" - "@babel/helper-compilation-targets": "npm:^7.25.9" + "@babel/code-frame": "npm:^7.26.2" + "@babel/generator": "npm:^7.26.5" + "@babel/helper-compilation-targets": "npm:^7.26.5" "@babel/helper-module-transforms": "npm:^7.26.0" - "@babel/helpers": "npm:^7.26.0" - "@babel/parser": "npm:^7.26.0" + "@babel/helpers": "npm:^7.26.7" + "@babel/parser": "npm:^7.26.7" "@babel/template": "npm:^7.25.9" - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.26.0" + "@babel/traverse": "npm:^7.26.7" + "@babel/types": "npm:^7.26.7" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 10c0/91de73a7ff5c4049fbc747930aa039300e4d2670c2a91f5aa622f1b4868600fc89b01b6278385fbcd46f9574186fa3d9b376a9e7538e50f8d118ec13cfbcb63e - languageName: node - linkType: hard - -"@babel/generator@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/generator@npm:7.25.9" - dependencies: - "@babel/types": "npm:^7.25.9" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^3.0.2" - checksum: 10c0/fca49a1440ac550bb835a73c0e8314849cd493a468a5431ca7f9dbb3d3443e3a1a6dcba2426752e8a97cc2feed4a3b7a0c639e1c45871c4a9dd0c994f08dd25a + checksum: 10c0/fbd2cd9fc23280bdcaca556e558f715c0a42d940b9913c52582e8e3d24e391d269cb8a9cd6589172593983569021c379e28bba6b19ea2ee08674f6068c210a9d languageName: node linkType: hard -"@babel/generator@npm:^7.26.0": - version: 7.26.2 - resolution: "@babel/generator@npm:7.26.2" +"@babel/generator@npm:^7.26.5": + version: 7.26.5 + resolution: "@babel/generator@npm:7.26.5" dependencies: - "@babel/parser": "npm:^7.26.2" - "@babel/types": "npm:^7.26.0" + "@babel/parser": "npm:^7.26.5" + "@babel/types": "npm:^7.26.5" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10c0/167ebce8977142f5012fad6bd91da51ac52bcd752f2261a54b7ab605d928aebe57e21636cdd2a9c7757e552652c68d9fcb5d40b06fcb66e02d9ee7526e118a5c + checksum: 10c0/3be79e0aa03f38858a465d12ee2e468320b9122dc44fc85984713e32f16f4d77ce34a16a1a9505972782590e0b8d847b6f373621f9c6fafa1906d90f31416cb0 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-compilation-targets@npm:7.25.9" +"@babel/helper-compilation-targets@npm:^7.26.5": + version: 7.26.5 + resolution: "@babel/helper-compilation-targets@npm:7.26.5" dependencies: - "@babel/compat-data": "npm:^7.25.9" + "@babel/compat-data": "npm:^7.26.5" "@babel/helper-validator-option": "npm:^7.25.9" browserslist: "npm:^4.24.0" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 10c0/a6b26a1e4222e69ef8e62ee19374308f060b007828bc11c65025ecc9e814aba21ff2175d6d3f8bf53c863edd728ee8f94ba7870f8f90a37d39552ad9933a8aaa + checksum: 10c0/9da5c77e5722f1a2fcb3e893049a01d414124522bbf51323bb1a0c9dcd326f15279836450fc36f83c9e8a846f3c40e88be032ed939c5a9840922bed6073edfb4 languageName: node linkType: hard @@ -128,9 +119,9 @@ __metadata: linkType: hard "@babel/helper-plugin-utils@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-plugin-utils@npm:7.25.9" - checksum: 10c0/483066a1ba36ff16c0116cd24f93de05de746a603a777cd695ac7a1b034928a65a4ecb35f255761ca56626435d7abdb73219eba196f9aa83b6c3c3169325599d + version: 7.26.5 + resolution: "@babel/helper-plugin-utils@npm:7.26.5" + checksum: 10c0/cdaba71d4b891aa6a8dfbe5bac2f94effb13e5fa4c2c487667fdbaa04eae059b78b28d85a885071f45f7205aeb56d16759e1bed9c118b94b16e4720ef1ab0f65 languageName: node linkType: hard @@ -155,47 +146,24 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/helpers@npm:7.26.0" +"@babel/helpers@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/helpers@npm:7.26.7" dependencies: "@babel/template": "npm:^7.25.9" - "@babel/types": "npm:^7.26.0" - checksum: 10c0/343333cced6946fe46617690a1d0789346960910225ce359021a88a60a65bc0d791f0c5d240c0ed46cf8cc63b5fd7df52734ff14e43b9c32feae2b61b1647097 - languageName: node - linkType: hard - -"@babel/highlight@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/highlight@npm:7.25.9" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.25.9" - chalk: "npm:^2.4.2" - js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.0.0" - checksum: 10c0/ae0ed93c151b85a07df42936117fa593ce91563a22dfc8944a90ae7088c9679645c33e00dcd20b081c1979665d65f986241172dae1fc9e5922692fc3ff685a49 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/parser@npm:7.25.9" - dependencies: - "@babel/types": "npm:^7.25.9" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/143faff8a72331be5ed94080e0f4645cbeea814fb488cd9210154083735f67cb66fde32f6a4a80efd6c4cdf12c6f8b50995a465846093c7f65c5da8d7829627c + "@babel/types": "npm:^7.26.7" + checksum: 10c0/37fec398e53a2dbbf24bc2a025c4d571b2556cef18d8116d05d04b153f13ef659cdfbaab96c8eed875e629d39bdf9b3ea5d099ccf80544537de224e2d94f9b11 languageName: node linkType: hard -"@babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2": - version: 7.26.2 - resolution: "@babel/parser@npm:7.26.2" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.5, @babel/parser@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/parser@npm:7.26.7" dependencies: - "@babel/types": "npm:^7.26.0" + "@babel/types": "npm:^7.26.7" bin: parser: ./bin/babel-parser.js - checksum: 10c0/751a743087b3a9172a7599f1421830d44c38f065ef781588d2bfb1c98f9b461719a226feb13c868d7a284783eee120c88ea522593118f2668f46ebfb1105c4d7 + checksum: 10c0/dcb08a4f2878ece33caffefe43b71488d753324bae7ca58d64bca3bc4af34dcfa1b58abdf9972516d76af760fceb25bb9294ca33461d56b31c5059ccfe32001f languageName: node linkType: hard @@ -221,21 +189,12 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.7": - version: 7.25.9 - resolution: "@babel/runtime@npm:7.25.9" - dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/d1727a47eab67b8a742cbf1ef336a20c3d906fe65d6316d073c72479125addfa4358c44dd7b95d114f241b93409b134fad7cea43f3bf8ca7e2ef344177eb72d8 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/runtime@npm:7.26.0" +"@babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.25.7, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": + version: 7.26.7 + resolution: "@babel/runtime@npm:7.26.7" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: 10c0/12c01357e0345f89f4f7e8c0e81921f2a3e3e101f06e8eaa18a382b517376520cd2fa8c237726eb094dab25532855df28a7baaf1c26342b52782f6936b07c287 + checksum: 10c0/60199c049f90e5e41c687687430052a370aca60bac7859ff4ee761c5c1739b8ba1604d391d01588c22dc0e93828cbadb8ada742578ad1b1df240746bce98729a languageName: node linkType: hard @@ -250,38 +209,28 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/traverse@npm:7.25.9" +"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/traverse@npm:7.26.7" dependencies: - "@babel/code-frame": "npm:^7.25.9" - "@babel/generator": "npm:^7.25.9" - "@babel/parser": "npm:^7.25.9" + "@babel/code-frame": "npm:^7.26.2" + "@babel/generator": "npm:^7.26.5" + "@babel/parser": "npm:^7.26.7" "@babel/template": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" + "@babel/types": "npm:^7.26.7" debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: 10c0/e90be586a714da4adb80e6cb6a3c5cfcaa9b28148abdafb065e34cc109676fc3db22cf98cd2b2fff66ffb9b50c0ef882cab0f466b6844be0f6c637b82719bba1 - languageName: node - linkType: hard - -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/types@npm:7.25.9" - dependencies: - "@babel/helper-string-parser": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - checksum: 10c0/33890d08bcb06b26a3a60e4c6c996cbdf2b8d8a3c212664de659c2775f80b002c5f2bceedaa309c384ff5e99bd579794fe6a7e41de07df70246f43c55016d349 + checksum: 10c0/b23a36ce40d2e4970741431c45d4f92e3f4c2895c0a421456516b2729bd9e17278846e01ee3d9039b0adf5fc5a071768061c17fcad040e74a5c3e39517449d5b languageName: node linkType: hard -"@babel/types@npm:^7.26.0": - version: 7.26.0 - resolution: "@babel/types@npm:7.26.0" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.5, @babel/types@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/types@npm:7.26.7" dependencies: "@babel/helper-string-parser": "npm:^7.25.9" "@babel/helper-validator-identifier": "npm:^7.25.9" - checksum: 10c0/b694f41ad1597127e16024d766c33a641508aad037abd08d0d1f73af753e1119fa03b4a107d04b5f92cc19c095a594660547ae9bead1db2299212d644b0a5cb8 + checksum: 10c0/7810a2bca97b13c253f07a0863a628d33dbe76ee3c163367f24be93bfaf4c8c0a325f73208abaaa050a6b36059efc2950c2e4b71fb109c0f07fa62221d8473d4 languageName: node linkType: hard @@ -1063,6 +1012,52 @@ __metadata: languageName: node linkType: hard +"@csstools/color-helpers@npm:^5.0.1": + version: 5.0.1 + resolution: "@csstools/color-helpers@npm:5.0.1" + checksum: 10c0/77fa3b7236eaa3f36dea24708ac0d5e53168903624ac5aed54615752a0730cd20773fda50e742ce868012eca8c000cc39688e05869e79f34714230ab6968d1e6 + languageName: node + linkType: hard + +"@csstools/css-calc@npm:^2.1.1": + version: 2.1.1 + resolution: "@csstools/css-calc@npm:2.1.1" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.4 + "@csstools/css-tokenizer": ^3.0.3 + checksum: 10c0/857c8dac40eb6ba8810408dad141bbcad060b28bce69dfd3bcf095a060fcaa23d5c4dbf52be88fcb57e12ce32c666e855dc68de1d8020851f6b432e3f9b29950 + languageName: node + linkType: hard + +"@csstools/css-color-parser@npm:^3.0.7": + version: 3.0.7 + resolution: "@csstools/css-color-parser@npm:3.0.7" + dependencies: + "@csstools/color-helpers": "npm:^5.0.1" + "@csstools/css-calc": "npm:^2.1.1" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.4 + "@csstools/css-tokenizer": ^3.0.3 + checksum: 10c0/b81780e6c50f0b0605776bd39bbd6203780231a561601853a9835cc70788560e7a281d0fbfe47ebe8affcb07dd64b0b1dcd4b67552520cfbe0e5088df158f12c + languageName: node + linkType: hard + +"@csstools/css-parser-algorithms@npm:^3.0.4": + version: 3.0.4 + resolution: "@csstools/css-parser-algorithms@npm:3.0.4" + peerDependencies: + "@csstools/css-tokenizer": ^3.0.3 + checksum: 10c0/d411f07765e14eede17bccc6bd4f90ff303694df09aabfede3fd104b2dfacfd4fe3697cd25ddad14684c850328f3f9420ebfa9f78380892492974db24ae47dbd + languageName: node + linkType: hard + +"@csstools/css-tokenizer@npm:^3.0.3": + version: 3.0.3 + resolution: "@csstools/css-tokenizer@npm:3.0.3" + checksum: 10c0/c31bf410e1244b942e71798e37c54639d040cb59e0121b21712b40015fced2b0fb1ffe588434c5f8923c9cd0017cfc1c1c8f3921abc94c96edf471aac2eba5e5 + languageName: node + linkType: hard + "@dagrejs/dagre@npm:1.1.4": version: 1.1.4 resolution: "@dagrejs/dagre@npm:1.1.4" @@ -1126,7 +1121,7 @@ __metadata: languageName: node linkType: hard -"@emotion/cache@npm:^11.13.5, @emotion/cache@npm:^11.14.0": +"@emotion/cache@npm:*, @emotion/cache@npm:^11.13.5, @emotion/cache@npm:^11.14.0": version: 11.14.0 resolution: "@emotion/cache@npm:11.14.0" dependencies: @@ -1183,7 +1178,7 @@ __metadata: languageName: node linkType: hard -"@emotion/serialize@npm:^1.3.3": +"@emotion/serialize@npm:*, @emotion/serialize@npm:^1.3.3": version: 1.3.3 resolution: "@emotion/serialize@npm:1.3.3" dependencies: @@ -1239,7 +1234,7 @@ __metadata: languageName: node linkType: hard -"@emotion/utils@npm:^1.4.2": +"@emotion/utils@npm:*, @emotion/utils@npm:^1.4.2": version: 1.4.2 resolution: "@emotion/utils@npm:1.4.2" checksum: 10c0/7d0010bf60a2a8c1a033b6431469de4c80e47aeb8fd856a17c1d1f76bbc3a03161a34aeaa78803566e29681ca551e7bf9994b68e9c5f5c796159923e44f78d9a @@ -1267,6 +1262,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/aix-ppc64@npm:0.25.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" @@ -1281,6 +1283,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/android-arm64@npm:0.25.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" @@ -1295,6 +1304,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/android-arm@npm:0.25.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" @@ -1309,6 +1325,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/android-x64@npm:0.25.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" @@ -1323,6 +1346,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/darwin-arm64@npm:0.25.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" @@ -1337,6 +1367,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/darwin-x64@npm:0.25.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" @@ -1351,6 +1388,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/freebsd-arm64@npm:0.25.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" @@ -1365,6 +1409,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/freebsd-x64@npm:0.25.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" @@ -1379,6 +1430,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-arm64@npm:0.25.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" @@ -1393,6 +1451,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-arm@npm:0.25.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" @@ -1407,6 +1472,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-ia32@npm:0.25.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" @@ -1421,6 +1493,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-loong64@npm:0.25.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" @@ -1435,6 +1514,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-mips64el@npm:0.25.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" @@ -1449,6 +1535,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-ppc64@npm:0.25.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" @@ -1463,6 +1556,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-riscv64@npm:0.25.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" @@ -1477,6 +1577,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-s390x@npm:0.25.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" @@ -1491,6 +1598,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/linux-x64@npm:0.25.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-arm64@npm:0.24.2": version: 0.24.2 resolution: "@esbuild/netbsd-arm64@npm:0.24.2" @@ -1498,6 +1612,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/netbsd-arm64@npm:0.25.0" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" @@ -1512,6 +1633,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/netbsd-x64@npm:0.25.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-arm64@npm:0.24.2": version: 0.24.2 resolution: "@esbuild/openbsd-arm64@npm:0.24.2" @@ -1519,6 +1647,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/openbsd-arm64@npm:0.25.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" @@ -1533,6 +1668,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/openbsd-x64@npm:0.25.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" @@ -1547,6 +1689,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/sunos-x64@npm:0.25.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" @@ -1561,6 +1710,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/win32-arm64@npm:0.25.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" @@ -1575,6 +1731,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/win32-ia32@npm:0.25.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" @@ -1589,25 +1752,25 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.25.0": + version: 0.25.0 + resolution: "@esbuild/win32-x64@npm:0.25.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.0 - resolution: "@eslint-community/eslint-utils@npm:4.4.0" + version: 4.4.1 + resolution: "@eslint-community/eslint-utils@npm:4.4.1" dependencies: - eslint-visitor-keys: "npm:^3.3.0" + eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/7e559c4ce59cd3a06b1b5a517b593912e680a7f981ae7affab0d01d709e99cd5647019be8fafa38c350305bc32f1f7d42c7073edde2ab536c745e365f37b607e - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.10.0": - version: 4.11.1 - resolution: "@eslint-community/regexpp@npm:4.11.1" - checksum: 10c0/fbcc1cb65ef5ed5b92faa8dc542e035269065e7ebcc0b39c81a4fe98ad35cfff20b3c8df048641de15a7757e07d69f85e2579c1a5055f993413ba18c055654f8 + checksum: 10c0/2aa0ac2fc50ff3f234408b10900ed4f1a0b19352f21346ad4cc3d83a1271481bdda11097baa45d484dd564c895e0762a27a8240be7a256b3ad47129e96528252 languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.12.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 @@ -1615,13 +1778,13 @@ __metadata: linkType: hard "@eslint/config-array@npm:^0.19.0": - version: 0.19.0 - resolution: "@eslint/config-array@npm:0.19.0" + version: 0.19.2 + resolution: "@eslint/config-array@npm:0.19.2" dependencies: - "@eslint/object-schema": "npm:^2.1.4" + "@eslint/object-schema": "npm:^2.1.6" debug: "npm:^4.3.1" minimatch: "npm:^3.1.2" - checksum: 10c0/def23c6c67a8f98dc88f1b87e17a5668e5028f5ab9459661aabfe08e08f2acd557474bbaf9ba227be0921ae4db232c62773dbb7739815f8415678eb8f592dbf5 + checksum: 10c0/dd68da9abb32d336233ac4fe0db1e15a0a8d794b6e69abb9e57545d746a97f6f542496ff9db0d7e27fab1438546250d810d90b1904ac67677215b8d8e7573f3d languageName: node linkType: hard @@ -1634,6 +1797,15 @@ __metadata: languageName: node linkType: hard +"@eslint/core@npm:^0.11.0": + version: 0.11.0 + resolution: "@eslint/core@npm:0.11.0" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10c0/1e0671d035c908175f445864a7864cf6c6a8b67a5dfba8c47b2ac91e2d3ed36e8c1f2fd81d98a73264f8677055559699d4adb0f97d86588e616fc0dc9a4b86c9 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^3.2.0": version: 3.2.0 resolution: "@eslint/eslintrc@npm:3.2.0" @@ -1651,17 +1823,17 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.19.0": - version: 9.19.0 - resolution: "@eslint/js@npm:9.19.0" - checksum: 10c0/45dc544c8803984f80a438b47a8e578fae4f6e15bc8478a703827aaf05e21380b42a43560374ce4dad0d5cb6349e17430fc9ce1686fed2efe5d1ff117939ff90 +"@eslint/js@npm:9.20.0": + version: 9.20.0 + resolution: "@eslint/js@npm:9.20.0" + checksum: 10c0/10e7b5b9e628b5192e8fc6b0ecd27cf48322947e83e999ff60f9f9e44ac8d499138bcb9383cbfa6e51e780d53b4e76ccc2d1753b108b7173b8404fd484d37328 languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/object-schema@npm:2.1.4" - checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda +"@eslint/object-schema@npm:^2.1.6": + version: 2.1.6 + resolution: "@eslint/object-schema@npm:2.1.6" + checksum: 10c0/b8cdb7edea5bc5f6a96173f8d768d3554a628327af536da2fc6967a93b040f2557114d98dbcdbf389d5a7b290985ad6a9ce5babc547f36fc1fde42e674d11a56 languageName: node linkType: hard @@ -1690,21 +1862,21 @@ __metadata: linkType: hard "@floating-ui/core@npm:^1.6.0": - version: 1.6.8 - resolution: "@floating-ui/core@npm:1.6.8" + version: 1.6.9 + resolution: "@floating-ui/core@npm:1.6.9" dependencies: - "@floating-ui/utils": "npm:^0.2.8" - checksum: 10c0/d6985462aeccae7b55a2d3f40571551c8c42bf820ae0a477fc40ef462e33edc4f3f5b7f11b100de77c9b58ecb581670c5c3f46d0af82b5e30aa185c735257eb9 + "@floating-ui/utils": "npm:^0.2.9" + checksum: 10c0/77debdfc26bc36c6f5ae1f26ab3c15468215738b3f5682af4e1915602fa21ba33ad210273f31c9d2da1c531409929e1afb1138b1608c6b54a0f5853ee84c340d languageName: node linkType: hard "@floating-ui/dom@npm:^1.0.0": - version: 1.6.11 - resolution: "@floating-ui/dom@npm:1.6.11" + version: 1.6.13 + resolution: "@floating-ui/dom@npm:1.6.13" dependencies: "@floating-ui/core": "npm:^1.6.0" - "@floating-ui/utils": "npm:^0.2.8" - checksum: 10c0/02ef34a75a515543c772880338eea7b66724997bd5ec7cd58d26b50325709d46d480a306b84e7d5509d734434411a4bcf23af5680c2e461e6e6a8bf45d751df8 + "@floating-ui/utils": "npm:^0.2.9" + checksum: 10c0/272242d2eb6238ffcee0cb1f3c66e0eafae804d5d7b449db5ecf904bc37d31ad96cf575a9e650b93c1190f64f49a684b1559d10e05ed3ec210628b19116991a9 languageName: node linkType: hard @@ -1720,10 +1892,10 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.8": - version: 0.2.8 - resolution: "@floating-ui/utils@npm:0.2.8" - checksum: 10c0/a8cee5f17406c900e1c3ef63e3ca89b35e7a2ed645418459a73627b93b7377477fc888081011c6cd177cac45ec2b92a6cab018c14ea140519465498dddd2d3f9 +"@floating-ui/utils@npm:^0.2.9": + version: 0.2.9 + resolution: "@floating-ui/utils@npm:0.2.9" + checksum: 10c0/48bbed10f91cb7863a796cc0d0e917c78d11aeb89f98d03fc38d79e7eb792224a79f538ed8a2d5d5584511d4ca6354ef35f1712659fd569868e342df4398ad6f languageName: node linkType: hard @@ -1786,15 +1958,15 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:2.3.2": - version: 2.3.2 - resolution: "@formatjs/ecma402-abstract@npm:2.3.2" +"@formatjs/ecma402-abstract@npm:2.3.3": + version: 2.3.3 + resolution: "@formatjs/ecma402-abstract@npm:2.3.3" dependencies: "@formatjs/fast-memoize": "npm:2.2.6" - "@formatjs/intl-localematcher": "npm:0.5.10" + "@formatjs/intl-localematcher": "npm:0.6.0" decimal.js: "npm:10" tslib: "npm:2" - checksum: 10c0/364e9e7de974fed976e0e8142a0f888ee0af4a11a61899115e5761ed933e7c1f16379b7b54a01524fd3c5d58bf08b71308237ea969cd54889eaf7bb2d30ec776 + checksum: 10c0/63de990c380a1800bc54d97c4aa13a88a92e73b1680f0f561d03f9bf3e23289b7aafd1a92037527c285bd587a44e20504258ac2cbd4564a4138ce2b4612c1495 languageName: node linkType: hard @@ -1807,51 +1979,51 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.9.8": - version: 2.9.8 - resolution: "@formatjs/icu-messageformat-parser@npm:2.9.8" +"@formatjs/icu-messageformat-parser@npm:2.11.1": + version: 2.11.1 + resolution: "@formatjs/icu-messageformat-parser@npm:2.11.1" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.2" - "@formatjs/icu-skeleton-parser": "npm:1.8.12" + "@formatjs/ecma402-abstract": "npm:2.3.3" + "@formatjs/icu-skeleton-parser": "npm:1.8.13" tslib: "npm:2" - checksum: 10c0/df97c7f24fbeb8ef49ae1371f9498ad90f231f88211bf1effb7b2e8ac3531bec67c5d9147ddcb1add0ba697e8d089729add44a9a9c5015e0e8d61e7a43f062d9 + checksum: 10c0/2e4106d564ede73cc52c97fc4270002f2460c3ded10715a095ec6765c48f951b1e9744cc55679abe046e24e4e22c345e738f7477c43d440d1d10a0235b12df37 languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.8.12": - version: 1.8.12 - resolution: "@formatjs/icu-skeleton-parser@npm:1.8.12" +"@formatjs/icu-skeleton-parser@npm:1.8.13": + version: 1.8.13 + resolution: "@formatjs/icu-skeleton-parser@npm:1.8.13" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.2" + "@formatjs/ecma402-abstract": "npm:2.3.3" tslib: "npm:2" - checksum: 10c0/03e743aa09acb2137e37d03b98578fcbbc949d056b8c151763778e885d04d621e69c82f7656547f0532351d2a987bffac0a8c4c3d81186f47a28047ba64385e2 + checksum: 10c0/eddea5b7c43745d05178211b25641319e054747e40b42ffaa93ae9940fd42e6f5654d12d42e6998b91b4de4b67a24e3ed779a37394262ec1dd46e693c166729a languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.5.10": - version: 0.5.10 - resolution: "@formatjs/intl-localematcher@npm:0.5.10" +"@formatjs/intl-localematcher@npm:0.6.0": + version: 0.6.0 + resolution: "@formatjs/intl-localematcher@npm:0.6.0" dependencies: tslib: "npm:2" - checksum: 10c0/362ec83aca9382165be575f1cefa477478339e6fead8ca8866185ce6e58427ea1487a811b12c73d1bcfa99fd4db0c24543b35c823451839f585576bfccb8c9cc + checksum: 10c0/90238e633426ff7237ab2bbe017be044fb2fb185a8d59a0652096ddab9cb1ddf64106d58fafd711ea19c4d3455bd966516ab93574ac3b169d9af2325875fae59 languageName: node linkType: hard -"@formatjs/intl@npm:3.1.0": - version: 3.1.0 - resolution: "@formatjs/intl@npm:3.1.0" +"@formatjs/intl@npm:3.1.4": + version: 3.1.4 + resolution: "@formatjs/intl@npm:3.1.4" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.2" + "@formatjs/ecma402-abstract": "npm:2.3.3" "@formatjs/fast-memoize": "npm:2.2.6" - "@formatjs/icu-messageformat-parser": "npm:2.9.8" - intl-messageformat: "npm:10.7.11" + "@formatjs/icu-messageformat-parser": "npm:2.11.1" + intl-messageformat: "npm:10.7.15" tslib: "npm:2" peerDependencies: typescript: 5 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/a073768fffc51696eb7bd25fe1f0afdda1a0e38db3e2dd9b2fc3138ea799f00ef522f3d3083626ad3acbf913593254cfd728a6c6b08ef4f167dd132626a7e9fc + checksum: 10c0/c05828cf510b3e7930e7d334662142d4bbe603eb8b1bcb2eb5bc81856501c8ae62c89d43f6c54c9605d2a538fc8b361822880e5d92cea621c95e8d1915f870c5 languageName: node linkType: hard @@ -1925,14 +2097,23 @@ __metadata: languageName: node linkType: hard +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.5": - version: 0.3.5 - resolution: "@jridgewell/gen-mapping@npm:0.3.5" + version: 0.3.8 + resolution: "@jridgewell/gen-mapping@npm:0.3.8" dependencies: "@jridgewell/set-array": "npm:^1.2.1" "@jridgewell/sourcemap-codec": "npm:^1.4.10" "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/1be4fd4a6b0f41337c4f5fdf4afc3bd19e39c3691924817108b82ffcb9c9e609c273f936932b9fba4b3a298ce2eb06d9bff4eb1cc3bd81c4f4ee1b4917e25feb + checksum: 10c0/c668feaf86c501d7c804904a61c23c67447b2137b813b9ce03eca82cb9d65ac7006d766c218685d76e3d72828279b6ee26c347aa1119dab23fbaf36aed51585a languageName: node linkType: hard @@ -2004,9 +2185,9 @@ __metadata: linkType: hard "@mui/core-downloads-tracker@npm:^6.4.1": - version: 6.4.1 - resolution: "@mui/core-downloads-tracker@npm:6.4.1" - checksum: 10c0/5c35592eecb6b9b64b23003975a8ce20fadb9e9b712a78dd552b5ea835d06e8e4d7b7cb84f471f5658b5285de317a860b40597ad3c5e494e84f0ae0daf35fd6b + version: 6.4.3 + resolution: "@mui/core-downloads-tracker@npm:6.4.3" + checksum: 10c0/4be7a66f004a2bfb03d81348581c35c25f74dfc8cfe32a3a44ca30dd45888f37ae3c0da24b957d598adf3e833bc2ca32c0d6b70c4bca08499a0819f78dc417eb languageName: node linkType: hard @@ -2094,12 +2275,12 @@ __metadata: languageName: node linkType: hard -"@mui/private-theming@npm:^6.4.1": - version: 6.4.1 - resolution: "@mui/private-theming@npm:6.4.1" +"@mui/private-theming@npm:^6.4.1, @mui/private-theming@npm:^6.4.3": + version: 6.4.3 + resolution: "@mui/private-theming@npm:6.4.3" dependencies: "@babel/runtime": "npm:^7.26.0" - "@mui/utils": "npm:^6.4.1" + "@mui/utils": "npm:^6.4.3" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2107,13 +2288,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/5b6936e6dff6218373579f901aabba01eea1953e97a5b4b695736aeebca2d39fc7c2b4d0e54ab064d1ba99a6ffce0d907098791ecec28795f7da25c1bd0d33cb + checksum: 10c0/f1f6afede4917eb04f007b0c2ff52536b5e7561259812663eb77bfd059dd41eb7f85ae80e1229ebde0d134f428241bbd91185053c6e06e70a32bdfb983981a2a languageName: node linkType: hard -"@mui/styled-engine@npm:^6.4.0": - version: 6.4.0 - resolution: "@mui/styled-engine@npm:6.4.0" +"@mui/styled-engine@npm:^6.4.0, @mui/styled-engine@npm:^6.4.3": + version: 6.4.3 + resolution: "@mui/styled-engine@npm:6.4.3" dependencies: "@babel/runtime": "npm:^7.26.0" "@emotion/cache": "npm:^11.13.5" @@ -2130,50 +2311,47 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10c0/bff35147ca9ef586679b53786d840e98837f0c1e5bf10a3510d4b2b68c340ae4ab69befe94b69ef25f6846bada5b3c355d25fa3a179d1598499e28c51f28d5d2 + checksum: 10c0/7968beec5878fbed0e22d04595bf9e05007d67fbf5c69aed1095e7bef2207ddab72331ef683be2ad61bb5a59aeaca16464d86621d4da43c87c1c8cf4c8db8cdb languageName: node linkType: hard -"@mui/styles@npm:6.4.1": +"@mui/system@npm:6.4.1": version: 6.4.1 - resolution: "@mui/styles@npm:6.4.1" + resolution: "@mui/system@npm:6.4.1" dependencies: "@babel/runtime": "npm:^7.26.0" - "@emotion/hash": "npm:^0.9.2" "@mui/private-theming": "npm:^6.4.1" + "@mui/styled-engine": "npm:^6.4.0" "@mui/types": "npm:^7.2.21" "@mui/utils": "npm:^6.4.1" clsx: "npm:^2.1.1" csstype: "npm:^3.1.3" - hoist-non-react-statics: "npm:^3.3.2" - jss: "npm:^10.10.0" - jss-plugin-camel-case: "npm:^10.10.0" - jss-plugin-default-unit: "npm:^10.10.0" - jss-plugin-global: "npm:^10.10.0" - jss-plugin-nested: "npm:^10.10.0" - jss-plugin-props-sort: "npm:^10.10.0" - jss-plugin-rule-value-function: "npm:^10.10.0" - jss-plugin-vendor-prefixer: "npm:^10.10.0" prop-types: "npm:^15.8.1" peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true "@types/react": optional: true - checksum: 10c0/8f6771be05226ebdde1c33d46a96244c379c3eec3575694e7b95c72a94ddf6219d27ff2ce4afcba54a85f67780da25652b20defcdfd48b90ad8efeb91f607d2d + checksum: 10c0/34d731fb5faf1a6242c9faca5672a4b8722ac97cf5d1fd58cf85cce093cfbd2249ed57dd4c33e8f3b879c611e0fab56bb9e0e8fc1b7c8a49cbe4dd39ba32f98d languageName: node linkType: hard -"@mui/system@npm:6.4.1, @mui/system@npm:^6.4.1": - version: 6.4.1 - resolution: "@mui/system@npm:6.4.1" +"@mui/system@npm:^6.4.1": + version: 6.4.3 + resolution: "@mui/system@npm:6.4.3" dependencies: "@babel/runtime": "npm:^7.26.0" - "@mui/private-theming": "npm:^6.4.1" - "@mui/styled-engine": "npm:^6.4.0" + "@mui/private-theming": "npm:^6.4.3" + "@mui/styled-engine": "npm:^6.4.3" "@mui/types": "npm:^7.2.21" - "@mui/utils": "npm:^6.4.1" + "@mui/utils": "npm:^6.4.3" clsx: "npm:^2.1.1" csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" @@ -2189,35 +2367,23 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10c0/34d731fb5faf1a6242c9faca5672a4b8722ac97cf5d1fd58cf85cce093cfbd2249ed57dd4c33e8f3b879c611e0fab56bb9e0e8fc1b7c8a49cbe4dd39ba32f98d - languageName: node - linkType: hard - -"@mui/types@npm:^7.2.18": - version: 7.2.18 - resolution: "@mui/types@npm:7.2.18" - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 10c0/338404bdef7c7f9ebcd389ebbf429c44d2cc9c25c65d8669dc900a24b2c8718240482273bf6cd953578965e3838ad40a8e7376c71d3d9146be3afb88bff1b67a + checksum: 10c0/e5bf5255672b21253390adfc843fa764d3e98e530dfe51b770ea6fba880a8b8c8b153d616f9b54828c99bbdb0f25911c2fc70e557434621d1eaa767de78aff1f languageName: node linkType: hard "@mui/types@npm:^7.2.21": - version: 7.2.21 - resolution: "@mui/types@npm:7.2.21" + version: 7.2.22 + resolution: "@mui/types@npm:7.2.22" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/c0038ae402a3cfb2805a19167362fb5ac2ca1403f0ef3dad688d1e2276afe757b69d5fb1e3af4cd0e985b9221d287fd863c5b00f29fd07a276c7de9e3423a0f3 + checksum: 10c0/99811e972ac19e256af05ed4047f53f72282c4e239748ebbc9ef4f074f54e0f5d2d99e23210f9faa93fce49ed426ea80021db21d31fc18cd1e878ca1081e1472 languageName: node linkType: hard -"@mui/utils@npm:6.4.1, @mui/utils@npm:^6.4.1": +"@mui/utils@npm:6.4.1": version: 6.4.1 resolution: "@mui/utils@npm:6.4.1" dependencies: @@ -2237,23 +2403,23 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.16.6 || ^6.0.0": - version: 6.1.5 - resolution: "@mui/utils@npm:6.1.5" +"@mui/utils@npm:^5.16.6 || ^6.0.0, @mui/utils@npm:^6.4.1, @mui/utils@npm:^6.4.3": + version: 6.4.3 + resolution: "@mui/utils@npm:6.4.3" dependencies: - "@babel/runtime": "npm:^7.25.7" - "@mui/types": "npm:^7.2.18" - "@types/prop-types": "npm:^15.7.13" + "@babel/runtime": "npm:^7.26.0" + "@mui/types": "npm:^7.2.21" + "@types/prop-types": "npm:^15.7.14" clsx: "npm:^2.1.1" prop-types: "npm:^15.8.1" - react-is: "npm:^18.3.1" + react-is: "npm:^19.0.0" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/899191334f321aedf993e6a79cd63ac511e8ef23a84c1e156ca4a82c407e97f86f9f3d4250765f5c9e71d9af963bdc738e6d63fc62f9088fc5ad9c055fc3b111 + checksum: 10c0/bf199e61bd5d92469b954dd74471db3d27bd6fe43fd13a306056f6cdeb60f5bb1fe1e9ffc4a99e56785c8f56928951e098f340d79aeaf2b3a91041ae8154f934 languageName: node linkType: hard @@ -2355,25 +2521,25 @@ __metadata: languageName: node linkType: hard -"@npmcli/agent@npm:^2.0.0": - version: 2.2.2 - resolution: "@npmcli/agent@npm:2.2.2" +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" dependencies: agent-base: "npm:^7.1.0" http-proxy-agent: "npm:^7.0.0" https-proxy-agent: "npm:^7.0.1" lru-cache: "npm:^10.0.1" socks-proxy-agent: "npm:^8.0.3" - checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae + checksum: 10c0/efe37b982f30740ee77696a80c196912c274ecd2cb243bc6ae7053a50c733ce0f6c09fda085145f33ecf453be19654acca74b69e81eaad4c90f00ccffe2f9271 languageName: node linkType: hard -"@npmcli/fs@npm:^3.1.0": - version: 3.1.1 - resolution: "@npmcli/fs@npm:3.1.1" +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" dependencies: semver: "npm:^7.3.5" - checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 + checksum: 10c0/c90935d5ce670c87b6b14fab04a965a3b8137e585f8b2a6257263bd7f97756dd736cb165bb470e5156a9e718ecd99413dccc54b1138c1a46d6ec7cf325982fe5 languageName: node linkType: hard @@ -2504,247 +2670,268 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.24.0" +"@rollup/rollup-android-arm-eabi@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.34.3" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.31.0" +"@rollup/rollup-android-arm-eabi@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.34.4" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-android-arm64@npm:4.24.0" +"@rollup/rollup-android-arm64@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-android-arm64@npm:4.34.3" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-android-arm64@npm:4.31.0" +"@rollup/rollup-android-arm64@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-android-arm64@npm:4.34.4" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.24.0" +"@rollup/rollup-darwin-arm64@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-darwin-arm64@npm:4.34.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-darwin-arm64@npm:4.31.0" +"@rollup/rollup-darwin-arm64@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-darwin-arm64@npm:4.34.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.24.0" +"@rollup/rollup-darwin-x64@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-darwin-x64@npm:4.34.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-darwin-x64@npm:4.31.0" +"@rollup/rollup-darwin-x64@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-darwin-x64@npm:4.34.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.31.0" +"@rollup/rollup-freebsd-arm64@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.34.3" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.34.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-freebsd-x64@npm:4.31.0" +"@rollup/rollup-freebsd-x64@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-freebsd-x64@npm:4.34.3" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-freebsd-x64@npm:4.34.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.24.0" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.34.3" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.31.0" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.34.4" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.24.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.34.3" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.31.0" +"@rollup/rollup-linux-arm-musleabihf@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.34.4" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.24.0" +"@rollup/rollup-linux-arm64-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.34.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.31.0" +"@rollup/rollup-linux-arm64-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.34.4" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.24.0" +"@rollup/rollup-linux-arm64-musl@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.34.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.31.0" +"@rollup/rollup-linux-arm64-musl@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.34.4" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.31.0" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.34.3" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-loongarch64-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.34.4" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.24.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.3" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.31.0" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.34.4" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.24.0" +"@rollup/rollup-linux-riscv64-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.34.3" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.31.0" +"@rollup/rollup-linux-riscv64-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.34.4" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.24.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.34.3" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.31.0" +"@rollup/rollup-linux-s390x-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.34.4" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.24.0" +"@rollup/rollup-linux-x64-gnu@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.34.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.31.0" +"@rollup/rollup-linux-x64-gnu@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.34.4" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.24.0" +"@rollup/rollup-linux-x64-musl@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.34.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.31.0" +"@rollup/rollup-linux-x64-musl@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.34.4" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.24.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.34.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.31.0" +"@rollup/rollup-win32-arm64-msvc@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.34.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.24.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.34.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.31.0" +"@rollup/rollup-win32-ia32-msvc@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.34.4" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.24.0": - version: 4.24.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.24.0" +"@rollup/rollup-win32-x64-msvc@npm:4.34.3": + version: 4.34.3 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.34.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.31.0": - version: 4.31.0 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.31.0" +"@rollup/rollup-win32-x64-msvc@npm:4.34.4": + version: 4.34.4 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.34.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -2772,11 +2959,11 @@ __metadata: linkType: hard "@svgdotjs/svg.draggable.js@npm:^3.0.4": - version: 3.0.4 - resolution: "@svgdotjs/svg.draggable.js@npm:3.0.4" + version: 3.0.5 + resolution: "@svgdotjs/svg.draggable.js@npm:3.0.5" peerDependencies: "@svgdotjs/svg.js": ^3.2.4 - checksum: 10c0/0c3237a6f6998f04862fde916d5dddb7d2c00e79c1606551be6abf2d2993b9d21abe86576c9e0374c094af22155b78e86f57ba959f8c9098db32ad31ecd82503 + checksum: 10c0/b92cb434a1c66c236c03f9ab645bc67372cfdf3800eea254c875d4a77e0dc90ec89cccb9f89f5831b7c873d63a03f1e4d65a02afde2f97d76e44e6cc1f49887d languageName: node linkType: hard @@ -3036,12 +3223,12 @@ __metadata: linkType: hard "@types/hoist-non-react-statics@npm:3": - version: 3.3.5 - resolution: "@types/hoist-non-react-statics@npm:3.3.5" + version: 3.3.6 + resolution: "@types/hoist-non-react-statics@npm:3.3.6" dependencies: "@types/react": "npm:*" hoist-non-react-statics: "npm:^3.3.0" - checksum: 10c0/2a3b64bf3d9817d7830afa60ee314493c475fb09570a64e7737084cd482d2177ebdddf888ce837350bac51741278b077683facc9541f052d4bbe8487b4e3e618 + checksum: 10c0/149a4c217d81f21f8a1e152160a59d5b99b6a9aa6d354385d5f5bc02760cbf1e170a8442ba92eb653befff44b0c5bc2234bb77ce33e0d11a65f779e8bab5c321 languageName: node linkType: hard @@ -3078,18 +3265,18 @@ __metadata: linkType: hard "@types/ms@npm:*": - version: 0.7.34 - resolution: "@types/ms@npm:0.7.34" - checksum: 10c0/ac80bd90012116ceb2d188fde62d96830ca847823e8ca71255616bc73991aa7d9f057b8bfab79e8ee44ffefb031ddd1bcce63ea82f9e66f7c31ec02d2d823ccc + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 10c0/5ce692ffe1549e1b827d99ef8ff71187457e0eb44adbae38fdf7b9a74bae8d20642ee963c14516db1d35fa2652e65f47680fdf679dcbde52bbfadd021f497225 languageName: node linkType: hard "@types/node@npm:*": - version: 22.7.9 - resolution: "@types/node@npm:22.7.9" + version: 22.13.1 + resolution: "@types/node@npm:22.13.1" dependencies: - undici-types: "npm:~6.19.2" - checksum: 10c0/2d1917702b9d9ede8e4d8151cd8b1af8bc147d543486474ffbe0742e38764ea73105939e6a767addf7a4c39e842e16eae762bff90617d7b7f9ee3fbbb2d23bfa + undici-types: "npm:~6.20.0" + checksum: 10c0/d4e56d41d8bd53de93da2651c0a0234e330bd7b1b6d071b1a94bd3b5ee2d9f387519e739c52a15c1faa4fb9d97e825b848421af4b2e50e6518011e7adb4a34b7 languageName: node linkType: hard @@ -3110,11 +3297,11 @@ __metadata: linkType: hard "@types/pdfkit@npm:*": - version: 0.13.5 - resolution: "@types/pdfkit@npm:0.13.5" + version: 0.13.9 + resolution: "@types/pdfkit@npm:0.13.9" dependencies: "@types/node": "npm:*" - checksum: 10c0/de23f205951e5b7c12882453c08a3cbf602fd664cf0b110a310711eafdc8ace153dd13b350247d1713fe9847f1776bc443b9a701f6d799a57207d8ddab4ea499 + checksum: 10c0/e467fbbc4f4e5a487887c9f27784aa6262e5a45ab8f5676ee4662eb8862e1ef9a18a8f463fbc3150f2d50fe83902c5877714ac141acd8ccb780e18c88999cc29 languageName: node linkType: hard @@ -3135,14 +3322,7 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.13": - version: 15.7.13 - resolution: "@types/prop-types@npm:15.7.13" - checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61 - languageName: node - linkType: hard - -"@types/prop-types@npm:^15.7.14": +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.14": version: 15.7.14 resolution: "@types/prop-types@npm:15.7.14" checksum: 10c0/1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1 @@ -3183,16 +3363,7 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.4.11": - version: 4.4.11 - resolution: "@types/react-transition-group@npm:4.4.11" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/8fbf0dcc1b81985cdcebe3c59d769fe2ea3f4525f12c3a10a7429a59f93e303c82b2abb744d21cb762879f4514969d70a7ab11b9bf486f92213e8fe70e04098d - languageName: node - linkType: hard - -"@types/react-transition-group@npm:^4.4.12": +"@types/react-transition-group@npm:^4.4.11, @types/react-transition-group@npm:^4.4.12": version: 4.4.12 resolution: "@types/react-transition-group@npm:4.4.12" peerDependencies: @@ -3201,23 +3372,13 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:16 || 17 || 18": - version: 18.3.12 - resolution: "@types/react@npm:18.3.12" - dependencies: - "@types/prop-types": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10c0/8bae8d9a41619804561574792e29112b413044eb0d53746dde2b9720c1f9a59f71c895bbd7987cd8ce9500b00786e53bc032dced38cddf42910458e145675290 - languageName: node - linkType: hard - -"@types/react@npm:18.3.14": - version: 18.3.14 - resolution: "@types/react@npm:18.3.14" +"@types/react@npm:18": + version: 18.3.18 + resolution: "@types/react@npm:18.3.18" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10c0/d925fbfcf084238b93d1a0b5406d4cf9aeb37c4a1191559aa4ee107c2e55cc15327989140f03eddda4d471f5b935d4673fd74a86f451860edea18eae48ca44f8 + checksum: 10c0/8fb2b00672072135d0858dc9db07873ea107cc238b6228aaa2a9afd1ef7a64a7074078250db38afbeb19064be8ea6af5eac32d404efdd5f45e093cc4829d87f8 languageName: node linkType: hard @@ -3307,16 +3468,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.15.0": - version: 8.15.0 - resolution: "@typescript-eslint/scope-manager@npm:8.15.0" - dependencies: - "@typescript-eslint/types": "npm:8.15.0" - "@typescript-eslint/visitor-keys": "npm:8.15.0" - checksum: 10c0/c27dfdcea4100cc2d6fa967f857067cbc93155b55e648f9f10887a1b9372bb76cf864f7c804f3fa48d7868d9461cdef10bcea3dab7637d5337e8aa8042dc08b9 - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:8.22.0": version: 8.22.0 resolution: "@typescript-eslint/scope-manager@npm:8.22.0" @@ -3327,6 +3478,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.23.0": + version: 8.23.0 + resolution: "@typescript-eslint/scope-manager@npm:8.23.0" + dependencies: + "@typescript-eslint/types": "npm:8.23.0" + "@typescript-eslint/visitor-keys": "npm:8.23.0" + checksum: 10c0/625b524a4fc25667b20f3541da84674af9c2abfac6596e30f7a40085513172bf1aac125488b32885894e3ef6596a0d06dec9a65ed4562884e0bca87a758600fa + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:8.22.0": version: 8.22.0 resolution: "@typescript-eslint/type-utils@npm:8.22.0" @@ -3342,13 +3503,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.15.0": - version: 8.15.0 - resolution: "@typescript-eslint/types@npm:8.15.0" - checksum: 10c0/84abc6fd954aff13822a76ac49efdcb90a55c0025c20eee5d8cebcfb68faff33b79bbc711ea524e0209cecd90c5ee3a5f92babc7083c081d3a383a0710264a41 - languageName: node - linkType: hard - "@typescript-eslint/types@npm:8.22.0": version: 8.22.0 resolution: "@typescript-eslint/types@npm:8.22.0" @@ -3356,22 +3510,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.15.0": - version: 8.15.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.15.0" - dependencies: - "@typescript-eslint/types": "npm:8.15.0" - "@typescript-eslint/visitor-keys": "npm:8.15.0" - debug: "npm:^4.3.4" - fast-glob: "npm:^3.3.2" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/3af5c129532db3575349571bbf64d32aeccc4f4df924ac447f5d8f6af8b387148df51965eb2c9b99991951d3dadef4f2509d7ce69bf34a2885d013c040762412 +"@typescript-eslint/types@npm:8.23.0": + version: 8.23.0 + resolution: "@typescript-eslint/types@npm:8.23.0" + checksum: 10c0/78737a14e8469e33212d9bbc26d6880bca3f8e47764273eb4c662f5ed38d0b35c626d646d4a8e9a6ee64a0e352b18dd36422e59ce217362b5af473b79d058b35 languageName: node linkType: hard @@ -3393,6 +3535,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.23.0": + version: 8.23.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.23.0" + dependencies: + "@typescript-eslint/types": "npm:8.23.0" + "@typescript-eslint/visitor-keys": "npm:8.23.0" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.0.1" + peerDependencies: + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/2cc8defb3d9b25b899a62c6b6ca26c442433bf95f626f6275935e2754d9a74abb0015c737de27038b0f378273e67e61120d9cf2941c44848e4bffbbc297fdf74 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:8.22.0": version: 8.22.0 resolution: "@typescript-eslint/utils@npm:8.22.0" @@ -3409,29 +3569,17 @@ __metadata: linkType: hard "@typescript-eslint/utils@npm:^8.13.0": - version: 8.15.0 - resolution: "@typescript-eslint/utils@npm:8.15.0" + version: 8.23.0 + resolution: "@typescript-eslint/utils@npm:8.23.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.15.0" - "@typescript-eslint/types": "npm:8.15.0" - "@typescript-eslint/typescript-estree": "npm:8.15.0" + "@typescript-eslint/scope-manager": "npm:8.23.0" + "@typescript-eslint/types": "npm:8.23.0" + "@typescript-eslint/typescript-estree": "npm:8.23.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/65743f51845a1f6fd2d21f66ca56182ba33e966716bdca73d30b7a67c294e47889c322de7d7b90ab0818296cd33c628e5eeeb03cec7ef2f76c47de7a453eeda2 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:8.15.0": - version: 8.15.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.15.0" - dependencies: - "@typescript-eslint/types": "npm:8.15.0" - eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/02a954c3752c4328482a884eb1da06ca8fb72ae78ef28f1d854b18f3779406ed47263af22321cf3f65a637ec7584e5f483e34a263b5c8cec60ec85aebc263574 + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/8967cf6543b1df2fb8d29086a0d35f5f7623e935706ad7c5bfcc6123e6fb08a767be1770601d481d815022bec43422730c6c8035892f23cd11cdadb16176b418 languageName: node linkType: hard @@ -3445,6 +3593,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.23.0": + version: 8.23.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.23.0" + dependencies: + "@typescript-eslint/types": "npm:8.23.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/a406f78aa18b4efb2adf26e3a6ca48c9a6f2cc9545e083b50efaaf90f0a80d2bea79ceda51da1f109706d4138756b0978a323b9176c9a6a519e87168851e7e16 + languageName: node + linkType: hard + "@uiw/copy-to-clipboard@npm:~1.0.12": version: 1.0.17 resolution: "@uiw/copy-to-clipboard@npm:1.0.17" @@ -3492,9 +3650,9 @@ __metadata: linkType: hard "@ungap/structured-clone@npm:^1.0.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10c0/8209c937cb39119f44eb63cf90c0b73e7c754209a6411c707be08e50e29ee81356dca1a848a405c8bdeebfe2f5e4f831ad310ae1689eeef65e7445c090c6657d + version: 1.3.0 + resolution: "@ungap/structured-clone@npm:1.3.0" + checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a languageName: node linkType: hard @@ -3513,9 +3671,9 @@ __metadata: languageName: node linkType: hard -"@vitest/eslint-plugin@npm:1.1.25": - version: 1.1.25 - resolution: "@vitest/eslint-plugin@npm:1.1.25" +"@vitest/eslint-plugin@npm:1.1.27": + version: 1.1.27 + resolution: "@vitest/eslint-plugin@npm:1.1.27" peerDependencies: "@typescript-eslint/utils": ">= 8.0" eslint: ">= 8.57.0" @@ -3526,7 +3684,7 @@ __metadata: optional: true vitest: optional: true - checksum: 10c0/9707dbad11d86136a36c6c820fea063cb96e5fa6f8111ad24d3a9894df5594154da9a28ab51858a158ccaff4f49fbd79baada57b49d4891f98d5251cd53c90cb + checksum: 10c0/c7114a223df4491413b416962e7bb0948664c31b2b62c4daeffe30251735628f46dc14a829fcdbf2c20c2c934f7227791e834f1664530c1ead51c460acf168a5 languageName: node linkType: hard @@ -3572,11 +3730,11 @@ __metadata: linkType: hard "@vitest/pretty-format@npm:^2.1.1": - version: 2.1.3 - resolution: "@vitest/pretty-format@npm:2.1.3" + version: 2.1.9 + resolution: "@vitest/pretty-format@npm:2.1.9" dependencies: tinyrainbow: "npm:^1.2.0" - checksum: 10c0/5a6ee872a8adf5e2764f2b5b2276d8a2199be4ef14777ab693428caf359481851400af10b59721d4972289c955ffe7277954a662b04cfb10233824574c7074ba + checksum: 10c0/155f9ede5090eabed2a73361094bb35ed4ec6769ae3546d2a2af139166569aec41bb80e031c25ff2da22b71dd4ed51e5468e66a05e6aeda5f14b32e30bc18f00 languageName: node linkType: hard @@ -3611,11 +3769,11 @@ __metadata: linkType: hard "@vitest/spy@npm:^2.1.0-beta.1": - version: 2.1.3 - resolution: "@vitest/spy@npm:2.1.3" + version: 2.1.9 + resolution: "@vitest/spy@npm:2.1.9" dependencies: - tinyspy: "npm:^3.0.0" - checksum: 10c0/8d85a5c2848c5bd81892af989aebad65d0c7ae74094aa98ad4f35ecf80755259c7a748a8e7bf683b2906fac29a51fc0ffa82f8fc073b36dbd8a0418261fccdba + tinyspy: "npm:^3.0.2" + checksum: 10c0/12a59b5095e20188b819a1d797e0a513d991b4e6a57db679927c43b362a3eff52d823b34e855a6dd9e73c9fa138dcc5ef52210841a93db5cbf047957a60ca83c languageName: node linkType: hard @@ -3666,10 +3824,10 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:^2.0.0": - version: 2.0.0 - resolution: "abbrev@npm:2.0.0" - checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 +"abbrev@npm:^3.0.0": + version: 3.0.0 + resolution: "abbrev@npm:3.0.0" + checksum: 10c0/049704186396f571650eb7b22ed3627b77a5aedf98bb83caf2eac81ca2a3e25e795394b0464cfb2d6076df3db6a5312139eac5b6a126ca296ac53c5008069c28 languageName: node linkType: hard @@ -3719,31 +3877,10 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.12.0": - version: 8.13.0 - resolution: "acorn@npm:8.13.0" - bin: - acorn: bin/acorn - checksum: 10c0/f35dd53d68177c90699f4c37d0bb205b8abe036d955d0eb011ddb7f14a81e6fd0f18893731c457c1b5bd96754683f4c3d80d9a5585ddecaa53cdf84e0b3d68f7 - languageName: node - linkType: hard - -"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": - version: 7.1.1 - resolution: "agent-base@npm:7.1.1" - dependencies: - debug: "npm:^4.3.4" - checksum: 10c0/e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 - languageName: node - linkType: hard - -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: "npm:^2.0.0" - indent-string: "npm:^4.0.0" - checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.3 + resolution: "agent-base@npm:7.1.3" + checksum: 10c0/6192b580c5b1d8fb399b9c62bf8343d76654c2dd62afcb9a52b2cf44a8b6ace1e3b704d3fe3547d91555c857d3df02603341ff2cb961b9cfe2b12f9f3c38ee11 languageName: node linkType: hard @@ -3773,15 +3910,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^3.2.1": - version: 3.2.1 - resolution: "ansi-styles@npm:3.2.1" - dependencies: - color-convert: "npm:^1.9.0" - checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b - languageName: node - linkType: hard - "ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" @@ -3805,9 +3933,9 @@ __metadata: languageName: node linkType: hard -"apexcharts@npm:4.3.0": - version: 4.3.0 - resolution: "apexcharts@npm:4.3.0" +"apexcharts@npm:4.4.0": + version: 4.4.0 + resolution: "apexcharts@npm:4.4.0" dependencies: "@svgdotjs/svg.draggable.js": "npm:^3.0.4" "@svgdotjs/svg.filter.js": "npm:^3.0.8" @@ -3815,7 +3943,7 @@ __metadata: "@svgdotjs/svg.resize.js": "npm:^2.0.2" "@svgdotjs/svg.select.js": "npm:^4.0.1" "@yr/monotone-cubic-spline": "npm:^1.0.3" - checksum: 10c0/1120485120ffc52438bfb22db5371cef2f74133bfe839f0464d8c34f09dc477b9bb233f08718db9eef6fcbf96bf3c2c70026ad79f5631ab1feb2b2e3d7e914d9 + checksum: 10c0/e78b4e5359d9be0bb02741be9a6ee404f4eef1c9980841d18018cf61757499440e67b96d16b680e1ced3221acceb6c94f1355f50217e784a7c78894c4e0ebba2 languageName: node linkType: hard @@ -3835,17 +3963,7 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "array-buffer-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.5" - is-array-buffer: "npm:^3.0.4" - checksum: 10c0/f5cdf54527cd18a3d2852ddf73df79efec03829e7373a8322ef5df2b4ef546fb365c19c71d6b42d641cb6bfe0f1a2f19bc0ece5b533295f86d7c3d522f228917 - languageName: node - linkType: hard - -"array-buffer-byte-length@npm:^1.0.2": +"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "array-buffer-byte-length@npm:1.0.2" dependencies: @@ -3905,30 +4023,18 @@ __metadata: linkType: hard "array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flat@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10c0/a578ed836a786efbb6c2db0899ae80781b476200617f65a44846cb1ed8bd8b24c8821b83703375d8af639c689497b7b07277060024b9919db94ac3e10dc8a49b - languageName: node - linkType: hard - -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flatmap@npm:1.3.2" + version: 1.3.3 + resolution: "array.prototype.flat@npm:1.3.3" dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10c0/67b3f1d602bb73713265145853128b1ad77cc0f9b833c7e1e056b323fbeac41a4ff1c9c99c7b9445903caea924d9ca2450578d9011913191aa88cc3c3a4b54f4 + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10c0/d90e04dfbc43bb96b3d2248576753d1fb2298d2d972e29ca7ad5ec621f0d9e16ff8074dae647eac4f31f4fb7d3f561a7ac005fb01a71f51705a13b5af06a7d8a languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.3": +"array.prototype.flatmap@npm:^1.3.2, array.prototype.flatmap@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flatmap@npm:1.3.3" dependencies: @@ -3953,22 +4059,6 @@ __metadata: languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.3": - version: 1.0.3 - resolution: "arraybuffer.prototype.slice@npm:1.0.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" - es-errors: "npm:^1.2.1" - get-intrinsic: "npm:^1.2.3" - is-array-buffer: "npm:^3.0.4" - is-shared-array-buffer: "npm:^1.0.2" - checksum: 10c0/d32754045bcb2294ade881d45140a5e52bda2321b9e98fa514797b7f0d252c4c5ab0d1edb34112652c62fa6a9398def568da63a4d7544672229afea283358c36 - languageName: node - linkType: hard - "arraybuffer.prototype.slice@npm:^1.0.4": version: 1.0.4 resolution: "arraybuffer.prototype.slice@npm:1.0.4" @@ -3991,6 +4081,13 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 + languageName: node + linkType: hard + "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -4143,16 +4240,16 @@ __metadata: linkType: hard "browserslist@npm:^4.24.0": - version: 4.24.2 - resolution: "browserslist@npm:4.24.2" + version: 4.24.4 + resolution: "browserslist@npm:4.24.4" dependencies: - caniuse-lite: "npm:^1.0.30001669" - electron-to-chromium: "npm:^1.5.41" - node-releases: "npm:^2.0.18" + caniuse-lite: "npm:^1.0.30001688" + electron-to-chromium: "npm:^1.5.73" + node-releases: "npm:^2.0.19" update-browserslist-db: "npm:^1.1.1" bin: browserslist: cli.js - checksum: 10c0/d747c9fb65ed7b4f1abcae4959405707ed9a7b835639f8a9ba0da2911995a6ab9b0648fd05baf2a4d4e3cf7f9fdbad56d3753f91881e365992c1d49c8d88ff7a + checksum: 10c0/db7ebc1733cf471e0b490b4f47e3e2ea2947ce417192c9246644e92c667dd56a71406cc58f62ca7587caf828364892e9952904a02b7aead752bc65b62a37cfe9 languageName: node linkType: hard @@ -4170,11 +4267,11 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^18.0.0": - version: 18.0.4 - resolution: "cacache@npm:18.0.4" +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" dependencies: - "@npmcli/fs": "npm:^3.1.0" + "@npmcli/fs": "npm:^4.0.0" fs-minipass: "npm:^3.0.0" glob: "npm:^10.2.2" lru-cache: "npm:^10.0.1" @@ -4182,11 +4279,11 @@ __metadata: minipass-collect: "npm:^2.0.1" minipass-flush: "npm:^1.0.5" minipass-pipeline: "npm:^1.2.4" - p-map: "npm:^4.0.0" - ssri: "npm:^10.0.0" - tar: "npm:^6.1.11" - unique-filename: "npm:^3.0.0" - checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f + p-map: "npm:^7.0.2" + ssri: "npm:^12.0.0" + tar: "npm:^7.4.3" + unique-filename: "npm:^4.0.0" + checksum: 10c0/01f2134e1bd7d3ab68be851df96c8d63b492b1853b67f2eecb2c37bb682d37cb70bb858a16f2f0554d3c0071be6dfe21456a1ff6fa4b7eed996570d6a25ffe9c languageName: node linkType: hard @@ -4210,20 +4307,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": - version: 1.0.7 - resolution: "call-bind@npm:1.0.7" - dependencies: - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - get-intrinsic: "npm:^1.2.4" - set-function-length: "npm:^1.2.1" - checksum: 10c0/a3ded2e423b8e2a265983dba81c27e125b48eefb2655e7dfab6be597088da3d47c47976c24bc51b8fd9af1061f8f87b4ab78a314f3c77784b2ae2ba535ad8b8d - languageName: node - linkType: hard - -"call-bind@npm:^1.0.8": +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" dependencies: @@ -4259,10 +4343,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001669": - version: 1.0.30001669 - resolution: "caniuse-lite@npm:1.0.30001669" - checksum: 10c0/f125f23440d3dbb6c25ffb8d55f4ce48af36a84d0932b152b3b74f143a4170cbe92e02b0a9676209c86609bf7bf34119ff10cc2bc7c1b7ea40e936cc16598408 +"caniuse-lite@npm:^1.0.30001688": + version: 1.0.30001697 + resolution: "caniuse-lite@npm:1.0.30001697" + checksum: 10c0/c114045be1bb5e610ca14c619157472910401bf59cc4d3050cc64ecd6887345ae8f685a5474c126755fabbd6e02f899b3b743218ab46dcbd5b6880607b67e18e languageName: node linkType: hard @@ -4286,17 +4370,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.2": - version: 2.4.2 - resolution: "chalk@npm:2.4.2" - dependencies: - ansi-styles: "npm:^3.2.1" - escape-string-regexp: "npm:^1.0.5" - supports-color: "npm:^5.3.0" - checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 - languageName: node - linkType: hard - "chalk@npm:^4.0.0, chalk@npm:^4.1.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -4372,10 +4445,10 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^2.0.0": - version: 2.0.0 - resolution: "chownr@npm:2.0.0" - checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 languageName: node linkType: hard @@ -4452,20 +4525,6 @@ __metadata: languageName: node linkType: hard -"classnames@npm:2.5.1": - version: 2.5.1 - resolution: "classnames@npm:2.5.1" - checksum: 10c0/afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69 - languageName: node - linkType: hard - -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -4507,22 +4566,6 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0": - version: 1.9.3 - resolution: "color-convert@npm:1.9.3" - dependencies: - color-name: "npm:1.1.3" - checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c - languageName: node - linkType: hard - -"color-name@npm:1.1.3": - version: 1.1.3 - resolution: "color-name@npm:1.1.3" - checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 - languageName: node - linkType: hard - "color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" @@ -4562,14 +4605,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^12.1.0": - version: 12.1.0 - resolution: "commander@npm:12.1.0" - checksum: 10c0/6e1996680c083b3b897bfc1cfe1c58dfbcd9842fd43e1aaf8a795fbc237f65efcc860a3ef457b318e73f29a4f4a28f6403c3d653d021d960e4632dd45bde54a9 - languageName: node - linkType: hard - -"commander@npm:^13.0.0": +"commander@npm:^13.0.0, commander@npm:^13.1.0": version: 13.1.0 resolution: "commander@npm:13.1.0" checksum: 10c0/7b8c5544bba704fbe84b7cab2e043df8586d5c114a4c5b607f83ae5060708940ed0b5bd5838cf8ce27539cde265c1cbd59ce3c8c6b017ed3eec8943e3a415164 @@ -4584,16 +4620,9 @@ __metadata: linkType: hard "consola@npm:^3.2.3": - version: 3.2.3 - resolution: "consola@npm:3.2.3" - checksum: 10c0/c606220524ec88a05bb1baf557e9e0e04a0c08a9c35d7a08652d99de195c4ddcb6572040a7df57a18ff38bbc13ce9880ad032d56630cef27bef72768ef0ac078 - languageName: node - linkType: hard - -"console-grid@npm:^2.2.2": - version: 2.2.2 - resolution: "console-grid@npm:2.2.2" - checksum: 10c0/6fe4dd9f7224e65d1bf84ccd68e214aa3c32050b1bbff2e921f837ff2c9541dac97626105f9b0536df835f2eb29ed0b0f03e1ef257d68d43f6d8fad7a3a97750 + version: 3.4.0 + resolution: "consola@npm:3.4.0" + checksum: 10c0/bc7f7ad46514375109a80f3ae8330097eb1e5d89232a24eb830f3ac383e22036a62c53d33561cd73d7cda4b3691fba85e3dcf35229ef7721b324aae291ceb40c languageName: node linkType: hard @@ -4716,18 +4745,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1": - version: 7.0.5 - resolution: "cross-spawn@npm:7.0.5" - dependencies: - path-key: "npm:^3.1.0" - shebang-command: "npm:^2.0.0" - which: "npm:^2.0.1" - checksum: 10c0/aa82ce7ac0814a27e6f2b738c5a7cf1fa21a3558a1e42df449fc96541ba3ba731e4d3ecffa4435348808a86212f287c6f20a1ee551ef1ff95d01cfec5f434944 - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -4752,22 +4770,13 @@ __metadata: languageName: node linkType: hard -"css-vendor@npm:^2.0.8": - version: 2.0.8 - resolution: "css-vendor@npm:2.0.8" - dependencies: - "@babel/runtime": "npm:^7.8.3" - is-in-browser: "npm:^1.0.2" - checksum: 10c0/2538bc37adf72eb79781929dbb8c48e12c6a4b926594ad4134408b3000249f1a50d25be374f0e63f688c863368814aa6cc2e9ea11ea22a7309a7d966b281244c - languageName: node - linkType: hard - "cssstyle@npm:^4.1.0": - version: 4.1.0 - resolution: "cssstyle@npm:4.1.0" + version: 4.2.1 + resolution: "cssstyle@npm:4.2.1" dependencies: - rrweb-cssom: "npm:^0.7.1" - checksum: 10c0/05c6597e5d3e0ec6b15221f2c0ce9a0443a46cc50a6089a3ba9ee1ac27f83ff86a445a8f95435137dadd859f091fc61b6d342abaf396d3c910471b5b33cfcbfa + "@asamuzakjp/css-color": "npm:^2.8.2" + rrweb-cssom: "npm:^0.8.0" + checksum: 10c0/02ba8c47c0caaab57acadacb3eb6c0f5f009000f55d61f6563670e07d389b26edefeed497e6c1847fcd2e6bbe0b6974c2d4291f97fa0c6ec6add13a7fa926d84 languageName: node linkType: hard @@ -4877,17 +4886,6 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-buffer@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/8984119e59dbed906a11fcfb417d7d861936f16697a0e7216fe2c6c810f6b5e8f4a5281e73f2c28e8e9259027190ac4a33e2a65fdd7fa86ac06b76e838918583 - languageName: node - linkType: hard - "data-view-buffer@npm:^1.0.2": version: 1.0.2 resolution: "data-view-buffer@npm:1.0.2" @@ -4899,17 +4897,6 @@ __metadata: languageName: node linkType: hard -"data-view-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/b7d9e48a0cf5aefed9ab7d123559917b2d7e0d65531f43b2fd95b9d3a6b46042dd3fca597c42bba384e66b70d7ad66ff23932f8367b241f53d93af42cfe04ec2 - languageName: node - linkType: hard - "data-view-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "data-view-byte-length@npm:1.0.2" @@ -4921,17 +4908,6 @@ __metadata: languageName: node linkType: hard -"data-view-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "data-view-byte-offset@npm:1.0.0" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10c0/21b0d2e53fd6e20cc4257c873bf6d36d77bd6185624b84076c0a1ddaa757b49aaf076254006341d35568e89f52eecd1ccb1a502cfb620f2beca04f48a6a62a8f - languageName: node - linkType: hard - "data-view-byte-offset@npm:^1.0.1": version: 1.0.1 resolution: "data-view-byte-offset@npm:1.0.1" @@ -4960,14 +4936,14 @@ __metadata: linkType: hard "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6": - version: 4.3.7 - resolution: "debug@npm:4.3.7" + version: 4.4.0 + resolution: "debug@npm:4.4.0" dependencies: ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b + checksum: 10c0/db94f1a182bf886f57b4755f85b3a74c39b5114b9377b7ab375dc2cfa3454f09490cc6c30f829df3fc8042bc8b8995f6567ce5cd96f3bc3688bd24027197d9de languageName: node linkType: hard @@ -4981,9 +4957,9 @@ __metadata: linkType: hard "decimal.js@npm:10, decimal.js@npm:^10.4.3": - version: 10.4.3 - resolution: "decimal.js@npm:10.4.3" - checksum: 10c0/6d60206689ff0911f0ce968d40f163304a6c1bc739927758e6efc7921cfa630130388966f16bf6ef6b838cb33679fbe8e7a78a2f3c478afce841fd55ac8fb8ee + version: 10.5.0 + resolution: "decimal.js@npm:10.5.0" + checksum: 10c0/785c35279df32762143914668df35948920b6c1c259b933e0519a69b7003fc0a5ed2a766b1e1dda02574450c566b21738a45f15e274b47c2ac02072c0d1f3ac3 languageName: node linkType: hard @@ -5042,7 +5018,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -5192,14 +5168,14 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^3.1.0": - version: 3.1.0 - resolution: "domutils@npm:3.1.0" +"domutils@npm:^3.2.1": + version: 3.2.2 + resolution: "domutils@npm:3.2.2" dependencies: dom-serializer: "npm:^2.0.0" domelementtype: "npm:^2.3.0" domhandler: "npm:^5.0.3" - checksum: 10c0/342d64cf4d07b8a0573fb51e0a6312a88fb520c7fefd751870bf72fa5fc0f2e0cb9a3958a573610b1d608c6e2a69b8e9b4b40f0bfb8f87a71bce4f180cca1887 + checksum: 10c0/47938f473b987ea71cd59e59626eb8666d3aa8feba5266e45527f3b636c7883cca7e582d901531961f742c519d7514636b7973353b648762b2e3bedbf235fada languageName: node linkType: hard @@ -5235,10 +5211,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.41": - version: 1.5.45 - resolution: "electron-to-chromium@npm:1.5.45" - checksum: 10c0/f361ceda3bedcdc531ec0c060759c3487efd894d16a379beffe82a372fbeadcd1ac3cfc74a103b946dd2d12923a547289916743a609adaf68e5c4eef806e9e49 +"electron-to-chromium@npm:^1.5.73": + version: 1.5.92 + resolution: "electron-to-chromium@npm:1.5.92" + checksum: 10c0/336a3f5fea79cef2463c7e485e17d6c30e94155675cfb5b99478503c51c2603f7af79fe3969e72f5630d87b9097100690a0fb03b0d49a67b8a5e7aba03d79180 languageName: node linkType: hard @@ -5293,6 +5269,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^6.0.0": + version: 6.0.0 + resolution: "entities@npm:6.0.0" + checksum: 10c0/b82a7bd5de282860f3c36a91e815e41e874fd036c83956a568b82729678492eb088359d6f7e0a4f5c00776427263fcba04959b8340fefa430c39b9bce770427e + languageName: node + linkType: hard + "env-paths@npm:^2.2.0, env-paths@npm:^2.2.1": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -5316,61 +5299,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3": - version: 1.23.3 - resolution: "es-abstract@npm:1.23.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - arraybuffer.prototype.slice: "npm:^1.0.3" - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - data-view-buffer: "npm:^1.0.1" - data-view-byte-length: "npm:^1.0.1" - data-view-byte-offset: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-set-tostringtag: "npm:^2.0.3" - es-to-primitive: "npm:^1.2.1" - function.prototype.name: "npm:^1.1.6" - get-intrinsic: "npm:^1.2.4" - get-symbol-description: "npm:^1.0.2" - globalthis: "npm:^1.0.3" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.2" - internal-slot: "npm:^1.0.7" - is-array-buffer: "npm:^3.0.4" - is-callable: "npm:^1.2.7" - is-data-view: "npm:^1.0.1" - is-negative-zero: "npm:^2.0.3" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.3" - is-string: "npm:^1.0.7" - is-typed-array: "npm:^1.1.13" - is-weakref: "npm:^1.0.2" - object-inspect: "npm:^1.13.1" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.5" - regexp.prototype.flags: "npm:^1.5.2" - safe-array-concat: "npm:^1.1.2" - safe-regex-test: "npm:^1.0.3" - string.prototype.trim: "npm:^1.2.9" - string.prototype.trimend: "npm:^1.0.8" - string.prototype.trimstart: "npm:^1.0.8" - typed-array-buffer: "npm:^1.0.2" - typed-array-byte-length: "npm:^1.0.1" - typed-array-byte-offset: "npm:^1.0.2" - typed-array-length: "npm:^1.0.6" - unbox-primitive: "npm:^1.0.2" - which-typed-array: "npm:^1.1.15" - checksum: 10c0/d27e9afafb225c6924bee9971a7f25f20c314f2d6cb93a63cada4ac11dcf42040896a6c22e5fb8f2a10767055ed4ddf400be3b1eb12297d281726de470b75666 - languageName: node - linkType: hard - -"es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": version: 1.23.9 resolution: "es-abstract@npm:1.23.9" dependencies: @@ -5429,23 +5358,14 @@ __metadata: languageName: node linkType: hard -"es-define-property@npm:^1.0.0": - version: 1.0.0 - resolution: "es-define-property@npm:1.0.0" - dependencies: - get-intrinsic: "npm:^1.2.4" - checksum: 10c0/6bf3191feb7ea2ebda48b577f69bdfac7a2b3c9bcf97307f55fd6ef1bbca0b49f0c219a935aca506c993d8c5d8bddd937766cb760cd5e5a1071351f2df9f9aa4 - languageName: node - linkType: hard - -"es-define-property@npm:^1.0.1": +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": version: 1.0.1 resolution: "es-define-property@npm:1.0.1" checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c languageName: node linkType: hard -"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": +"es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 @@ -5477,26 +5397,15 @@ __metadata: linkType: hard "es-object-atoms@npm:^1.0.0": - version: 1.0.0 - resolution: "es-object-atoms@npm:1.0.0" + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" dependencies: es-errors: "npm:^1.3.0" - checksum: 10c0/1fed3d102eb27ab8d983337bb7c8b159dd2a1e63ff833ec54eea1311c96d5b08223b433060ba240541ca8adba9eee6b0a60cdbf2f80634b784febc9cc8b687b4 + checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c languageName: node linkType: hard -"es-set-tostringtag@npm:^2.0.3": - version: 2.0.3 - resolution: "es-set-tostringtag@npm:2.0.3" - dependencies: - get-intrinsic: "npm:^1.2.4" - has-tostringtag: "npm:^1.0.2" - hasown: "npm:^2.0.1" - checksum: 10c0/f22aff1585eb33569c326323f0b0d175844a1f11618b86e193b386f8be0ea9474cfbe46df39c45d959f7aa8f6c06985dc51dd6bce5401645ec5a74c4ceaa836a - languageName: node - linkType: hard - -"es-set-tostringtag@npm:^2.1.0": +"es-set-tostringtag@npm:^2.0.3, es-set-tostringtag@npm:^2.1.0": version: 2.1.0 resolution: "es-set-tostringtag@npm:2.1.0" dependencies: @@ -5508,7 +5417,7 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": +"es-shim-unscopables@npm:^1.0.2": version: 1.0.2 resolution: "es-shim-unscopables@npm:1.0.2" dependencies: @@ -5517,17 +5426,6 @@ __metadata: languageName: node linkType: hard -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: "npm:^1.1.4" - is-date-object: "npm:^1.0.1" - is-symbol: "npm:^1.0.2" - checksum: 10c0/0886572b8dc075cb10e50c0af62a03d03a68e1e69c388bd4f10c0649ee41b1fbb24840a1b7e590b393011b5cdbe0144b776da316762653685432df37d6de60f1 - languageName: node - linkType: hard - "es-to-primitive@npm:^1.3.0": version: 1.3.0 resolution: "es-to-primitive@npm:1.3.0" @@ -5546,35 +5444,35 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:0.24.2, esbuild@npm:^0.24.2": - version: 0.24.2 - resolution: "esbuild@npm:0.24.2" - dependencies: - "@esbuild/aix-ppc64": "npm:0.24.2" - "@esbuild/android-arm": "npm:0.24.2" - "@esbuild/android-arm64": "npm:0.24.2" - "@esbuild/android-x64": "npm:0.24.2" - "@esbuild/darwin-arm64": "npm:0.24.2" - "@esbuild/darwin-x64": "npm:0.24.2" - "@esbuild/freebsd-arm64": "npm:0.24.2" - "@esbuild/freebsd-x64": "npm:0.24.2" - "@esbuild/linux-arm": "npm:0.24.2" - "@esbuild/linux-arm64": "npm:0.24.2" - "@esbuild/linux-ia32": "npm:0.24.2" - "@esbuild/linux-loong64": "npm:0.24.2" - "@esbuild/linux-mips64el": "npm:0.24.2" - "@esbuild/linux-ppc64": "npm:0.24.2" - "@esbuild/linux-riscv64": "npm:0.24.2" - "@esbuild/linux-s390x": "npm:0.24.2" - "@esbuild/linux-x64": "npm:0.24.2" - "@esbuild/netbsd-arm64": "npm:0.24.2" - "@esbuild/netbsd-x64": "npm:0.24.2" - "@esbuild/openbsd-arm64": "npm:0.24.2" - "@esbuild/openbsd-x64": "npm:0.24.2" - "@esbuild/sunos-x64": "npm:0.24.2" - "@esbuild/win32-arm64": "npm:0.24.2" - "@esbuild/win32-ia32": "npm:0.24.2" - "@esbuild/win32-x64": "npm:0.24.2" +"esbuild@npm:0.25.0": + version: 0.25.0 + resolution: "esbuild@npm:0.25.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.0" + "@esbuild/android-arm": "npm:0.25.0" + "@esbuild/android-arm64": "npm:0.25.0" + "@esbuild/android-x64": "npm:0.25.0" + "@esbuild/darwin-arm64": "npm:0.25.0" + "@esbuild/darwin-x64": "npm:0.25.0" + "@esbuild/freebsd-arm64": "npm:0.25.0" + "@esbuild/freebsd-x64": "npm:0.25.0" + "@esbuild/linux-arm": "npm:0.25.0" + "@esbuild/linux-arm64": "npm:0.25.0" + "@esbuild/linux-ia32": "npm:0.25.0" + "@esbuild/linux-loong64": "npm:0.25.0" + "@esbuild/linux-mips64el": "npm:0.25.0" + "@esbuild/linux-ppc64": "npm:0.25.0" + "@esbuild/linux-riscv64": "npm:0.25.0" + "@esbuild/linux-s390x": "npm:0.25.0" + "@esbuild/linux-x64": "npm:0.25.0" + "@esbuild/netbsd-arm64": "npm:0.25.0" + "@esbuild/netbsd-x64": "npm:0.25.0" + "@esbuild/openbsd-arm64": "npm:0.25.0" + "@esbuild/openbsd-x64": "npm:0.25.0" + "@esbuild/sunos-x64": "npm:0.25.0" + "@esbuild/win32-arm64": "npm:0.25.0" + "@esbuild/win32-ia32": "npm:0.25.0" + "@esbuild/win32-x64": "npm:0.25.0" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -5628,7 +5526,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/5a25bb08b6ba23db6e66851828d848bd3ff87c005a48c02d83e38879058929878a6baa5a414e1141faee0d1dece3f32b5fbc2a87b82ed6a7aa857cf40359aeb5 + checksum: 10c0/5767b72da46da3cfec51661647ec850ddbf8a8d0662771139f10ef0692a8831396a0004b2be7966cecdb08264fb16bdc16290dcecd92396fac5f12d722fa013d languageName: node linkType: hard @@ -5712,6 +5610,92 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.24.2": + version: 0.24.2 + resolution: "esbuild@npm:0.24.2" + dependencies: + "@esbuild/aix-ppc64": "npm:0.24.2" + "@esbuild/android-arm": "npm:0.24.2" + "@esbuild/android-arm64": "npm:0.24.2" + "@esbuild/android-x64": "npm:0.24.2" + "@esbuild/darwin-arm64": "npm:0.24.2" + "@esbuild/darwin-x64": "npm:0.24.2" + "@esbuild/freebsd-arm64": "npm:0.24.2" + "@esbuild/freebsd-x64": "npm:0.24.2" + "@esbuild/linux-arm": "npm:0.24.2" + "@esbuild/linux-arm64": "npm:0.24.2" + "@esbuild/linux-ia32": "npm:0.24.2" + "@esbuild/linux-loong64": "npm:0.24.2" + "@esbuild/linux-mips64el": "npm:0.24.2" + "@esbuild/linux-ppc64": "npm:0.24.2" + "@esbuild/linux-riscv64": "npm:0.24.2" + "@esbuild/linux-s390x": "npm:0.24.2" + "@esbuild/linux-x64": "npm:0.24.2" + "@esbuild/netbsd-arm64": "npm:0.24.2" + "@esbuild/netbsd-x64": "npm:0.24.2" + "@esbuild/openbsd-arm64": "npm:0.24.2" + "@esbuild/openbsd-x64": "npm:0.24.2" + "@esbuild/sunos-x64": "npm:0.24.2" + "@esbuild/win32-arm64": "npm:0.24.2" + "@esbuild/win32-ia32": "npm:0.24.2" + "@esbuild/win32-x64": "npm:0.24.2" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/5a25bb08b6ba23db6e66851828d848bd3ff87c005a48c02d83e38879058929878a6baa5a414e1141faee0d1dece3f32b5fbc2a87b82ed6a7aa857cf40359aeb5 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -5726,13 +5710,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.5": - version: 1.0.5 - resolution: "escape-string-regexp@npm:1.0.5" - checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 - languageName: node - linkType: hard - "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -5883,12 +5860,12 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-refresh@npm:0.4.18": - version: 0.4.18 - resolution: "eslint-plugin-react-refresh@npm:0.4.18" +"eslint-plugin-react-refresh@npm:0.4.19": + version: 0.4.19 + resolution: "eslint-plugin-react-refresh@npm:0.4.19" peerDependencies: eslint: ">=8.40" - checksum: 10c0/19140a0d90e126c198c07337bc106af24f398dd8f061314f42c17511a647bea93880a11b7d40219088ac0eaea598eb591d320cfc6f82262bfb05f602101b2acc + checksum: 10c0/7c19c864c5fb1292dd1c9df2ce73cb1f86457937975d108e8619d6f354855d838d3f56f0262ce5cd541a7087de103ad802a32906e13724ea1b93c6e3b6477708 languageName: node linkType: hard @@ -5939,20 +5916,13 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0": +"eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.1.0": - version: 4.1.0 - resolution: "eslint-visitor-keys@npm:4.1.0" - checksum: 10c0/5483ef114c93a136aa234140d7aa3bd259488dae866d35cb0d0b52e6a158f614760a57256ac8d549acc590a87042cb40f6951815caa821e55dc4fd6ef4c722eb - languageName: node - linkType: hard - "eslint-visitor-keys@npm:^4.2.0": version: 4.2.0 resolution: "eslint-visitor-keys@npm:4.2.0" @@ -5960,16 +5930,16 @@ __metadata: languageName: node linkType: hard -"eslint@npm:9.19.0": - version: 9.19.0 - resolution: "eslint@npm:9.19.0" +"eslint@npm:9.20.0": + version: 9.20.0 + resolution: "eslint@npm:9.20.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.12.1" "@eslint/config-array": "npm:^0.19.0" - "@eslint/core": "npm:^0.10.0" + "@eslint/core": "npm:^0.11.0" "@eslint/eslintrc": "npm:^3.2.0" - "@eslint/js": "npm:9.19.0" + "@eslint/js": "npm:9.20.0" "@eslint/plugin-kit": "npm:^0.2.5" "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" @@ -6005,22 +5975,11 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/3b0dfaeff6a831de086884a3e2432f18468fe37c69f35e1a0a9a2833d9994a65b6dd2a524aaee28f361c849035ad9d15e3841029b67d261d0abd62c7de6d51f5 + checksum: 10c0/5eb2d9b5ed85a0b022871d19719417d110afb07a4abfedd856ad03d9a821def5f6bc31d7c407ca27f56e5e66e39375300fd2b877017245eb99c44060d6c983bd languageName: node linkType: hard -"espree@npm:^10.0.1": - version: 10.2.0 - resolution: "espree@npm:10.2.0" - dependencies: - acorn: "npm:^8.12.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.1.0" - checksum: 10c0/2b6bfb683e7e5ab2e9513949879140898d80a2d9867ea1db6ff5b0256df81722633b60a7523a7c614f05a39aeea159dd09ad2a0e90c0e218732fc016f9086215 - languageName: node - linkType: hard - -"espree@npm:^10.3.0": +"espree@npm:^10.0.1, espree@npm:^10.3.0": version: 10.3.0 resolution: "espree@npm:10.3.0" dependencies: @@ -6107,9 +6066,9 @@ __metadata: languageName: node linkType: hard -"express@npm:4.21.1": - version: 4.21.1 - resolution: "express@npm:4.21.1" +"express@npm:4.21.2": + version: 4.21.2 + resolution: "express@npm:4.21.2" dependencies: accepts: "npm:~1.3.8" array-flatten: "npm:1.1.1" @@ -6130,7 +6089,7 @@ __metadata: methods: "npm:~1.1.2" on-finished: "npm:2.4.1" parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.10" + path-to-regexp: "npm:0.1.12" proxy-addr: "npm:~2.0.7" qs: "npm:6.13.0" range-parser: "npm:~1.2.1" @@ -6142,7 +6101,7 @@ __metadata: type-is: "npm:~1.6.18" utils-merge: "npm:1.0.1" vary: "npm:~1.1.2" - checksum: 10c0/0c287867e5f6129d3def1edd9b63103a53c40d4dc8628839d4b6827e35eb8f0de5a4656f9d85f4457eba584f9871ebb2ad26c750b36bd75d9bbb8bcebdc4892c + checksum: 10c0/38168fd0a32756600b56e6214afecf4fc79ec28eca7f7a91c2ab8d50df4f47562ca3f9dee412da7f5cea6b1a1544b33b40f9f8586dbacfbdada0fe90dbb10a1f languageName: node linkType: hard @@ -6161,15 +6120,15 @@ __metadata: linkType: hard "fast-glob@npm:^3.3.2": - version: 3.3.2 - resolution: "fast-glob@npm:3.3.2" + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" dependencies: "@nodelib/fs.stat": "npm:^2.0.2" "@nodelib/fs.walk": "npm:^1.2.3" glob-parent: "npm:^5.1.2" merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845 + micromatch: "npm:^4.0.8" + checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe languageName: node linkType: hard @@ -6195,11 +6154,11 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.17.1 - resolution: "fastq@npm:1.17.1" + version: 1.19.0 + resolution: "fastq@npm:1.19.0" dependencies: reusify: "npm:^1.0.4" - checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 + checksum: 10c0/d6a001638f1574a696660fcbba5300d017760432372c801632c325ca7c16819604841c92fd3ccadcdacec0966ca336363a5ff57bc5f0be335d8ea7ac6087b98f languageName: node linkType: hard @@ -6300,9 +6259,9 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.1 - resolution: "flatted@npm:3.3.1" - checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf + version: 3.3.2 + resolution: "flatted@npm:3.3.2" + checksum: 10c0/24cc735e74d593b6c767fe04f2ef369abe15b62f6906158079b9874bdb3ee5ae7110bb75042e70cd3f99d409d766f357caf78d5ecee9780206f5fdc5edbad334 languageName: node linkType: hard @@ -6317,11 +6276,11 @@ __metadata: linkType: hard "for-each@npm:^0.3.3": - version: 0.3.3 - resolution: "for-each@npm:0.3.3" + version: 0.3.4 + resolution: "for-each@npm:0.3.4" dependencies: - is-callable: "npm:^1.1.3" - checksum: 10c0/22330d8a2db728dbf003ec9182c2d421fbcd2969b02b4f97ec288721cda63eb28f2c08585ddccd0f77cb2930af8d958005c9e72f47141dc51816127a118f39aa + is-callable: "npm:^1.2.7" + checksum: 10c0/6b2016c0a0fe3107c70a233923cac74f07bedb5a1847636039fa6bcc3df09aefa554cfec23c3342ad365acac1f95e799d9f8e220cb82a4c7b8a84f969234302f languageName: node linkType: hard @@ -6378,15 +6337,6 @@ __metadata: languageName: node linkType: hard -"fs-minipass@npm:^2.0.0": - version: 2.1.0 - resolution: "fs-minipass@npm:2.1.0" - dependencies: - minipass: "npm:^3.0.0" - checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 - languageName: node - linkType: hard - "fs-minipass@npm:^3.0.0": version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" @@ -6441,19 +6391,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.6": - version: 1.1.6 - resolution: "function.prototype.name@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - functions-have-names: "npm:^1.2.3" - checksum: 10c0/9eae11294905b62cb16874adb4fc687927cda3162285e0ad9612e6a1d04934005d46907362ea9cdb7428edce05a2f2c3dabc3b2d21e9fd343e9bb278230ad94b - languageName: node - linkType: hard - -"function.prototype.name@npm:^1.1.8": +"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": version: 1.1.8 resolution: "function.prototype.name@npm:1.1.8" dependencies: @@ -6488,20 +6426,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": - version: 1.2.4 - resolution: "get-intrinsic@npm:1.2.4" - dependencies: - es-errors: "npm:^1.3.0" - function-bind: "npm:^1.1.2" - has-proto: "npm:^1.0.1" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.0" - checksum: 10c0/0a9b82c16696ed6da5e39b1267104475c47e3a9bdbe8b509dfe1710946e38a87be70d759f4bb3cda042d76a41ef47fe769660f3b7c0d1f68750299344ffb15b7 - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7": +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7": version: 1.2.7 resolution: "get-intrinsic@npm:1.2.7" dependencies: @@ -6529,17 +6454,6 @@ __metadata: languageName: node linkType: hard -"get-symbol-description@npm:^1.0.2": - version: 1.0.2 - resolution: "get-symbol-description@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.5" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - checksum: 10c0/867be6d63f5e0eb026cb3b0ef695ec9ecf9310febb041072d2e142f260bd91ced9eeb426b3af98791d1064e324e653424afa6fd1af17dee373bea48ae03162bc - languageName: node - linkType: hard - "get-symbol-description@npm:^1.1.0": version: 1.1.0 resolution: "get-symbol-description@npm:1.1.0" @@ -6576,7 +6490,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10": +"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -6622,7 +6536,7 @@ __metadata: languageName: node linkType: hard -"globalthis@npm:^1.0.3, globalthis@npm:^1.0.4": +"globalthis@npm:^1.0.4": version: 1.0.4 resolution: "globalthis@npm:1.0.4" dependencies: @@ -6632,16 +6546,7 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.0.1": - version: 1.0.1 - resolution: "gopd@npm:1.0.1" - dependencies: - get-intrinsic: "npm:^1.1.3" - checksum: 10c0/505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63 - languageName: node - linkType: hard - -"gopd@npm:^1.2.0": +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead @@ -6662,17 +6567,10 @@ __metadata: languageName: node linkType: hard -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 10c0/724eb1485bfa3cdff6f18d95130aa190561f00b3fcf9f19dc640baf8176b5917c143b81ec2123f8cddb6c05164a198c94b13e1377c497705ccc8e1a80306e83b - languageName: node - linkType: hard - -"has-flag@npm:^3.0.0": - version: 3.0.0 - resolution: "has-flag@npm:3.0.0" - checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 +"has-bigints@npm:^1.0.2": + version: 1.1.0 + resolution: "has-bigints@npm:1.1.0" + checksum: 10c0/2de0cdc4a1ccf7a1e75ffede1876994525ac03cc6f5ae7392d3415dd475cd9eee5bceec63669ab61aa997ff6cceebb50ef75561c7002bed8988de2b9d1b40788 languageName: node linkType: hard @@ -6692,13 +6590,6 @@ __metadata: languageName: node linkType: hard -"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": - version: 1.0.3 - resolution: "has-proto@npm:1.0.3" - checksum: 10c0/35a6989f81e9f8022c2f4027f8b48a552de714938765d019dbea6bb547bd49ce5010a3c7c32ec6ddac6e48fc546166a3583b128f5a7add8b058a6d8b4afec205 - languageName: node - linkType: hard - "has-proto@npm:^1.2.0": version: 1.2.0 resolution: "has-proto@npm:1.2.0" @@ -6708,21 +6599,14 @@ __metadata: languageName: node linkType: hard -"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 - languageName: node - linkType: hard - -"has-symbols@npm:^1.1.0": +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": +"has-tostringtag@npm:^1.0.2": version: 1.0.2 resolution: "has-tostringtag@npm:1.0.2" dependencies: @@ -6731,7 +6615,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": +"hasown@npm:^2.0.0, hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -6755,18 +6639,18 @@ __metadata: linkType: hard "hast-util-from-parse5@npm:^8.0.0": - version: 8.0.1 - resolution: "hast-util-from-parse5@npm:8.0.1" + version: 8.0.2 + resolution: "hast-util-from-parse5@npm:8.0.2" dependencies: "@types/hast": "npm:^3.0.0" "@types/unist": "npm:^3.0.0" devlop: "npm:^1.0.0" - hastscript: "npm:^8.0.0" + hastscript: "npm:^9.0.0" property-information: "npm:^6.0.0" vfile: "npm:^6.0.0" vfile-location: "npm:^5.0.0" web-namespaces: "npm:^2.0.0" - checksum: 10c0/4a30bb885cff1f0e023c429ae3ece73fe4b03386f07234bf23f5555ca087c2573ff4e551035b417ed7615bde559f394cdaf1db2b91c3b7f0575f3563cd238969 + checksum: 10c0/921f40d7bd71fe7415b68df5e2d53ba62f0a35808be0504fa24584e6f6a85bfbf14dc20d171c7ccc1cf84058bcc445d12a746598d324cece1ec1e52ea9d489af languageName: node linkType: hard @@ -6823,8 +6707,8 @@ __metadata: linkType: hard "hast-util-raw@npm:^9.0.0": - version: 9.0.4 - resolution: "hast-util-raw@npm:9.0.4" + version: 9.1.0 + resolution: "hast-util-raw@npm:9.1.0" dependencies: "@types/hast": "npm:^3.0.0" "@types/unist": "npm:^3.0.0" @@ -6839,7 +6723,7 @@ __metadata: vfile: "npm:^6.0.0" web-namespaces: "npm:^2.0.0" zwitch: "npm:^2.0.0" - checksum: 10c0/03d0fe7ba8bd75c9ce81f829650b19b78917bbe31db70d36bf6f136842496c3474e3bb1841f2d30dafe1f6b561a89a524185492b9a93d40b131000743c0d7998 + checksum: 10c0/d0d909d2aedecef6a06f0005cfae410d6475e6e182d768bde30c3af9fcbbe4f9beb0522bdc21d0679cb3c243c0df40385797ed255148d68b3d3f12e82d12aacc languageName: node linkType: hard @@ -6867,8 +6751,8 @@ __metadata: linkType: hard "hast-util-to-html@npm:^9.0.0": - version: 9.0.3 - resolution: "hast-util-to-html@npm:9.0.3" + version: 9.0.4 + resolution: "hast-util-to-html@npm:9.0.4" dependencies: "@types/hast": "npm:^3.0.0" "@types/unist": "npm:^3.0.0" @@ -6881,7 +6765,7 @@ __metadata: space-separated-tokens: "npm:^2.0.0" stringify-entities: "npm:^4.0.0" zwitch: "npm:^2.0.4" - checksum: 10c0/af938a03034727f6c944d3855732d72f71a3bcd920d36b9ba3e083df2217faf81713740934db64673aca69d76b60abe80052e47c0702323fd0bd5dce03b67b8d + checksum: 10c0/5eba69554c41d036105b9cedd61df26fd9046b64172aa6b61c143c8c539b43fe27bc7e04e50099564e5a3a501aa6c6719620365120eedf1b09eca51cb8b4dc40 languageName: node linkType: hard @@ -6967,16 +6851,16 @@ __metadata: languageName: node linkType: hard -"hastscript@npm:^8.0.0": - version: 8.0.0 - resolution: "hastscript@npm:8.0.0" +"hastscript@npm:^9.0.0": + version: 9.0.0 + resolution: "hastscript@npm:9.0.0" dependencies: "@types/hast": "npm:^3.0.0" comma-separated-tokens: "npm:^2.0.0" hast-util-parse-selector: "npm:^4.0.0" property-information: "npm:^6.0.0" space-separated-tokens: "npm:^2.0.0" - checksum: 10c0/f0b54bbdd710854b71c0f044612db0fe1b5e4d74fa2001633dc8c535c26033269f04f536f9fd5b03f234de1111808f9e230e9d19493bf919432bb24d541719e0 + checksum: 10c0/66eff826846c55482052ebbc99b6881c14aff6421526634f4c95318ba1d0d1f1bbf5aa38446f388943c0f32d5383fa38740c972b37678dd1cd0c82e6e5807fbf languageName: node linkType: hard @@ -6994,7 +6878,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:3, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:3, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -7003,13 +6887,13 @@ __metadata: languageName: node linkType: hard -"html-dom-parser@npm:5.0.11": - version: 5.0.11 - resolution: "html-dom-parser@npm:5.0.11" +"html-dom-parser@npm:5.0.13": + version: 5.0.13 + resolution: "html-dom-parser@npm:5.0.13" dependencies: domhandler: "npm:5.0.3" - htmlparser2: "npm:9.1.0" - checksum: 10c0/752c962663d9873d90d15d1c0b5721dd16816b2ee307b660e5d579d962674d9aec10d7b532607349df21a6ee8c0f308821480b1fe664fbefad76fe94ca96d086 + htmlparser2: "npm:10.0.0" + checksum: 10c0/9ab49dce1c0708d6f91a495f5bbec397233653c0427ec3f60f8a00db6f44600a4363fe1d5e23c0282a2164de28d0209602dd899d8b35e1f9f78c21682a121807 languageName: node linkType: hard @@ -7029,12 +6913,12 @@ __metadata: languageName: node linkType: hard -"html-react-parser@npm:5.2.0": - version: 5.2.0 - resolution: "html-react-parser@npm:5.2.0" +"html-react-parser@npm:5.2.2": + version: 5.2.2 + resolution: "html-react-parser@npm:5.2.2" dependencies: domhandler: "npm:5.0.3" - html-dom-parser: "npm:5.0.11" + html-dom-parser: "npm:5.0.13" react-property: "npm:2.0.2" style-to-js: "npm:1.1.16" peerDependencies: @@ -7043,7 +6927,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/7c70ce8c5557a32c944a6408ef058f47369923e7d618c6713b7c3f2b90ace39bcdae52e6728119383c3ee582969e779189a4f3ea0116f2451f87f446ef476553 + checksum: 10c0/f757476308831afeba42698c83213045ce83a94577788217022528f9b52dfd2a5076f0f77acf0927ba97c2c695423c6898cef8e162134d7d1ceadc150f80b730 languageName: node linkType: hard @@ -7068,15 +6952,15 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:9.1.0": - version: 9.1.0 - resolution: "htmlparser2@npm:9.1.0" +"htmlparser2@npm:10.0.0": + version: 10.0.0 + resolution: "htmlparser2@npm:10.0.0" dependencies: domelementtype: "npm:^2.3.0" domhandler: "npm:^5.0.3" - domutils: "npm:^3.1.0" - entities: "npm:^4.5.0" - checksum: 10c0/394f6323efc265bbc791d8c0d96bfe95984e0407565248521ab92e2dc7668e5ceeca7bc6ed18d408b9ee3b25032c5743368a4280d280332d782821d5d467ad8f + domutils: "npm:^3.2.1" + entities: "npm:^6.0.0" + checksum: 10c0/47cfa37e529c86a7ba9a1e0e6f951ad26ef8ca5af898ab6e8916fa02c0264c1453b4a65f28b7b8a7f9d0d29b5a70abead8203bf8b3f07bc69407e85e7d9a68e4 languageName: node linkType: hard @@ -7166,19 +7050,12 @@ __metadata: linkType: hard "https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.5": - version: 7.0.5 - resolution: "https-proxy-agent@npm:7.0.5" + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" dependencies: - agent-base: "npm:^7.0.2" + agent-base: "npm:^7.1.2" debug: "npm:4" - checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c - languageName: node - linkType: hard - -"hyphenate-style-name@npm:^1.0.3": - version: 1.1.0 - resolution: "hyphenate-style-name@npm:1.1.0" - checksum: 10c0/bfe88deac2414a41a0d08811e277c8c098f23993d6a1eb17f14a0f11b54c4d42865a63d3cfe1914668eefb9a188e2de58f38b55a179a238fd1fef606893e194f + checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac languageName: node linkType: hard @@ -7215,12 +7092,12 @@ __metadata: linkType: hard "import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" + version: 3.3.1 + resolution: "import-fresh@npm:3.3.1" dependencies: parent-module: "npm:^1.0.0" resolve-from: "npm:^4.0.0" - checksum: 10c0/7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 + checksum: 10c0/bf8cc494872fef783249709385ae883b447e3eb09db0ebd15dcead7d9afe7224dad7bd7591c6b73b0b19b3c0f9640eb8ee884f01cfaf2887ab995b0b36a0cbec languageName: node linkType: hard @@ -7231,13 +7108,6 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f - languageName: node - linkType: hard - "inherits@npm:2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" @@ -7252,17 +7122,6 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.7": - version: 1.0.7 - resolution: "internal-slot@npm:1.0.7" - dependencies: - es-errors: "npm:^1.3.0" - hasown: "npm:^2.0.0" - side-channel: "npm:^1.0.4" - checksum: 10c0/f8b294a4e6ea3855fc59551bbf35f2b832cf01fd5e6e2a97f5c201a071cc09b49048f856e484b67a6c721da5e55736c5b6ddafaf19e2dbeb4a3ff1821680de6c - languageName: node - linkType: hard - "internal-slot@npm:^1.1.0": version: 1.1.0 resolution: "internal-slot@npm:1.1.0" @@ -7274,15 +7133,15 @@ __metadata: languageName: node linkType: hard -"intl-messageformat@npm:10.7.11": - version: 10.7.11 - resolution: "intl-messageformat@npm:10.7.11" +"intl-messageformat@npm:10.7.15": + version: 10.7.15 + resolution: "intl-messageformat@npm:10.7.15" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.2" + "@formatjs/ecma402-abstract": "npm:2.3.3" "@formatjs/fast-memoize": "npm:2.2.6" - "@formatjs/icu-messageformat-parser": "npm:2.9.8" + "@formatjs/icu-messageformat-parser": "npm:2.11.1" tslib: "npm:2" - checksum: 10c0/7ccd972277cc6798038af876c830203084db6552becfa99c3706541fd67838552013f57f8ed0ed3aed03d4fba436591a83a25f913365d66ad04ee9332eee7b73 + checksum: 10c0/5759cd38718b7e4874fd6eb5e759e920227f993bdf17d71cd7474919098aafc13c8bbc63f5ccb2bafe13093f3a519fd7a03a47efc84bb3e9fbf9f25f88a408c9 languageName: node linkType: hard @@ -7338,26 +7197,16 @@ __metadata: linkType: hard "is-arguments@npm:^1.1.1": - version: 1.1.1 - resolution: "is-arguments@npm:1.1.1" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/5ff1f341ee4475350adfc14b2328b38962564b7c2076be2f5bac7bd9b61779efba99b9f844a7b82ba7654adccf8e8eb19d1bb0cc6d1c1a085e498f6793d4328f - languageName: node - linkType: hard - -"is-array-buffer@npm:^3.0.4": - version: 3.0.4 - resolution: "is-array-buffer@npm:3.0.4" + version: 1.2.0 + resolution: "is-arguments@npm:1.2.0" dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.1" - checksum: 10c0/42a49d006cc6130bc5424eae113e948c146f31f9d24460fc0958f855d9d810e6fd2e4519bf19aab75179af9c298ea6092459d8cafdec523cd19e529b26eab860 + call-bound: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/6377344b31e9fcb707c6751ee89b11f132f32338e6a782ec2eac9393b0cbd32235dad93052998cda778ee058754860738341d8114910d50ada5615912bb929fc languageName: node linkType: hard -"is-array-buffer@npm:^3.0.5": +"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": version: 3.0.5 resolution: "is-array-buffer@npm:3.0.5" dependencies: @@ -7376,20 +7225,15 @@ __metadata: linkType: hard "is-async-function@npm:^2.0.0": - version: 2.0.0 - resolution: "is-async-function@npm:2.0.0" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/787bc931576aad525d751fc5ce211960fe91e49ac84a5c22d6ae0bc9541945fbc3f686dc590c3175722ce4f6d7b798a93f6f8ff4847fdb2199aea6f4baf5d668 - languageName: node - linkType: hard - -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" dependencies: - has-bigints: "npm:^1.0.1" - checksum: 10c0/eb9c88e418a0d195ca545aff2b715c9903d9b0a5033bc5922fec600eb0c3d7b1ee7f882dbf2e0d5a6e694e42391be3683e4368737bd3c4a77f8ac293e7773696 + async-function: "npm:^1.0.0" + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10c0/d70c236a5e82de6fc4d44368ffd0c2fee2b088b893511ce21e679da275a5ecc6015ff59a7d7e1bdd7ca39f71a8dbdd253cf8cce5c6b3c91cdd5b42b5ce677298 languageName: node linkType: hard @@ -7402,52 +7246,33 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/6090587f8a8a8534c0f816da868bc94f32810f08807aa72fa7e79f7e11c466d281486ffe7a788178809c2aa71fe3e700b167fe80dd96dad68026bfff8ebf39f7 - languageName: node - linkType: hard - "is-boolean-object@npm:^1.2.1": - version: 1.2.1 - resolution: "is-boolean-object@npm:1.2.1" + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" dependencies: - call-bound: "npm:^1.0.2" + call-bound: "npm:^1.0.3" has-tostringtag: "npm:^1.0.2" - checksum: 10c0/2ef601d255a39fdbde79cfe6be80c27b47430ed6712407f29b17d002e20f64c1e3d6692f1d842ba16bf1e9d8ddf1c4f13cac3ed7d9a4a21290f44879ebb4e8f5 + checksum: 10c0/36ff6baf6bd18b3130186990026f5a95c709345c39cd368468e6c1b6ab52201e9fd26d8e1f4c066357b4938b0f0401e1a5000e08257787c1a02f3a719457001e languageName: node linkType: hard -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": +"is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1": - version: 2.15.1 - resolution: "is-core-module@npm:2.15.1" +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1, is-core-module@npm:^2.16.0": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" dependencies: hasown: "npm:^2.0.2" - checksum: 10c0/53432f10c69c40bfd2fa8914133a68709ff9498c86c3bf5fca3cdf3145a56fd2168cbf4a43b29843a6202a120a5f9c5ffba0a4322e1e3441739bc0b641682612 - languageName: node - linkType: hard - -"is-data-view@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-view@npm:1.0.1" - dependencies: - is-typed-array: "npm:^1.1.13" - checksum: 10c0/a3e6ec84efe303da859107aed9b970e018e2bee7ffcb48e2f8096921a493608134240e672a2072577e5f23a729846241d9634806e8a0e51d9129c56d5f65442d + checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd languageName: node linkType: hard -"is-data-view@npm:^1.0.2": +"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": version: 1.0.2 resolution: "is-data-view@npm:1.0.2" dependencies: @@ -7458,16 +7283,7 @@ __metadata: languageName: node linkType: hard -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/eed21e5dcc619c48ccef804dfc83a739dbb2abee6ca202838ee1bd5f760fe8d8a93444f0d49012ad19bb7c006186e2884a1b92f6e1c056da7fd23d0a9ad5992e - languageName: node - linkType: hard - -"is-date-object@npm:^1.1.0": +"is-date-object@npm:^1.0.5, is-date-object@npm:^1.1.0": version: 1.1.0 resolution: "is-date-object@npm:1.1.0" dependencies: @@ -7515,11 +7331,14 @@ __metadata: linkType: hard "is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": - version: 1.0.10 - resolution: "is-generator-function@npm:1.0.10" + version: 1.1.0 + resolution: "is-generator-function@npm:1.1.0" dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/df03514df01a6098945b5a0cfa1abff715807c8e72f57c49a0686ad54b3b74d394e2d8714e6f709a71eb00c9630d48e73ca1796c1ccc84ac95092c1fecc0d98b + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.0" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10c0/fdfa96c8087bf36fc4cd514b474ba2ff404219a4dd4cfa6cf5426404a1eed259bdcdb98f082a71029a48d01f27733e3436ecc6690129a7ec09cb0434bee03a2a languageName: node linkType: hard @@ -7546,20 +7365,6 @@ __metadata: languageName: node linkType: hard -"is-in-browser@npm:^1.0.2, is-in-browser@npm:^1.1.3": - version: 1.1.3 - resolution: "is-in-browser@npm:1.1.3" - checksum: 10c0/87e6119a56ec3d84910eb6ad855b4a3ac05b242fc2bc2c28abbf978f76b5a834ec5622165035acaf2844a85856b1a0fbc12bd0cb1ce9e86314ebec675c6fe856 - languageName: node - linkType: hard - -"is-lambda@npm:^1.0.1": - version: 1.0.1 - resolution: "is-lambda@npm:1.0.1" - checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d - languageName: node - linkType: hard - "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -7567,22 +7372,6 @@ __metadata: languageName: node linkType: hard -"is-negative-zero@npm:^2.0.3": - version: 2.0.3 - resolution: "is-negative-zero@npm:2.0.3" - checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e - languageName: node - linkType: hard - -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/aad266da1e530f1804a2b7bd2e874b4869f71c98590b3964f9d06cc9869b18f8d1f4778f838ecd2a11011bce20aeecb53cb269ba916209b79c24580416b74b1b - languageName: node - linkType: hard - "is-number-object@npm:^1.1.1": version: 1.1.1 resolution: "is-number-object@npm:1.1.1" @@ -7621,17 +7410,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.1.4": - version: 1.1.4 - resolution: "is-regex@npm:1.1.4" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/bb72aae604a69eafd4a82a93002058c416ace8cde95873589a97fc5dac96a6c6c78a9977d487b7b95426a8f5073969124dd228f043f9f604f041f32fcc465fc1 - languageName: node - linkType: hard - -"is-regex@npm:^1.2.1": +"is-regex@npm:^1.1.4, is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" dependencies: @@ -7650,15 +7429,6 @@ __metadata: languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "is-shared-array-buffer@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - checksum: 10c0/adc11ab0acbc934a7b9e5e9d6c588d4ec6682f6fea8cda5180721704fa32927582ede5b123349e32517fdadd07958973d24716c80e7ab198970c47acc09e59c7 - languageName: node - linkType: hard - "is-shared-array-buffer@npm:^1.0.4": version: 1.0.4 resolution: "is-shared-array-buffer@npm:1.0.4" @@ -7668,16 +7438,7 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10c0/905f805cbc6eedfa678aaa103ab7f626aac9ebbdc8737abb5243acaa61d9820f8edc5819106b8fcd1839e33db21de9f0116ae20de380c8382d16dc2a601921f6 - languageName: node - linkType: hard - -"is-string@npm:^1.1.1": +"is-string@npm:^1.0.7, is-string@npm:^1.1.1": version: 1.1.1 resolution: "is-string@npm:1.1.1" dependencies: @@ -7687,15 +7448,6 @@ __metadata: languageName: node linkType: hard -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" - dependencies: - has-symbols: "npm:^1.0.2" - checksum: 10c0/9381dd015f7c8906154dbcbf93fad769de16b4b961edc94f88d26eb8c555935caa23af88bda0c93a18e65560f6d7cca0fd5a3f8a8e1df6f1abbb9bead4502ef7 - languageName: node - linkType: hard - "is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": version: 1.1.1 resolution: "is-symbol@npm:1.1.1" @@ -7707,16 +7459,7 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.13": - version: 1.1.13 - resolution: "is-typed-array@npm:1.1.13" - dependencies: - which-typed-array: "npm:^1.1.14" - checksum: 10c0/fa5cb97d4a80e52c2cc8ed3778e39f175a1a2ae4ddf3adae3187d69586a1fd57cfa0b095db31f66aa90331e9e3da79184cea9c6abdcd1abc722dc3c3edd51cca - languageName: node - linkType: hard - -"is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": version: 1.1.15 resolution: "is-typed-array@npm:1.1.15" dependencies: @@ -7732,16 +7475,7 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - checksum: 10c0/1545c5d172cb690c392f2136c23eec07d8d78a7f57d0e41f10078aa4f5daf5d7f57b6513a67514ab4f073275ad00c9822fc8935e00229d0a2089e1c02685d4b1 - languageName: node - linkType: hard - -"is-weakref@npm:^1.1.0": +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.0": version: 1.1.1 resolution: "is-weakref@npm:1.1.1" dependencies: @@ -7751,12 +7485,12 @@ __metadata: linkType: hard "is-weakset@npm:^2.0.3": - version: 2.0.3 - resolution: "is-weakset@npm:2.0.3" + version: 2.0.4 + resolution: "is-weakset@npm:2.0.4" dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - checksum: 10c0/8ad6141b6a400e7ce7c7442a13928c676d07b1f315ab77d9912920bf5f4170622f43126f111615788f26c3b1871158a6797c862233124507db0bcc33a9537d1a + call-bound: "npm:^1.0.3" + get-intrinsic: "npm:^1.2.6" + checksum: 10c0/6491eba08acb8dc9532da23cb226b7d0192ede0b88f16199e592e4769db0a077119c1f5d2283d1e0d16d739115f70046e887e477eb0e66cd90e1bb29f28ba647 languageName: node linkType: hard @@ -7903,11 +7637,11 @@ __metadata: linkType: hard "jsesc@npm:^3.0.2": - version: 3.0.2 - resolution: "jsesc@npm:3.0.2" + version: 3.1.0 + resolution: "jsesc@npm:3.1.0" bin: jsesc: bin/jsesc - checksum: 10c0/ef22148f9e793180b14d8a145ee6f9f60f301abf443288117b4b6c53d0ecd58354898dc506ccbb553a5f7827965cd38bc5fb726575aae93c5e8915e2de8290e1 + checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1 languageName: node linkType: hard @@ -7972,92 +7706,6 @@ __metadata: languageName: node linkType: hard -"jss-plugin-camel-case@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-camel-case@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - hyphenate-style-name: "npm:^1.0.3" - jss: "npm:10.10.0" - checksum: 10c0/29dedf0866837425258eae3b12b72c1de435ea7caddef94ac13044b3a04c4abd8dd238a81fd6e0a4afdbf10c9cb4674df41f50af79554c34c736cd2ecf3752da - languageName: node - linkType: hard - -"jss-plugin-default-unit@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-default-unit@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - jss: "npm:10.10.0" - checksum: 10c0/f394d5411114fde7056249f4650de51e6f3e47c64a3d48cee80180a6e75876f0d0d68c96d81458880e1024ca880ed53baade682d36a5f7177046bfef0b280572 - languageName: node - linkType: hard - -"jss-plugin-global@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-global@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - jss: "npm:10.10.0" - checksum: 10c0/2d24ef0e16cd6ebcce59f132756716ae37fdffe3f59461018636a57ef68298e649f43bd5c346041f1642872aa2cc0629f5ecfb48a20bfb471813318cb8f3935f - languageName: node - linkType: hard - -"jss-plugin-nested@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-nested@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - jss: "npm:10.10.0" - tiny-warning: "npm:^1.0.2" - checksum: 10c0/868ac4e4bea9dc02fac33f15e3165c008669d69e6b87201f1d8574eb213408b67366302288b49f46acda1320164460daa50e6aac817d34ae3b1c256a03f4ebba - languageName: node - linkType: hard - -"jss-plugin-props-sort@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-props-sort@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - jss: "npm:10.10.0" - checksum: 10c0/5579bb21bfe514c12f43bd5e57458badc37c8e5676a47109f45195466a3aed633c61609daef079622421ef7c902b8342d1f96578543fefcb729f0b8dcfd2fe37 - languageName: node - linkType: hard - -"jss-plugin-rule-value-function@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-rule-value-function@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - jss: "npm:10.10.0" - tiny-warning: "npm:^1.0.2" - checksum: 10c0/678bedb49da3b5e93fc1971d691f7f3ad2d7cf15dfc220edab934b70c7571fc383a435371a687a8ae125ab5ccd7bada9712574620959a3d1cd961fbca1583c29 - languageName: node - linkType: hard - -"jss-plugin-vendor-prefixer@npm:^10.10.0": - version: 10.10.0 - resolution: "jss-plugin-vendor-prefixer@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - css-vendor: "npm:^2.0.8" - jss: "npm:10.10.0" - checksum: 10c0/e3ad2dfe93d126f722586782aebddcd68dc46c0ad59f99edd65e164ecbb6e4cad6ce85c874f90553fa5fec50c2fd2b1f5984abfc4e3dd49d24033bbc378a2e11 - languageName: node - linkType: hard - -"jss@npm:10.10.0, jss@npm:^10.10.0": - version: 10.10.0 - resolution: "jss@npm:10.10.0" - dependencies: - "@babel/runtime": "npm:^7.3.1" - csstype: "npm:^3.0.2" - is-in-browser: "npm:^1.1.3" - tiny-warning: "npm:^1.0.2" - checksum: 10c0/aa5e743a3f40d6df05ae951c6913b6495ef42b3e9539f6875c32bf01c42ab405bd91038d6feca2ed5c67a2947111b0137213983089e2a310ee11fc563208ad61 - languageName: node - linkType: hard - "jsx-ast-utils@npm:^2.4.1 || ^3.0.0": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -8223,9 +7871,9 @@ __metadata: linkType: hard "loupe@npm:^3.1.0, loupe@npm:^3.1.1": - version: 3.1.2 - resolution: "loupe@npm:3.1.2" - checksum: 10c0/b13c02e3ddd6a9d5f8bf84133b3242de556512d824dddeea71cce2dbd6579c8f4d672381c4e742d45cf4423d0701765b4a6e5fbc24701def16bc2b40f8daa96a + version: 3.1.3 + resolution: "loupe@npm:3.1.3" + checksum: 10c0/f5dab4144254677de83a35285be1b8aba58b3861439ce4ba65875d0d5f3445a4a496daef63100ccf02b2dbc25bf58c6db84c9cb0b96d6435331e9d0a33b48541 languageName: node linkType: hard @@ -8239,7 +7887,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0, lru-cache@npm:^10.4.3": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb @@ -8272,11 +7920,11 @@ __metadata: linkType: hard "magic-string@npm:^0.30.11": - version: 0.30.12 - resolution: "magic-string@npm:0.30.12" + version: 0.30.17 + resolution: "magic-string@npm:0.30.17" dependencies: "@jridgewell/sourcemap-codec": "npm:^1.5.0" - checksum: 10c0/469f457d18af37dfcca8617086ea8a65bcd8b60ba8a1182cb024ce43e470ace3c9d1cb6bee58d3b311768fb16bc27bd50bdeebcaa63dadd0fd46cac4d2e11d5f + checksum: 10c0/16826e415d04b88378f200fe022b53e638e3838b9e496edda6c0e086d7753a44a6ed187adc72d19f3623810589bf139af1a315541cd6a26ae0771a0193eaf7b8 languageName: node linkType: hard @@ -8289,23 +7937,22 @@ __metadata: languageName: node linkType: hard -"make-fetch-happen@npm:^13.0.0": - version: 13.0.1 - resolution: "make-fetch-happen@npm:13.0.1" +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" dependencies: - "@npmcli/agent": "npm:^2.0.0" - cacache: "npm:^18.0.0" + "@npmcli/agent": "npm:^3.0.0" + cacache: "npm:^19.0.1" http-cache-semantics: "npm:^4.1.1" - is-lambda: "npm:^1.0.1" minipass: "npm:^7.0.2" - minipass-fetch: "npm:^3.0.0" + minipass-fetch: "npm:^4.0.0" minipass-flush: "npm:^1.0.5" minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^0.6.3" - proc-log: "npm:^4.2.0" + negotiator: "npm:^1.0.0" + proc-log: "npm:^5.0.0" promise-retry: "npm:^2.0.1" - ssri: "npm:^10.0.0" - checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e + ssri: "npm:^12.0.0" + checksum: 10c0/c40efb5e5296e7feb8e37155bde8eb70bc57d731b1f7d90e35a092fde403d7697c56fb49334d92d330d6f1ca29a98142036d6480a12681133a0a1453164cb2f0 languageName: node linkType: hard @@ -8340,20 +7987,20 @@ __metadata: linkType: hard "mdast-util-find-and-replace@npm:^3.0.0": - version: 3.0.1 - resolution: "mdast-util-find-and-replace@npm:3.0.1" + version: 3.0.2 + resolution: "mdast-util-find-and-replace@npm:3.0.2" dependencies: "@types/mdast": "npm:^4.0.0" escape-string-regexp: "npm:^5.0.0" unist-util-is: "npm:^6.0.0" unist-util-visit-parents: "npm:^6.0.0" - checksum: 10c0/1faca98c4ee10a919f23b8cc6d818e5bb6953216a71dfd35f51066ed5d51ef86e5063b43dcfdc6061cd946e016a9f0d44a1dccadd58452cf4ed14e39377f00cb + checksum: 10c0/c8417a35605d567772ff5c1aa08363ff3010b0d60c8ea68c53cba09bf25492e3dd261560425c1756535f3b7107f62e7ff3857cdd8fb1e62d1b2cc2ea6e074ca2 languageName: node linkType: hard "mdast-util-from-markdown@npm:^2.0.0": - version: 2.0.1 - resolution: "mdast-util-from-markdown@npm:2.0.1" + version: 2.0.2 + resolution: "mdast-util-from-markdown@npm:2.0.2" dependencies: "@types/mdast": "npm:^4.0.0" "@types/unist": "npm:^3.0.0" @@ -8367,7 +8014,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" unist-util-stringify-position: "npm:^4.0.0" - checksum: 10c0/496596bc6419200ff6258531a0ebcaee576a5c169695f5aa296a79a85f2a221bb9247d565827c709a7c2acfb56ae3c3754bf483d86206617bd299a9658c8121c + checksum: 10c0/76eb2bd2c6f7a0318087c73376b8af6d7561c1e16654e7667e640f391341096c56142618fd0ff62f6d39e5ab4895898b9789c84cd7cec2874359a437a0e1ff15 languageName: node linkType: hard @@ -8463,8 +8110,8 @@ __metadata: linkType: hard "mdast-util-mdx-jsx@npm:^3.0.0": - version: 3.1.3 - resolution: "mdast-util-mdx-jsx@npm:3.1.3" + version: 3.2.0 + resolution: "mdast-util-mdx-jsx@npm:3.2.0" dependencies: "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -8478,7 +8125,7 @@ __metadata: stringify-entities: "npm:^4.0.0" unist-util-stringify-position: "npm:^4.0.0" vfile-message: "npm:^4.0.0" - checksum: 10c0/1b0b64215efbbbb1ee9ba2a2b3e5f11859dada7dff162949a0d503aefbd75c0308f17d404df126c54acea06d2224905915b2cac2e6c999514c919bd963b8de24 + checksum: 10c0/3acadaf3b962254f7ad2990fed4729961dc0217ca31fde9917986e880843f3ecf3392b1f22d569235cacd180d50894ad266db7af598aedca69d330d33c7ac613 languageName: node linkType: hard @@ -8524,18 +8171,19 @@ __metadata: linkType: hard "mdast-util-to-markdown@npm:^2.0.0": - version: 2.1.0 - resolution: "mdast-util-to-markdown@npm:2.1.0" + version: 2.1.2 + resolution: "mdast-util-to-markdown@npm:2.1.2" dependencies: "@types/mdast": "npm:^4.0.0" "@types/unist": "npm:^3.0.0" longest-streak: "npm:^3.0.0" mdast-util-phrasing: "npm:^4.0.0" mdast-util-to-string: "npm:^4.0.0" + micromark-util-classify-character: "npm:^2.0.0" micromark-util-decode-string: "npm:^2.0.0" unist-util-visit: "npm:^5.0.0" zwitch: "npm:^2.0.0" - checksum: 10c0/8bd37a9627a438ef6418d6642661904d0cc03c5c732b8b018a8e238ef5cc82fe8aef1940b19c6f563245e58b9659f35e527209bd3fe145f3c723ba14d18fc3e6 + checksum: 10c0/4649722a6099f12e797bd8d6469b2b43b44e526b5182862d9c7766a3431caad2c0112929c538a972f214e63c015395e5d3f54bd81d9ac1b16e6d8baaf582f749 languageName: node linkType: hard @@ -8548,13 +8196,13 @@ __metadata: languageName: node linkType: hard -"mdi-material-ui@npm:7.9.2": - version: 7.9.2 - resolution: "mdi-material-ui@npm:7.9.2" +"mdi-material-ui@npm:7.9.3": + version: 7.9.3 + resolution: "mdi-material-ui@npm:7.9.3" peerDependencies: "@mui/material": ^5.0.0 || ^6.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 10c0/c772d74d7979936a686142c97daa20ba956465f394be4a988c2b1e2cbc3e211b5cdd62c013949257064e1ec180da91daffd6075354711af5d805777908e0755d + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/67d9e037be721a4440ffa113a44794d22d02888229b5407d0b38826eece6bfddec4f54a4bfe93b9afc03a363e3ee567e9036cf18d24473a7f95c29c3ef1b806b languageName: node linkType: hard @@ -8587,8 +8235,8 @@ __metadata: linkType: hard "micromark-core-commonmark@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-core-commonmark@npm:2.0.1" + version: 2.0.2 + resolution: "micromark-core-commonmark@npm:2.0.2" dependencies: decode-named-character-reference: "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -8606,7 +8254,7 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/a0b280b1b6132f600518e72cb29a4dd1b2175b85f5ed5b25d2c5695e42b876b045971370daacbcfc6b4ce8cf7acbf78dd3a0284528fb422b450144f4b3bebe19 + checksum: 10c0/87c7a75cd339189eb6f1d6323037f7d108d1331d953b84fe839b37fd385ee2292b27222327c1ceffda46ba5d5d4dee703482475e5ee8744be40c9e308d8acb77 languageName: node linkType: hard @@ -8653,15 +8301,15 @@ __metadata: linkType: hard "micromark-extension-gfm-table@npm:^2.0.0": - version: 2.1.0 - resolution: "micromark-extension-gfm-table@npm:2.1.0" + version: 2.1.1 + resolution: "micromark-extension-gfm-table@npm:2.1.1" dependencies: devlop: "npm:^1.0.0" micromark-factory-space: "npm:^2.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/c1b564ab68576406046d825b9574f5b4dbedbb5c44bede49b5babc4db92f015d9057dd79d8e0530f2fecc8970a695c40ac2e5e1d4435ccf3ef161038d0d1463b + checksum: 10c0/04bc00e19b435fa0add62cd029d8b7eb6137522f77832186b1d5ef34544a9bd030c9cf85e92ddfcc5c31f6f0a58a43d4b96dba4fc21316037c734630ee12c912 languageName: node linkType: hard @@ -8704,195 +8352,195 @@ __metadata: linkType: hard "micromark-factory-destination@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-factory-destination@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-factory-destination@npm:2.0.1" dependencies: micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/b73492f687d41a6a379159c2f3acbf813042346bcea523d9041d0cc6124e6715f0779dbb2a0b3422719e9764c3b09f9707880aa159557e3cb4aeb03b9d274915 + checksum: 10c0/bbafcf869cee5bf511161354cb87d61c142592fbecea051000ff116068dc85216e6d48519d147890b9ea5d7e2864a6341c0c09d9948c203bff624a80a476023c languageName: node linkType: hard "micromark-factory-label@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-factory-label@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-factory-label@npm:2.0.1" dependencies: devlop: "npm:^1.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/8ffad00487a7891941b1d1f51d53a33c7a659dcf48617edb7a4008dad7aff67ec316baa16d55ca98ae3d75ce1d81628dbf72fedc7c6f108f740dec0d5d21c8ee + checksum: 10c0/0137716b4ecb428114165505e94a2f18855c8bbea21b07a8b5ce514b32a595ed789d2b967125718fc44c4197ceaa48f6609d58807a68e778138d2e6b91b824e8 languageName: node linkType: hard "micromark-factory-space@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-factory-space@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-factory-space@npm:2.0.1" dependencies: micromark-util-character: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/103ca954dade963d4ff1d2f27d397833fe855ddc72590205022832ef68b775acdea67949000cee221708e376530b1de78c745267b0bf8366740840783eb37122 + checksum: 10c0/f9ed43f1c0652d8d898de0ac2be3f77f776fffe7dd96bdbba1e02d7ce33d3853c6ff5daa52568fc4fa32cdf3a62d86b85ead9b9189f7211e1d69ff2163c450fb languageName: node linkType: hard "micromark-factory-title@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-factory-title@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-factory-title@npm:2.0.1" dependencies: micromark-factory-space: "npm:^2.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/2b2188e7a011b1b001faf8c860286d246d5c3485ef8819270c60a5808f4c7613e49d4e481dbdff62600ef7acdba0f5100be2d125cbd2a15e236c26b3668a8ebd + checksum: 10c0/e72fad8d6e88823514916890099a5af20b6a9178ccf78e7e5e05f4de99bb8797acb756257d7a3a57a53854cb0086bf8aab15b1a9e9db8982500dd2c9ff5948b6 languageName: node linkType: hard "micromark-factory-whitespace@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-factory-whitespace@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-factory-whitespace@npm:2.0.1" dependencies: micromark-factory-space: "npm:^2.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/4e91baab0cc71873095134bd0e225d01d9786cde352701402d71b72d317973954754e8f9f1849901f165530e6421202209f4d97c460a27bb0808ec5a3fc3148c + checksum: 10c0/20a1ec58698f24b766510a309b23a10175034fcf1551eaa9da3adcbed3e00cd53d1ebe5f030cf873f76a1cec3c34eb8c50cc227be3344caa9ed25d56cf611224 languageName: node linkType: hard "micromark-util-character@npm:^2.0.0": - version: 2.1.0 - resolution: "micromark-util-character@npm:2.1.0" + version: 2.1.1 + resolution: "micromark-util-character@npm:2.1.1" dependencies: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/fc37a76aaa5a5138191ba2bef1ac50c36b3bcb476522e98b1a42304ab4ec76f5b036a746ddf795d3de3e7004b2c09f21dd1bad42d161f39b8cfc0acd067e6373 + checksum: 10c0/d3fe7a5e2c4060fc2a076f9ce699c82a2e87190a3946e1e5eea77f563869b504961f5668d9c9c014724db28ac32fa909070ea8b30c3a39bd0483cc6c04cc76a1 languageName: node linkType: hard "micromark-util-chunked@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-chunked@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-chunked@npm:2.0.1" dependencies: micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/043b5f2abc8c13a1e2e4c378ead191d1a47ed9e0cd6d0fa5a0a430b2df9e17ada9d5de5a20688a000bbc5932507e746144acec60a9589d9a79fa60918e029203 + checksum: 10c0/b68c0c16fe8106949537bdcfe1be9cf36c0ccd3bc54c4007003cb0984c3750b6cdd0fd77d03f269a3382b85b0de58bde4f6eedbe7ecdf7244759112289b1ab56 languageName: node linkType: hard "micromark-util-classify-character@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-classify-character@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-classify-character@npm:2.0.1" dependencies: micromark-util-character: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/2bf5fa5050faa9b69f6c7e51dbaaf02329ab70fabad8229984381b356afbbf69db90f4617bec36d814a7d285fb7cad8e3c4e38d1daf4387dc9e240aa7f9a292a + checksum: 10c0/8a02e59304005c475c332f581697e92e8c585bcd45d5d225a66c1c1b14ab5a8062705188c2ccec33cc998d33502514121478b2091feddbc751887fc9c290ed08 languageName: node linkType: hard "micromark-util-combine-extensions@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-combine-extensions@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-combine-extensions@npm:2.0.1" dependencies: micromark-util-chunked: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/cd4c8d1a85255527facb419ff3b3cc3d7b7f27005c5ef5fa7ef2c4d0e57a9129534fc292a188ec2d467c2c458642d369c5f894bc8a9e142aed6696cc7989d3ea + checksum: 10c0/f15e282af24c8372cbb10b9b0b3e2c0aa681fea0ca323a44d6bc537dc1d9382c819c3689f14eaa000118f5a163245358ce6276b2cda9a84439cdb221f5d86ae7 languageName: node linkType: hard "micromark-util-decode-numeric-character-reference@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.1" + version: 2.0.2 + resolution: "micromark-util-decode-numeric-character-reference@npm:2.0.2" dependencies: micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/3f6d684ee8f317c67806e19b3e761956256cb936a2e0533aad6d49ac5604c6536b2041769c6febdd387ab7175b7b7e551851bf2c1f78da943e7a3671ca7635ac + checksum: 10c0/9c8a9f2c790e5593ffe513901c3a110e9ec8882a08f466da014112a25e5059b51551ca0aeb7ff494657d86eceb2f02ee556c6558b8d66aadc61eae4a240da0df languageName: node linkType: hard "micromark-util-decode-string@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-decode-string@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-decode-string@npm:2.0.1" dependencies: decode-named-character-reference: "npm:^1.0.0" micromark-util-character: "npm:^2.0.0" micromark-util-decode-numeric-character-reference: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/f5413bebb21bdb686cfa1bcfa7e9c93093a523d1b42443ead303b062d2d680a94e5e8424549f57b8ba9d786a758e5a26a97f56068991bbdbca5d1885b3aa7227 + checksum: 10c0/f24d75b2e5310be6e7b6dee532e0d17d3bf46996841d6295f2a9c87a2046fff4ab603c52ab9d7a7a6430a8b787b1574ae895849c603d262d1b22eef71736b5cb languageName: node linkType: hard "micromark-util-encode@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-encode@npm:2.0.0" - checksum: 10c0/ebdaafff23100bbf4c74e63b4b1612a9ddf94cd7211d6a076bc6fb0bc32c1b48d6fb615aa0953e607c62c97d849f97f1042260d3eb135259d63d372f401bbbb2 + version: 2.0.1 + resolution: "micromark-util-encode@npm:2.0.1" + checksum: 10c0/b2b29f901093845da8a1bf997ea8b7f5e061ffdba85070dfe14b0197c48fda64ffcf82bfe53c90cf9dc185e69eef8c5d41cae3ba918b96bc279326921b59008a languageName: node linkType: hard "micromark-util-html-tag-name@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-html-tag-name@npm:2.0.0" - checksum: 10c0/988aa26367449bd345b627ae32cf605076daabe2dc1db71b578a8a511a47123e14af466bcd6dcbdacec60142f07bc2723ec5f7a0eed0f5319ce83b5e04825429 + version: 2.0.1 + resolution: "micromark-util-html-tag-name@npm:2.0.1" + checksum: 10c0/ae80444db786fde908e9295f19a27a4aa304171852c77414516418650097b8afb401961c9edb09d677b06e97e8370cfa65638dde8438ebd41d60c0a8678b85b9 languageName: node linkType: hard "micromark-util-normalize-identifier@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-normalize-identifier@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-normalize-identifier@npm:2.0.1" dependencies: micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/93bf8789b8449538f22cf82ac9b196363a5f3b2f26efd98aef87c4c1b1f8c05be3ef6391ff38316ff9b03c1a6fd077342567598019ddd12b9bd923dacc556333 + checksum: 10c0/5299265fa360769fc499a89f40142f10a9d4a5c3dd8e6eac8a8ef3c2e4a6570e4c009cf75ea46dce5ee31c01f25587bde2f4a5cc0a935584ae86dd857f2babbd languageName: node linkType: hard "micromark-util-resolve-all@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-resolve-all@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-resolve-all@npm:2.0.1" dependencies: micromark-util-types: "npm:^2.0.0" - checksum: 10c0/3b912e88453dcefe728a9080c8934a75ac4732056d6576ceecbcaf97f42c5d6fa2df66db8abdc8427eb167c5ffddefe26713728cfe500bc0e314ed260d6e2746 + checksum: 10c0/bb6ca28764696bb479dc44a2d5b5fe003e7177aeae1d6b0d43f24cc223bab90234092d9c3ce4a4d2b8df095ccfd820537b10eb96bb7044d635f385d65a4c984a languageName: node linkType: hard "micromark-util-sanitize-uri@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-sanitize-uri@npm:2.0.0" + version: 2.0.1 + resolution: "micromark-util-sanitize-uri@npm:2.0.1" dependencies: micromark-util-character: "npm:^2.0.0" micromark-util-encode: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" - checksum: 10c0/74763ca1c927dd520d3ab8fd9856a19740acf76fc091f0a1f5d4e99c8cd5f1b81c5a0be3efb564941a071fb6d85fd951103f2760eb6cff77b5ab3abe08341309 + checksum: 10c0/60e92166e1870fd4f1961468c2651013ff760617342918e0e0c3c4e872433aa2e60c1e5a672bfe5d89dc98f742d6b33897585cf86ae002cda23e905a3c02527c languageName: node linkType: hard "micromark-util-subtokenize@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-subtokenize@npm:2.0.1" + version: 2.0.4 + resolution: "micromark-util-subtokenize@npm:2.0.4" dependencies: devlop: "npm:^1.0.0" micromark-util-chunked: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/000cefde827db129f4ed92b8fbdeb4866c5f9c93068c0115485564b0426abcb9058080aa257df9035e12ca7fa92259d66623ea750b9eb3bcdd8325d3fb6fc237 + checksum: 10c0/d1d19c6ede87e5d3778aa7f6c56ad736a48404556757abf71ea87bd2baac71927d18db3c9a1f76c4b3f42f32d6032aea97d1de739b49872daf168c6f8f373f39 languageName: node linkType: hard "micromark-util-symbol@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-symbol@npm:2.0.0" - checksum: 10c0/4e76186c185ce4cefb9cea8584213d9ffacd77099d1da30c0beb09fa21f46f66f6de4c84c781d7e34ff763fe3a06b530e132fa9004882afab9e825238d0aa8b3 + version: 2.0.1 + resolution: "micromark-util-symbol@npm:2.0.1" + checksum: 10c0/f2d1b207771e573232436618e78c5e46cd4b5c560dd4a6d63863d58018abbf49cb96ec69f7007471e51434c60de3c9268ef2bf46852f26ff4aacd10f9da16fe9 languageName: node linkType: hard "micromark-util-types@npm:^2.0.0": - version: 2.0.0 - resolution: "micromark-util-types@npm:2.0.0" - checksum: 10c0/d74e913b9b61268e0d6939f4209e3abe9dada640d1ee782419b04fd153711112cfaaa3c4d5f37225c9aee1e23c3bb91a1f5223e1e33ba92d33e83956a53e61de + version: 2.0.1 + resolution: "micromark-util-types@npm:2.0.1" + checksum: 10c0/872ec9334bb42afcc91c5bed8b7ee03b75654b36c6f221ab4d2b1bb0299279f00db948bf38ec6bc1ec03d0cf7842c21ab805190bf676157ba587eb0386d38b71 languageName: node linkType: hard "micromark@npm:^4.0.0": - version: 4.0.0 - resolution: "micromark@npm:4.0.0" + version: 4.0.1 + resolution: "micromark@npm:4.0.1" dependencies: "@types/debug": "npm:^4.0.0" debug: "npm:^4.0.0" @@ -8911,11 +8559,11 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10c0/7e91c8d19ff27bc52964100853f1b3b32bb5b2ece57470a34ba1b2f09f4e2a183d90106c4ae585c9f2046969ee088576fed79b2f7061cba60d16652ccc2c64fd + checksum: 10c0/b5d950c84664ce209575e5a54946488f0a1e1240d080544e657b65074c9b08208a5315d9db066b93cbc199ec05f68552ba8b09fd5e716c726f4a4712275a7c5c languageName: node linkType: hard -"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": +"micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -8984,18 +8632,18 @@ __metadata: languageName: node linkType: hard -"minipass-fetch@npm:^3.0.0": - version: 3.0.5 - resolution: "minipass-fetch@npm:3.0.5" +"minipass-fetch@npm:^4.0.0": + version: 4.0.0 + resolution: "minipass-fetch@npm:4.0.0" dependencies: encoding: "npm:^0.1.13" minipass: "npm:^7.0.3" minipass-sized: "npm:^1.0.3" - minizlib: "npm:^2.1.2" + minizlib: "npm:^3.0.1" dependenciesMeta: encoding: optional: true - checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b + checksum: 10c0/7fa30ce7c373fb6f94c086b374fff1589fd7e78451855d2d06c2e2d9df936d131e73e952163063016592ed3081444bd8d1ea608533313b0149156ce23311da4b languageName: node linkType: hard @@ -9030,50 +8678,43 @@ __metadata: version: 3.3.6 resolution: "minipass@npm:3.3.6" dependencies: - yallist: "npm:^4.0.0" - checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c - languageName: node - linkType: hard - -"minipass@npm:^5.0.0": - version: 5.0.0 - resolution: "minipass@npm:5.0.0" - checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 + yallist: "npm:^4.0.0" + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 languageName: node linkType: hard -"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": - version: 2.1.2 - resolution: "minizlib@npm:2.1.2" +"minizlib@npm:^3.0.1": + version: 3.0.1 + resolution: "minizlib@npm:3.0.1" dependencies: - minipass: "npm:^3.0.0" - yallist: "npm:^4.0.0" - checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 + minipass: "npm:^7.0.4" + rimraf: "npm:^5.0.5" + checksum: 10c0/82f8bf70da8af656909a8ee299d7ed3b3372636749d29e105f97f20e88971be31f5ed7642f2e898f00283b68b701cc01307401cdc209b0efc5dd3818220e5093 languageName: node linkType: hard -"mkdirp@npm:^1.0.3": - version: 1.0.4 - resolution: "mkdirp@npm:1.0.4" +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" bin: - mkdirp: bin/cmd.js - checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf + mkdirp: dist/cjs/src/bin.js + checksum: 10c0/9f2b975e9246351f5e3a40dcfac99fcd0baa31fbfab615fe059fb11e51f10e4803c63de1f384c54d656e4db31d000e4767e9ef076a22e12a641357602e31d57d languageName: node linkType: hard -"moment-timezone@npm:0.5.45": - version: 0.5.45 - resolution: "moment-timezone@npm:0.5.45" +"moment-timezone@npm:0.5.47": + version: 0.5.47 + resolution: "moment-timezone@npm:0.5.47" dependencies: moment: "npm:^2.29.4" - checksum: 10c0/7497f23c4b8c875dbf07c03f9a1253f79edaeedc29d5732e36bfd3c5577e25aed1924fbd84cbb713ce1920dbe822be0e21bd487851a7d13907226f289a5e568b + checksum: 10c0/6f7cdbebe712dcbb767a6380e097d352776b83dd7d1d797546d6ff21d813e8380633373da93aea1d24f2c3c031044fd4a18726cacad14eda3f1f428192ad955c languageName: node linkType: hard @@ -9106,15 +8747,15 @@ __metadata: languageName: node linkType: hard -"monocart-coverage-reports@npm:^2.11.3": - version: 2.11.3 - resolution: "monocart-coverage-reports@npm:2.11.3" +"monocart-coverage-reports@npm:^2.11.5": + version: 2.12.1 + resolution: "monocart-coverage-reports@npm:2.12.1" dependencies: acorn: "npm:^8.14.0" acorn-loose: "npm:^8.4.0" acorn-walk: "npm:^8.3.4" - commander: "npm:^12.1.0" - console-grid: "npm:^2.2.2" + commander: "npm:^13.1.0" + console-grid: "npm:^2.2.3" eight-colors: "npm:^1.3.1" foreground-child: "npm:^3.3.0" istanbul-lib-coverage: "npm:^3.2.2" @@ -9124,7 +8765,7 @@ __metadata: monocart-locator: "npm:^1.0.2" bin: mcr: lib/cli.js - checksum: 10c0/d649c85f3ee13c6b06ebbdf617e38abc3c1d4e66997bfd9717ab720a509c44f6e924123b75ee0fc525bde8bf645a5893bd14f7de59dd407c10080d9bf7215f96 + checksum: 10c0/eac03d76c1796647b159a2a1ef1e0acc691ac09f27a1156382ffec39582090ccb286dc0415493ffcd4601f6977d5a07617112e7fb733570632cd9590113918de languageName: node linkType: hard @@ -9135,21 +8776,21 @@ __metadata: languageName: node linkType: hard -"monocart-reporter@npm:2.9.11": - version: 2.9.11 - resolution: "monocart-reporter@npm:2.9.11" +"monocart-reporter@npm:2.9.13": + version: 2.9.13 + resolution: "monocart-reporter@npm:2.9.13" dependencies: - console-grid: "npm:^2.2.2" + console-grid: "npm:^2.2.3" eight-colors: "npm:^1.3.1" koa: "npm:^2.15.3" koa-static-resolver: "npm:^1.0.6" lz-utils: "npm:^2.1.0" - monocart-coverage-reports: "npm:^2.11.3" + monocart-coverage-reports: "npm:^2.11.5" monocart-locator: "npm:^1.0.2" nodemailer: "npm:^6.9.16" bin: monocart: lib/cli.js - checksum: 10c0/086c31370dfd443de35ac4acd9a0d3229800c7f0bcfd06e4473ea0b510e8557c9f05e96903152ae37c1ffd3957cd27b7eadf608c95fd226e5ce4a0b143eded7d + checksum: 10c0/ecb9d8b8befa97c2d9e4a6761f4c7f8d4844efdd25996a38aaa8f2af71c6abb5f530ca716dc296005e76f2b64d2448309eca949b682ef6598a1dcb9043ca5e9e languageName: node linkType: hard @@ -9190,10 +8831,10 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:^0.6.3": - version: 0.6.4 - resolution: "negotiator@npm:0.6.4" - checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b languageName: node linkType: hard @@ -9221,22 +8862,22 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 10.2.0 - resolution: "node-gyp@npm:10.2.0" + version: 11.0.0 + resolution: "node-gyp@npm:11.0.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" glob: "npm:^10.3.10" graceful-fs: "npm:^4.2.6" - make-fetch-happen: "npm:^13.0.0" - nopt: "npm:^7.0.0" - proc-log: "npm:^4.1.0" + make-fetch-happen: "npm:^14.0.3" + nopt: "npm:^8.0.0" + proc-log: "npm:^5.0.0" semver: "npm:^7.3.5" - tar: "npm:^6.2.1" - which: "npm:^4.0.0" + tar: "npm:^7.4.3" + which: "npm:^5.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/00630d67dbd09a45aee0a5d55c05e3916ca9e6d427ee4f7bc392d2d3dc5fad7449b21fc098dd38260a53d9dcc9c879b36704a1994235d4707e7271af7e9a835b + checksum: 10c0/a3b885bbee2d271f1def32ba2e30ffcf4562a3db33af06b8b365e053153e2dd2051b9945783c3c8e852d26a0f20f65b251c7e83361623383a99635c0280ee573 languageName: node linkType: hard @@ -9249,28 +8890,28 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.18": - version: 2.0.18 - resolution: "node-releases@npm:2.0.18" - checksum: 10c0/786ac9db9d7226339e1dc84bbb42007cb054a346bd9257e6aa154d294f01bc6a6cddb1348fa099f079be6580acbb470e3c048effd5f719325abd0179e566fd27 +"node-releases@npm:^2.0.19": + version: 2.0.19 + resolution: "node-releases@npm:2.0.19" + checksum: 10c0/52a0dbd25ccf545892670d1551690fe0facb6a471e15f2cfa1b20142a5b255b3aa254af5f59d6ecb69c2bec7390bc643c43aa63b13bf5e64b6075952e716b1aa languageName: node linkType: hard "nodemailer@npm:^6.9.16": - version: 6.9.16 - resolution: "nodemailer@npm:6.9.16" - checksum: 10c0/9fd73ab4ab5b81544c3c9820afbe386369aba442f997b2f58d171222a898a7aed580fc100bfe6eebc194f18ba6e169d67ee40ca64d32d69022d89e575cef97a4 + version: 6.10.0 + resolution: "nodemailer@npm:6.10.0" + checksum: 10c0/39fd35d65b021b94c968eeac82a66dd843021b6ba53c659d01b1dd4cda73b6a2f96e20facfe500efa4b8d3f1cb23df10245c6c86b2bde5f806691ed17ce87826 languageName: node linkType: hard -"nopt@npm:^7.0.0": - version: 7.2.1 - resolution: "nopt@npm:7.2.1" +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" dependencies: - abbrev: "npm:^2.0.0" + abbrev: "npm:^3.0.0" bin: nopt: bin/nopt.js - checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 + checksum: 10c0/62e9ea70c7a3eb91d162d2c706b6606c041e4e7b547cbbb48f8b3695af457dd6479904d7ace600856bf923dd8d1ed0696f06195c8c20f02ac87c1da0e1d315ef languageName: node linkType: hard @@ -9291,9 +8932,9 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.12": - version: 2.2.13 - resolution: "nwsapi@npm:2.2.13" - checksum: 10c0/9dbd1071bba3570ef0b046c43c03d0584c461063f27539ba39f4185188e9d5c10cb06fd4426cdb300bb83020c3daa2c8f4fa9e8a070299539ac4007433357ac0 + version: 2.2.16 + resolution: "nwsapi@npm:2.2.16" + checksum: 10c0/0aa0637f4d51043d0183d994e08336bae996b03b42984381bf09ebdf3ff4909c018eda6b2a8aba0a08f3ea8303db8a0dad0608b38dc0bff15fd87017286ae21a languageName: node linkType: hard @@ -9362,17 +9003,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.1": - version: 1.13.2 - resolution: "object-inspect@npm:1.13.2" - checksum: 10c0/b97835b4c91ec37b5fd71add84f21c3f1047d1d155d00c0fcd6699516c256d4fcc6ff17a1aced873197fe447f91a3964178fd2a67a1ee2120cdaf60e81a050b4 - languageName: node - linkType: hard - "object-inspect@npm:^1.13.3": - version: 1.13.3 - resolution: "object-inspect@npm:1.13.3" - checksum: 10c0/cc3f15213406be89ffdc54b525e115156086796a515410a8d390215915db9f23c8eab485a06f1297402f440a33715fe8f71a528c1dcbad6e1a3bcaf5a46921d4 + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10c0/d7f8711e803b96ea3191c745d6f8056ce1f2496e530e6a19a0e92d89b0fa3c76d910c31f0aa270432db6bd3b2f85500a376a83aaba849a8d518c8845b3211692 languageName: node linkType: hard @@ -9393,19 +9027,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": - version: 4.1.5 - resolution: "object.assign@npm:4.1.5" - dependencies: - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - has-symbols: "npm:^1.0.3" - object-keys: "npm:^1.1.1" - checksum: 10c0/60108e1fa2706f22554a4648299b0955236c62b3685c52abf4988d14fffb0e7731e00aa8c6448397e3eb63d087dcc124a9f21e1980f36d0b2667f3c18bacd469 - languageName: node - linkType: hard - -"object.assign@npm:^4.1.7": +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7": version: 4.1.7 resolution: "object.assign@npm:4.1.7" dependencies: @@ -9453,18 +9075,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.2.0": - version: 1.2.0 - resolution: "object.values@npm:1.2.0" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/15809dc40fd6c5529501324fec5ff08570b7d70fb5ebbe8e2b3901afec35cf2b3dc484d1210c6c642cd3e7e0a5e18dd1d6850115337fef46bdae14ab0cb18ac3 - languageName: node - linkType: hard - -"object.values@npm:^1.2.1": +"object.values@npm:^1.1.6, object.values@npm:^1.2.0, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" dependencies: @@ -9500,7 +9111,7 @@ __metadata: "@dagrejs/dagre": "npm:1.1.4" "@emotion/react": "npm:11.14.0" "@emotion/styled": "npm:11.14.0" - "@eslint/js": "npm:9.19.0" + "@eslint/js": "npm:9.20.0" "@faker-js/faker": "npm:9.4.0" "@fontsource/geologica": "npm:5.1.0" "@fontsource/ibm-plex-sans": "npm:5.1.0" @@ -9509,7 +9120,6 @@ __metadata: "@mui/icons-material": "npm:6.4.1" "@mui/lab": "npm:6.0.0-beta.24" "@mui/material": "npm:6.4.1" - "@mui/styles": "npm:6.4.1" "@mui/system": "npm:6.4.1" "@mui/utils": "npm:6.4.1" "@mui/x-date-pickers": "npm:7.24.0" @@ -9533,22 +9143,21 @@ __metadata: "@typescript-eslint/utils": "npm:8.22.0" "@uiw/react-md-editor": "npm:4.0.5" "@vitejs/plugin-react": "npm:4.3.4" - "@vitest/eslint-plugin": "npm:1.1.25" + "@vitest/eslint-plugin": "npm:1.1.27" "@xyflow/react": "npm:12.4.2" - apexcharts: "npm:4.3.0" + apexcharts: "npm:4.4.0" axios: "npm:1.7.9" chokidar: "npm:4.0.3" ckeditor5: "npm:44.1.0" classcat: "npm:5.0.5" - classnames: "npm:2.5.1" cronstrue: "npm:2.54.0" cross-env: "npm:7.0.3" d3-hierarchy: "npm:3.1.2" date-fns: "npm:4.1.0" dompurify: "npm:3.2.4" elkjs: "npm:0.9.3" - esbuild: "npm:0.24.2" - eslint: "npm:9.19.0" + esbuild: "npm:0.25.0" + eslint: "npm:9.20.0" eslint-import-resolver-oxc: "npm:0.10.1" eslint-plugin-custom-rules: "link:packages/eslint-plugin-custom-rules" eslint-plugin-i18next: "npm:6.1.1" @@ -9556,24 +9165,24 @@ __metadata: eslint-plugin-import-newlines: "npm:1.4.0" eslint-plugin-playwright: "npm:2.2.0" eslint-plugin-react: "npm:7.37.4" - eslint-plugin-react-refresh: "npm:0.4.18" + eslint-plugin-react-refresh: "npm:0.4.19" eslint-plugin-simple-import-sort: "npm:12.1.1" - express: "npm:4.21.1" + express: "npm:4.21.2" final-form: "npm:4.20.10" final-form-arrays: "npm:3.1.0" fs-extra: "npm:11.3.0" globals: "npm:15.14.0" - html-react-parser: "npm:5.2.0" + html-react-parser: "npm:5.2.2" html-to-image: "npm:1.11.11" http-proxy-middleware: "npm:3.0.3" js-file-download: "npm:0.4.12" jsdom: "npm:25.0.1" leaflet: "npm:1.9.4" - mdi-material-ui: "npm:7.9.2" + mdi-material-ui: "npm:7.9.3" moment: "npm:2.30.1" - moment-timezone: "npm:0.5.45" + moment-timezone: "npm:0.5.47" monocart-coverage-reports: "npm:2.12.0" - monocart-reporter: "npm:2.9.11" + monocart-reporter: "npm:2.9.13" normalizr: "npm:3.6.2" pdfmake: "npm:0.2.13" prop-types: "npm:15.8.1" @@ -9587,12 +9196,12 @@ __metadata: react-dropzone: "npm:14.3.5" react-final-form: "npm:6.5.9" react-final-form-arrays: "npm:3.1.4" - react-hook-form: "npm:7.54.1" - react-intl: "npm:7.1.0" + react-hook-form: "npm:7.54.2" + react-intl: "npm:7.1.6" react-leaflet: "npm:4.2.1" react-markdown: "npm:9.0.1" react-redux: "npm:9.2.0" - react-router: "npm:7.1.1" + react-router: "npm:7.1.5" react-syntax-highlighter: "npm:15.6.1" redux: "npm:5.0.1" redux-thunk: "npm:3.1.0" @@ -9601,12 +9210,13 @@ __metadata: remark-parse: "npm:11.0.0" rxjs: "npm:7.8.1" seamless-immutable: "npm:7.1.4" - swagger-typescript-api: "npm:13.0.22" - typescript: "npm:5.7.2" + swagger-typescript-api: "npm:13.0.23" + tss-react: "npm:4.9.15" + typescript: "npm:5.7.3" typescript-eslint: "npm:8.22.0" - usehooks-ts: "npm:3.1.0" - uuid: "npm:11.0.3" - vite: "npm:6.0.9" + usehooks-ts: "npm:3.1.1" + uuid: "npm:11.0.5" + vite: "npm:6.1.0" vitest: "npm:2.1.1" xlsx: "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz" zod: "npm:3.24.1" @@ -9699,12 +9309,10 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: "npm:^3.0.0" - checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 10c0/46091610da2b38ce47bcd1d8b4835a6fa4e832848a6682cf1652bc93915770f4617afc844c10a77d1b3e56d2472bb2d5622353fa3ead01a7f42b04fc8e744a5c languageName: node linkType: hard @@ -9746,18 +9354,17 @@ __metadata: linkType: hard "parse-entities@npm:^4.0.0": - version: 4.0.1 - resolution: "parse-entities@npm:4.0.1" + version: 4.0.2 + resolution: "parse-entities@npm:4.0.2" dependencies: "@types/unist": "npm:^2.0.0" - character-entities: "npm:^2.0.0" character-entities-legacy: "npm:^3.0.0" character-reference-invalid: "npm:^2.0.0" decode-named-character-reference: "npm:^1.0.0" is-alphanumerical: "npm:^2.0.0" is-decimal: "npm:^2.0.0" is-hexadecimal: "npm:^2.0.0" - checksum: 10c0/9dfa3b0dc43a913c2558c4bd625b1abcc2d6c6b38aa5724b141ed988471977248f7ad234eed57e1bc70b694dd15b0d710a04f66c2f7c096e35abd91962b7d926 + checksum: 10c0/a13906b1151750b78ed83d386294066daf5fb559e08c5af9591b2d98cc209123103016a01df776f65f8219ad26652d6d6b210d0974d452049cddfc53a8916c34 languageName: node linkType: hard @@ -9781,11 +9388,11 @@ __metadata: linkType: hard "parse5@npm:^7.0.0, parse5@npm:^7.1.2": - version: 7.2.0 - resolution: "parse5@npm:7.2.0" + version: 7.2.1 + resolution: "parse5@npm:7.2.1" dependencies: entities: "npm:^4.5.0" - checksum: 10c0/76d68684708befb41ff1d5e0e9835f566afb3950807d340941afc9dbe4c9c28db2414bda0c8503d459de863463869b8540c6abf8c9742cffa0b9b31eecd37951 + checksum: 10c0/829d37a0c709215a887e410a7118d754f8e1afd7edb529db95bc7bbf8045fb0266a7b67801331d8e8d9d073ea75793624ec27ce9ff3b96862c3b9008f4d68e80 languageName: node linkType: hard @@ -9827,10 +9434,10 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.10": - version: 0.1.10 - resolution: "path-to-regexp@npm:0.1.10" - checksum: 10c0/34196775b9113ca6df88e94c8d83ba82c0e1a2063dd33bfe2803a980da8d49b91db8104f49d5191b44ea780d46b8670ce2b7f4a5e349b0c48c6779b653f1afe4 +"path-to-regexp@npm:0.1.12": + version: 0.1.12 + resolution: "path-to-regexp@npm:0.1.12" + checksum: 10c0/1c6ff10ca169b773f3bba943bbc6a07182e332464704572962d277b900aeee81ac6aa5d060ff9e01149636c30b1f63af6e69dd7786ba6e0ddb39d4dee1f0645b languageName: node linkType: hard @@ -9867,7 +9474,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -9926,18 +9533,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.43": - version: 8.4.47 - resolution: "postcss@npm:8.4.47" - dependencies: - nanoid: "npm:^3.3.7" - picocolors: "npm:^1.1.0" - source-map-js: "npm:^1.2.1" - checksum: 10c0/929f68b5081b7202709456532cee2a145c1843d391508c5a09de2517e8c4791638f71dd63b1898dba6712f8839d7a6da046c72a5e44c162e908f5911f57b5f44 - languageName: node - linkType: hard - -"postcss@npm:^8.4.49": +"postcss@npm:^8.4.43, postcss@npm:^8.5.1": version: 8.5.1 resolution: "postcss@npm:8.5.1" dependencies: @@ -9989,10 +9585,10 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": - version: 4.2.0 - resolution: "proc-log@npm:4.2.0" - checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: 10c0/bbe5edb944b0ad63387a1d5b1911ae93e05ce8d0f60de1035b218cdcceedfe39dbd2c697853355b70f1a090f8f58fe90da487c85216bf9671f9499d1a897e9e3 languageName: node linkType: hard @@ -10207,34 +9803,34 @@ __metadata: languageName: node linkType: hard -"react-hook-form@npm:7.54.1": - version: 7.54.1 - resolution: "react-hook-form@npm:7.54.1" +"react-hook-form@npm:7.54.2": + version: 7.54.2 + resolution: "react-hook-form@npm:7.54.2" peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - checksum: 10c0/2d960ddf8aa654f34e36f5d995f0ec067a4c01340d650eca44f22aa4421e278dcc449c8522e66c5c66b1c61d62fbdf914b9e0a8de9deb4c6346cc3b37ef4eb82 + checksum: 10c0/6eebead2900e3d369a989e7a20429f390dc75b3897142aa3107f1f6dabb9ae64fed201ea98cdcd8676e40466c97748aeb0c0d83264f5bd3a84dbc0b8e4863415 languageName: node linkType: hard -"react-intl@npm:7.1.0": - version: 7.1.0 - resolution: "react-intl@npm:7.1.0" +"react-intl@npm:7.1.6": + version: 7.1.6 + resolution: "react-intl@npm:7.1.6" dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.2" - "@formatjs/icu-messageformat-parser": "npm:2.9.8" - "@formatjs/intl": "npm:3.1.0" + "@formatjs/ecma402-abstract": "npm:2.3.3" + "@formatjs/icu-messageformat-parser": "npm:2.11.1" + "@formatjs/intl": "npm:3.1.4" "@types/hoist-non-react-statics": "npm:3" - "@types/react": "npm:16 || 17 || 18" + "@types/react": "npm:16 || 17 || 18 || 19" hoist-non-react-statics: "npm:3" - intl-messageformat: "npm:10.7.11" + intl-messageformat: "npm:10.7.15" tslib: "npm:2" peerDependencies: - react: ^16.6.0 || 17 || 18 + react: ^16.6.0 || 17 || 18 || 19 typescript: 5 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/9d69e316a5f5c6d31fa77f136b595079db2f75f63398cf8253d407878246dd5bcf0cc2eb4d7d4aa0646530ee58b16ce9a8c3876a5c2f0dc38fdda7e4f8c07615 + checksum: 10c0/6ccb6ba40e30079822994eb36f76c8631d5f31f5826f1fa62b00371be6efd1481b094285f7f1f672c01705dfe9b36b91ce89df35f61d7bb293e5709d7f07d1b7 languageName: node linkType: hard @@ -10252,13 +9848,6 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^18.3.1": - version: 18.3.1 - resolution: "react-is@npm:18.3.1" - checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 - languageName: node - linkType: hard - "react-is@npm:^19.0.0": version: 19.0.0 resolution: "react-is@npm:19.0.0" @@ -10279,7 +9868,7 @@ __metadata: languageName: node linkType: hard -"react-markdown@npm:9.0.1, react-markdown@npm:~9.0.1": +"react-markdown@npm:9.0.1": version: 9.0.1 resolution: "react-markdown@npm:9.0.1" dependencies: @@ -10300,6 +9889,27 @@ __metadata: languageName: node linkType: hard +"react-markdown@npm:~9.0.1": + version: 9.0.3 + resolution: "react-markdown@npm:9.0.3" + dependencies: + "@types/hast": "npm:^3.0.0" + devlop: "npm:^1.0.0" + hast-util-to-jsx-runtime: "npm:^2.0.0" + html-url-attributes: "npm:^3.0.0" + mdast-util-to-hast: "npm:^13.0.0" + remark-parse: "npm:^11.0.0" + remark-rehype: "npm:^11.0.0" + unified: "npm:^11.0.0" + unist-util-visit: "npm:^5.0.0" + vfile: "npm:^6.0.0" + peerDependencies: + "@types/react": ">=18" + react: ">=18" + checksum: 10c0/7f1aef171b49af9b84896917c033cbc0f45d0d2b4a5db5a339bf96977a143ae19f21cb7a69a6878b718d5578db021e96372fa33621b79bf57a87efb9b3c84166 + languageName: node + linkType: hard + "react-property@npm:2.0.2": version: 2.0.2 resolution: "react-property@npm:2.0.2" @@ -10333,9 +9943,9 @@ __metadata: languageName: node linkType: hard -"react-router@npm:7.1.1": - version: 7.1.1 - resolution: "react-router@npm:7.1.1" +"react-router@npm:7.1.5": + version: 7.1.5 + resolution: "react-router@npm:7.1.5" dependencies: "@types/cookie": "npm:^0.6.0" cookie: "npm:^1.0.1" @@ -10347,7 +9957,7 @@ __metadata: peerDependenciesMeta: react-dom: optional: true - checksum: 10c0/39f4859670f286eb2eac29e5830c1f730405701fca0808e5db853ec05e54e55a848c764e10ffd14a7b9b3b2154a0d6449656d7f208b9b3e4b2af780e07bf57a8 + checksum: 10c0/c0013102c7a02d26cd2353fa3749bd229fbcfedd291710540be1765d703861f96a34ef0114dd5ee8d9a728e87f3a5698387058f9539b39604f331505f507d912 languageName: node linkType: hard @@ -10401,9 +10011,9 @@ __metadata: linkType: hard "readdirp@npm:^4.0.1": - version: 4.0.2 - resolution: "readdirp@npm:4.0.2" - checksum: 10c0/a16ecd8ef3286dcd90648c3b103e3826db2b766cdb4a988752c43a83f683d01c7059158d623cbcd8bdfb39e65d302d285be2d208e7d9f34d022d912b929217dd + version: 4.1.1 + resolution: "readdirp@npm:4.1.1" + checksum: 10c0/a1afc90d0e57ce4caa28046875519453fd09663ade0d0c29fe0d6a117eca4596cfdf1a9ebb0859ad34cca7b9351d4f0d8d962a4363d40f3f37e57dba51ffb6b6 languageName: node linkType: hard @@ -10476,19 +10086,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": - version: 1.5.3 - resolution: "regexp.prototype.flags@npm:1.5.3" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-errors: "npm:^1.3.0" - set-function-name: "npm:^2.0.2" - checksum: 10c0/e1a7c7dc42cc91abf73e47a269c4b3a8f225321b7f617baa25821f6a123a91d23a73b5152f21872c566e699207e1135d075d2251cd3e84cc96d82a910adf6020 - languageName: node - linkType: hard - -"regexp.prototype.flags@npm:^1.5.3": +"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.3": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -10650,11 +10248,11 @@ __metadata: linkType: hard "remark-github-blockquote-alert@npm:^1.0.0": - version: 1.2.1 - resolution: "remark-github-blockquote-alert@npm:1.2.1" + version: 1.3.0 + resolution: "remark-github-blockquote-alert@npm:1.3.0" dependencies: unist-util-visit: "npm:^5.0.0" - checksum: 10c0/48f70a56347ba6d2649ec647f9b126fe2e22ee4efcbc4962e1645967ac0994859a930a1af3a8b75c2989d55ed5b7ce2df6fc86a4b0f2c0aa39d5ed2162c857ca + checksum: 10c0/5582834300dadf71ad083c2c27f3f3c37c5487aa42cf73a4dc235d3d55d1edc8608c3d37b88032dc3335b5c7980580c97c2668129c89c21c4f477ebacd4ecd85 languageName: node linkType: hard @@ -10730,15 +10328,15 @@ __metadata: linkType: hard "resolve@npm:^1.19.0, resolve@npm:^1.22.4": - version: 1.22.8 - resolution: "resolve@npm:1.22.8" + version: 1.22.10 + resolution: "resolve@npm:1.22.10" dependencies: - is-core-module: "npm:^2.13.0" + is-core-module: "npm:^2.16.0" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/07e179f4375e1fd072cfb72ad66d78547f86e6196c4014b31cb0b8bb1db5f7ca871f922d08da0fbc05b94e9fd42206f819648fa3b5b873ebbc8e1dc68fec433a + checksum: 10c0/8967e1f4e2cc40f79b7e080b4582b9a8c5ee36ffb46041dccb20e6461161adf69f843b43067b4a375de926a2cd669157e29a29578191def399dd5ef89a1b5203 languageName: node linkType: hard @@ -10756,15 +10354,15 @@ __metadata: linkType: hard "resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": - version: 1.22.8 - resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" + version: 1.22.10 + resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" dependencies: - is-core-module: "npm:^2.13.0" + is-core-module: "npm:^2.16.0" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10c0/0446f024439cd2e50c6c8fa8ba77eaa8370b4180f401a96abf3d1ebc770ac51c1955e12764cde449fde3fff480a61f84388e3505ecdbab778f4bef5f8212c729 + checksum: 10c0/52a4e505bbfc7925ac8f4cd91fd8c4e096b6a89728b9f46861d3b405ac9a1ccf4dcbf8befb4e89a2e11370dacd0160918163885cbc669369590f2f31f4c58939 languageName: node linkType: hard @@ -10795,26 +10393,40 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^5.0.5": + version: 5.0.10 + resolution: "rimraf@npm:5.0.10" + dependencies: + glob: "npm:^10.3.7" + bin: + rimraf: dist/esm/bin.mjs + checksum: 10c0/7da4fd0e15118ee05b918359462cfa1e7fe4b1228c7765195a45b55576e8c15b95db513b8466ec89129666f4af45ad978a3057a02139afba1a63512a2d9644cc + languageName: node + linkType: hard + "rollup@npm:^4.20.0": - version: 4.24.0 - resolution: "rollup@npm:4.24.0" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.24.0" - "@rollup/rollup-android-arm64": "npm:4.24.0" - "@rollup/rollup-darwin-arm64": "npm:4.24.0" - "@rollup/rollup-darwin-x64": "npm:4.24.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.24.0" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.24.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.24.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.24.0" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.24.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.24.0" - "@rollup/rollup-linux-s390x-gnu": "npm:4.24.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.24.0" - "@rollup/rollup-linux-x64-musl": "npm:4.24.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.24.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.24.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.24.0" + version: 4.34.3 + resolution: "rollup@npm:4.34.3" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.34.3" + "@rollup/rollup-android-arm64": "npm:4.34.3" + "@rollup/rollup-darwin-arm64": "npm:4.34.3" + "@rollup/rollup-darwin-x64": "npm:4.34.3" + "@rollup/rollup-freebsd-arm64": "npm:4.34.3" + "@rollup/rollup-freebsd-x64": "npm:4.34.3" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.34.3" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.34.3" + "@rollup/rollup-linux-arm64-gnu": "npm:4.34.3" + "@rollup/rollup-linux-arm64-musl": "npm:4.34.3" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.34.3" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.34.3" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.34.3" + "@rollup/rollup-linux-s390x-gnu": "npm:4.34.3" + "@rollup/rollup-linux-x64-gnu": "npm:4.34.3" + "@rollup/rollup-linux-x64-musl": "npm:4.34.3" + "@rollup/rollup-win32-arm64-msvc": "npm:4.34.3" + "@rollup/rollup-win32-ia32-msvc": "npm:4.34.3" + "@rollup/rollup-win32-x64-msvc": "npm:4.34.3" "@types/estree": "npm:1.0.6" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -10826,6 +10438,10 @@ __metadata: optional: true "@rollup/rollup-darwin-x64": optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true "@rollup/rollup-linux-arm-gnueabihf": optional: true "@rollup/rollup-linux-arm-musleabihf": @@ -10834,6 +10450,8 @@ __metadata: optional: true "@rollup/rollup-linux-arm64-musl": optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true "@rollup/rollup-linux-powerpc64le-gnu": optional: true "@rollup/rollup-linux-riscv64-gnu": @@ -10854,33 +10472,33 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/77fb549c1de8afd1142d2da765adbb0cdab9f13c47df5217f00b5cf40b74219caa48c6ba2157f6249313ee81b6fa4c4fa8b3d2a0347ad6220739e00e580a808d - languageName: node - linkType: hard - -"rollup@npm:^4.23.0": - version: 4.31.0 - resolution: "rollup@npm:4.31.0" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.31.0" - "@rollup/rollup-android-arm64": "npm:4.31.0" - "@rollup/rollup-darwin-arm64": "npm:4.31.0" - "@rollup/rollup-darwin-x64": "npm:4.31.0" - "@rollup/rollup-freebsd-arm64": "npm:4.31.0" - "@rollup/rollup-freebsd-x64": "npm:4.31.0" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.31.0" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.31.0" - "@rollup/rollup-linux-arm64-gnu": "npm:4.31.0" - "@rollup/rollup-linux-arm64-musl": "npm:4.31.0" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.31.0" - "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.31.0" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.31.0" - "@rollup/rollup-linux-s390x-gnu": "npm:4.31.0" - "@rollup/rollup-linux-x64-gnu": "npm:4.31.0" - "@rollup/rollup-linux-x64-musl": "npm:4.31.0" - "@rollup/rollup-win32-arm64-msvc": "npm:4.31.0" - "@rollup/rollup-win32-ia32-msvc": "npm:4.31.0" - "@rollup/rollup-win32-x64-msvc": "npm:4.31.0" + checksum: 10c0/f5bb9f40f3e27b6f9c94a5c69e3e81fe4208ca631dd988064347890556694b0bc29543d81e5336921ce0b694cf7e2bce910b037342c899c0f7d36d82d917d1a1 + languageName: node + linkType: hard + +"rollup@npm:^4.30.1": + version: 4.34.4 + resolution: "rollup@npm:4.34.4" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.34.4" + "@rollup/rollup-android-arm64": "npm:4.34.4" + "@rollup/rollup-darwin-arm64": "npm:4.34.4" + "@rollup/rollup-darwin-x64": "npm:4.34.4" + "@rollup/rollup-freebsd-arm64": "npm:4.34.4" + "@rollup/rollup-freebsd-x64": "npm:4.34.4" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.34.4" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.34.4" + "@rollup/rollup-linux-arm64-gnu": "npm:4.34.4" + "@rollup/rollup-linux-arm64-musl": "npm:4.34.4" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.34.4" + "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.34.4" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.34.4" + "@rollup/rollup-linux-s390x-gnu": "npm:4.34.4" + "@rollup/rollup-linux-x64-gnu": "npm:4.34.4" + "@rollup/rollup-linux-x64-musl": "npm:4.34.4" + "@rollup/rollup-win32-arm64-msvc": "npm:4.34.4" + "@rollup/rollup-win32-ia32-msvc": "npm:4.34.4" + "@rollup/rollup-win32-x64-msvc": "npm:4.34.4" "@types/estree": "npm:1.0.6" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -10926,7 +10544,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/0d6da45098af14c678e78be887fefefbf5a97fef6277c5a1c24ca722537bb3a02e695c6fcad8880218d8fbef8a7a17d865786afd99bb6e70409fad73844ca8cf + checksum: 10c0/a81e2268be82ce431714ab13214b75750a066f9c5e3a29cc085963a4dd2f3bbff0b17c0a14227c0499aa513a5f3271622158e2bc3cc33a5462ee958a22f5517a languageName: node linkType: hard @@ -10937,6 +10555,13 @@ __metadata: languageName: node linkType: hard +"rrweb-cssom@npm:^0.8.0": + version: 0.8.0 + resolution: "rrweb-cssom@npm:0.8.0" + checksum: 10c0/56f2bfd56733adb92c0b56e274c43f864b8dd48784d6fe946ef5ff8d438234015e59ad837fc2ad54714b6421384141c1add4eb569e72054e350d1f8a50b8ac7b + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -10955,18 +10580,6 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.1.2": - version: 1.1.2 - resolution: "safe-array-concat@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - has-symbols: "npm:^1.0.3" - isarray: "npm:^2.0.5" - checksum: 10c0/12f9fdb01c8585e199a347eacc3bae7b5164ae805cdc8c6707199dbad5b9e30001a50a43c4ee24dc9ea32dbb7279397850e9208a7e217f4d8b1cf5d90129dec9 - languageName: node - linkType: hard - "safe-array-concat@npm:^1.1.3": version: 1.1.3 resolution: "safe-array-concat@npm:1.1.3" @@ -10997,17 +10610,6 @@ __metadata: languageName: node linkType: hard -"safe-regex-test@npm:^1.0.3": - version: 1.0.3 - resolution: "safe-regex-test@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-regex: "npm:^1.1.4" - checksum: 10c0/900bf7c98dc58f08d8523b7012b468e4eb757afa624f198902c0643d7008ba777b0bdc35810ba0b758671ce887617295fb742b3f3968991b178ceca54cb07603 - languageName: node - linkType: hard - "safe-regex-test@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex-test@npm:1.1.0" @@ -11068,11 +10670,11 @@ __metadata: linkType: hard "semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0": - version: 7.6.3 - resolution: "semver@npm:7.6.3" + version: 7.7.1 + resolution: "semver@npm:7.7.1" bin: semver: bin/semver.js - checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf + checksum: 10c0/fd603a6fb9c399c6054015433051bdbe7b99a940a8fb44b85c2b524c4004b023d7928d47cb22154f8d054ea7ee8597f586605e05b52047f048278e4ac56ae958 languageName: node linkType: hard @@ -11116,7 +10718,7 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": +"set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -11267,19 +10869,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4, side-channel@npm:^1.0.6": - version: 1.0.6 - resolution: "side-channel@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - object-inspect: "npm:^1.13.1" - checksum: 10c0/d2afd163dc733cc0a39aa6f7e39bf0c436293510dbccbff446733daeaf295857dbccf94297092ec8c53e2503acac30f0b78830876f0485991d62a90e9cad305f - languageName: node - linkType: hard - -"side-channel@npm:^1.1.0": +"side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -11314,13 +10904,13 @@ __metadata: linkType: hard "socks-proxy-agent@npm:^8.0.3": - version: 8.0.4 - resolution: "socks-proxy-agent@npm:8.0.4" + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" dependencies: - agent-base: "npm:^7.1.1" + agent-base: "npm:^7.1.2" debug: "npm:^4.3.4" socks: "npm:^2.8.3" - checksum: 10c0/345593bb21b95b0508e63e703c84da11549f0a2657d6b4e3ee3612c312cb3a907eac10e53b23ede3557c6601d63252103494caa306b66560f43af7b98f53957a + checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6 languageName: node linkType: hard @@ -11369,12 +10959,12 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^10.0.0": - version: 10.0.6 - resolution: "ssri@npm:10.0.6" +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" dependencies: minipass: "npm:^7.0.3" - checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 + checksum: 10c0/caddd5f544b2006e88fa6b0124d8d7b28208b83c72d7672d5ade44d794525d23b540f3396108c4eb9280dcb7c01f0bef50682f5b4b2c34291f7c5e211fd1417d languageName: node linkType: hard @@ -11400,9 +10990,9 @@ __metadata: linkType: hard "std-env@npm:^3.7.0": - version: 3.7.0 - resolution: "std-env@npm:3.7.0" - checksum: 10c0/60edf2d130a4feb7002974af3d5a5f3343558d1ccf8d9b9934d225c638606884db4a20d2fe6440a09605bca282af6b042ae8070a10490c0800d69e82e478f41e + version: 3.8.0 + resolution: "std-env@npm:3.8.0" + checksum: 10c0/f560a2902fd0fa3d648d7d0acecbd19d664006f7372c1fba197ed4c216b4c9e48db6e2769b5fe1616d42a9333c9f066c5011935035e85c59f45dc4f796272040 languageName: node linkType: hard @@ -11474,30 +11064,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.9": - version: 1.2.9 - resolution: "string.prototype.trim@npm:1.2.9" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.0" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/dcef1a0fb61d255778155006b372dff8cc6c4394bc39869117e4241f41a2c52899c0d263ffc7738a1f9e61488c490b05c0427faa15151efad721e1a9fb2663c2 - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimend@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/0a0b54c17c070551b38e756ae271865ac6cc5f60dabf2e7e343cceae7d9b02e1a1120a824e090e79da1b041a74464e8477e2da43e2775c85392be30a6f60963c - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.9": +"string.prototype.trimend@npm:^1.0.8, string.prototype.trimend@npm:^1.0.9": version: 1.0.9 resolution: "string.prototype.trimend@npm:1.0.9" dependencies: @@ -11587,15 +11154,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^5.3.0": - version: 5.5.0 - resolution: "supports-color@npm:5.5.0" - dependencies: - has-flag: "npm:^3.0.0" - checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 - languageName: node - linkType: hard - "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -11619,9 +11177,9 @@ __metadata: languageName: node linkType: hard -"swagger-typescript-api@npm:13.0.22": - version: 13.0.22 - resolution: "swagger-typescript-api@npm:13.0.22" +"swagger-typescript-api@npm:13.0.23": + version: 13.0.23 + resolution: "swagger-typescript-api@npm:13.0.23" dependencies: "@types/swagger-schema-official": "npm:^2.0.25" consola: "npm:^3.2.3" @@ -11638,7 +11196,7 @@ __metadata: bin: sta: ./dist/cli.js swagger-typescript-api: ./dist/cli.js - checksum: 10c0/ac3615201ed87686669888e52958045f9e2dba2452a6689fe6b2e6c14ef3006914a6c9b6e5a7931ebed66f7af94536eb9e42bf3b3f062ab76e7f5709a06a1e30 + checksum: 10c0/b322bbc264a7f4a078961a93692e4adace0b1c34bc3a912211404ea799ebcd4cc2a586dc4cc9fc0f9404cbe90a6137aab2341f6a10239602972740c979c51ade languageName: node linkType: hard @@ -11672,17 +11230,17 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.1.11, tar@npm:^6.2.1": - version: 6.2.1 - resolution: "tar@npm:6.2.1" +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" dependencies: - chownr: "npm:^2.0.0" - fs-minipass: "npm:^2.0.0" - minipass: "npm:^5.0.0" - minizlib: "npm:^2.1.1" - mkdirp: "npm:^1.0.3" - yallist: "npm:^4.0.0" - checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.0.1" + mkdirp: "npm:^3.0.1" + yallist: "npm:^5.0.0" + checksum: 10c0/d4679609bb2a9b48eeaf84632b6d844128d2412b95b6de07d53d8ee8baf4ca0857c9331dfa510390a0727b550fd543d4d1a10995ad86cdf078423fbb8d99831d languageName: node linkType: hard @@ -11693,13 +11251,6 @@ __metadata: languageName: node linkType: hard -"tiny-warning@npm:^1.0.2": - version: 1.0.3 - resolution: "tiny-warning@npm:1.0.3" - checksum: 10c0/ef8531f581b30342f29670cb41ca248001c6fd7975ce22122bd59b8d62b4fc84ad4207ee7faa95cde982fa3357cd8f4be650142abc22805538c3b1392d7084fa - languageName: node - linkType: hard - "tinybench@npm:^2.9.0": version: 2.9.0 resolution: "tinybench@npm:2.9.0" @@ -11715,16 +11266,16 @@ __metadata: linkType: hard "tinyexec@npm:^0.3.0": - version: 0.3.1 - resolution: "tinyexec@npm:0.3.1" - checksum: 10c0/11e7a7c5d8b3bddf8b5cbe82a9290d70a6fad84d528421d5d18297f165723cb53d2e737d8f58dcce5ca56f2e4aa2d060f02510b1f8971784f97eb3e9aec28f09 + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90 languageName: node linkType: hard "tinypool@npm:^1.0.0": - version: 1.0.1 - resolution: "tinypool@npm:1.0.1" - checksum: 10c0/90939d6a03f1519c61007bf416632dc1f0b9c1a9dd673c179ccd9e36a408437384f984fc86555a5d040d45b595abc299c3bb39d354439e98a090766b5952e73d + version: 1.0.2 + resolution: "tinypool@npm:1.0.2" + checksum: 10c0/31ac184c0ff1cf9a074741254fe9ea6de95026749eb2b8ec6fd2b9d8ca94abdccda731f8e102e7f32e72ed3b36d32c6975fd5f5523df3f1b6de6c3d8dfd95e63 languageName: node linkType: hard @@ -11735,28 +11286,28 @@ __metadata: languageName: node linkType: hard -"tinyspy@npm:^3.0.0": +"tinyspy@npm:^3.0.0, tinyspy@npm:^3.0.2": version: 3.0.2 resolution: "tinyspy@npm:3.0.2" checksum: 10c0/55ffad24e346622b59292e097c2ee30a63919d5acb7ceca87fc0d1c223090089890587b426e20054733f97a58f20af2c349fb7cc193697203868ab7ba00bcea0 languageName: node linkType: hard -"tldts-core@npm:^6.1.54": - version: 6.1.54 - resolution: "tldts-core@npm:6.1.54" - checksum: 10c0/acf7245a4e1fdda55de929b1691e7272cde4b2d2ca5f0cb3009abaf42792ba25e7b9ee353a88f682895ca8adc560c082924c97e12995d33623b925ed43f6a4b8 +"tldts-core@npm:^6.1.76": + version: 6.1.76 + resolution: "tldts-core@npm:6.1.76" + checksum: 10c0/597a17715198f77cb8da98049d1cbb2684083c09c18e4957121009dea6aaa862dc1a2829f5d81a5306e49cd7b8f5316b5de82db64841acc9b570d7ada6e97f3e languageName: node linkType: hard "tldts@npm:^6.1.32": - version: 6.1.54 - resolution: "tldts@npm:6.1.54" + version: 6.1.76 + resolution: "tldts@npm:6.1.76" dependencies: - tldts-core: "npm:^6.1.54" + tldts-core: "npm:^6.1.76" bin: tldts: bin/cli.js - checksum: 10c0/c2aee449fec572aade90a03457d6bc281c22fbbb5fc787d6f803da4eac1c69a95584c1c57b5c8a573c336b4b81aca8796368d23489de500b5cf2da8e87976afd + checksum: 10c0/86173db1b152c4b8468777ec3b78b1e811a4ac5eb3ac34d077f7d72b11e6f14637b540e21464a522403bf034d5dcb6a2d5ea21d69a3d0cd1e9ae05a0e77624ad languageName: node linkType: hard @@ -11777,11 +11328,11 @@ __metadata: linkType: hard "tough-cookie@npm:^5.0.0": - version: 5.0.0 - resolution: "tough-cookie@npm:5.0.0" + version: 5.1.0 + resolution: "tough-cookie@npm:5.1.0" dependencies: tldts: "npm:^6.1.32" - checksum: 10c0/4a69c885bf6f45c5a64e60262af99e8c0d58a33bd3d0ce5da62121eeb9c00996d0128a72df8fc4614cbde59cc8b70aa3e21e4c3c98c2bbde137d7aba7fa00124 + checksum: 10c0/cae151040c9fc43169a1cac5af5c6d56aa3d31435b985fd5749669430d45a0c3a3be03991b210af40c1aa175050955b57509f8d275bd06735e7e268a7e0b78af languageName: node linkType: hard @@ -11815,21 +11366,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" - peerDependencies: - typescript: ">=4.2.0" - checksum: 10c0/f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c - languageName: node - linkType: hard - -"ts-api-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "ts-api-utils@npm:2.0.0" +"ts-api-utils@npm:^2.0.0, ts-api-utils@npm:^2.0.1": + version: 2.0.1 + resolution: "ts-api-utils@npm:2.0.1" peerDependencies: typescript: ">=4.8.4" - checksum: 10c0/6165e29a5b75bd0218e3cb0f9ee31aa893dbd819c2e46dbb086c841121eb0436ed47c2c18a20cb3463d74fd1fb5af62e2604ba5971cc48e5b38ebbdc56746dfc + checksum: 10c0/23fd56a958b332cac00150a652e4c84730df30571bd2faa1ba6d7b511356d1a61656621492bb6c7f15dd6e18847a1408357a0e406671d358115369a17f5bfedd languageName: node linkType: hard @@ -11845,17 +11387,32 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2, tslib@npm:^2.7.0": +"tslib@npm:2, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.7.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 languageName: node linkType: hard -"tslib@npm:^2.1.0, tslib@npm:^2.4.0": - version: 2.8.0 - resolution: "tslib@npm:2.8.0" - checksum: 10c0/31e4d14dc1355e9b89e4d3c893a18abb7f90b6886b089c2da91224d0a7752c79f3ddc41bc1aa0a588ac895bd97bb99c5bc2bfdb2f86de849f31caeb3ba79bbe5 +"tss-react@npm:4.9.15": + version: 4.9.15 + resolution: "tss-react@npm:4.9.15" + dependencies: + "@emotion/cache": "npm:*" + "@emotion/serialize": "npm:*" + "@emotion/utils": "npm:*" + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/server": ^11.4.0 + "@mui/material": ^5.0.0 || ^6.0.0 + "@types/react": ^16.8.0 || ^17.0.2 || ^18.0.0 || ^19.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/server": + optional: true + "@mui/material": + optional: true + checksum: 10c0/f11069b19ec276f34a26f5f4a987c53f7898a16dcb344b3102c977070ce1a378ae14fa8a84330b2554564206d15c781cd7d181df89fc1c5039ce84047f6c9f33 languageName: node linkType: hard @@ -11915,17 +11472,6 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-buffer@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/9e043eb38e1b4df4ddf9dde1aa64919ae8bb909571c1cc4490ba777d55d23a0c74c7d73afcdd29ec98616d91bb3ae0f705fad4421ea147e1daf9528200b562da - languageName: node - linkType: hard - "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -11937,19 +11483,6 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "typed-array-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/fcebeffb2436c9f355e91bd19e2368273b88c11d1acc0948a2a306792f1ab672bce4cfe524ab9f51a0505c9d7cd1c98eff4235c4f6bfef6a198f6cfc4ff3d4f3 - languageName: node - linkType: hard - "typed-array-byte-length@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-byte-length@npm:1.0.3" @@ -11963,20 +11496,6 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-byte-offset@npm:1.0.2" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10c0/d2628bc739732072e39269389a758025f75339de2ed40c4f91357023c5512d237f255b633e3106c461ced41907c1bf9a533c7e8578066b0163690ca8bc61b22f - languageName: node - linkType: hard - "typed-array-byte-offset@npm:^1.0.4": version: 1.0.4 resolution: "typed-array-byte-offset@npm:1.0.4" @@ -11992,20 +11511,6 @@ __metadata: languageName: node linkType: hard -"typed-array-length@npm:^1.0.6": - version: 1.0.6 - resolution: "typed-array-length@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - possible-typed-array-names: "npm:^1.0.0" - checksum: 10c0/74253d7dc488eb28b6b2711cf31f5a9dcefc9c41b0681fd1c178ed0a1681b4468581a3626d39cd4df7aee3d3927ab62be06aa9ca74e5baf81827f61641445b77 - languageName: node - linkType: hard - "typed-array-length@npm:^1.0.7": version: 1.0.7 resolution: "typed-array-length@npm:1.0.7" @@ -12034,13 +11539,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.7.2": - version: 5.7.2 - resolution: "typescript@npm:5.7.2" +"typescript@npm:5.7.3": + version: 5.7.3 + resolution: "typescript@npm:5.7.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/a873118b5201b2ef332127ef5c63fb9d9c155e6fdbe211cbd9d8e65877283797cca76546bad742eea36ed7efbe3424a30376818f79c7318512064e8625d61622 + checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa languageName: node linkType: hard @@ -12054,13 +11559,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.7.2#optional!builtin": - version: 5.7.2 - resolution: "typescript@patch:typescript@npm%3A5.7.2#optional!builtin::version=5.7.2&hash=5786d5" +"typescript@patch:typescript@npm%3A5.7.3#optional!builtin": + version: 5.7.3 + resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin::version=5.7.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/f3b8082c9d1d1629a215245c9087df56cb784f9fb6f27b5d55577a20e68afe2a889c040aacff6d27e35be165ecf9dca66e694c42eb9a50b3b2c451b36b5675cb + checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4 languageName: node linkType: hard @@ -12074,18 +11579,6 @@ __metadata: languageName: node linkType: hard -"unbox-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - has-bigints: "npm:^1.0.2" - has-symbols: "npm:^1.0.3" - which-boxed-primitive: "npm:^1.0.2" - checksum: 10c0/81ca2e81134167cc8f75fa79fbcc8a94379d6c61de67090986a2273850989dd3bae8440c163121b77434b68263e34787a675cbdcb34bb2f764c6b9c843a11b66 - languageName: node - linkType: hard - "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -12098,13 +11591,6 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344 - languageName: node - linkType: hard - "undici-types@npm:~6.20.0": version: 6.20.0 resolution: "undici-types@npm:6.20.0" @@ -12147,21 +11633,21 @@ __metadata: languageName: node linkType: hard -"unique-filename@npm:^3.0.0": - version: 3.0.0 - resolution: "unique-filename@npm:3.0.0" +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" dependencies: - unique-slug: "npm:^4.0.0" - checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f + unique-slug: "npm:^5.0.0" + checksum: 10c0/38ae681cceb1408ea0587b6b01e29b00eee3c84baee1e41fd5c16b9ed443b80fba90c40e0ba69627e30855570a34ba8b06702d4a35035d4b5e198bf5a64c9ddc languageName: node linkType: hard -"unique-slug@npm:^4.0.0": - version: 4.0.0 - resolution: "unique-slug@npm:4.0.0" +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" dependencies: imurmurhash: "npm:^0.1.4" - checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 + checksum: 10c0/d324c5a44887bd7e105ce800fcf7533d43f29c48757ac410afd42975de82cc38ea2035c0483f4de82d186691bf3208ef35c644f73aa2b1b20b8e651be5afd293 languageName: node linkType: hard @@ -12288,16 +11774,16 @@ __metadata: linkType: hard "update-browserslist-db@npm:^1.1.1": - version: 1.1.1 - resolution: "update-browserslist-db@npm:1.1.1" + version: 1.1.2 + resolution: "update-browserslist-db@npm:1.1.2" dependencies: escalade: "npm:^3.2.0" - picocolors: "npm:^1.1.0" + picocolors: "npm:^1.1.1" peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 10c0/536a2979adda2b4be81b07e311bd2f3ad5e978690987956bc5f514130ad50cac87cd22c710b686d79731e00fbee8ef43efe5fcd72baa241045209195d43dcc80 + checksum: 10c0/9cb353998d6d7d6ba1e46b8fa3db888822dd972212da4eda609d185eb5c3557a93fd59780ceb757afd4d84240518df08542736969e6a5d6d6ce2d58e9363aac6 languageName: node linkType: hard @@ -12310,16 +11796,7 @@ __metadata: languageName: node linkType: hard -"use-sync-external-store@npm:1.2.2": - version: 1.2.2 - resolution: "use-sync-external-store@npm:1.2.2" - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 10c0/23b1597c10adf15b26ade9e8c318d8cc0abc9ec0ab5fc7ca7338da92e89c2536abd150a5891bf076836c352fdfa104fc7231fb48f806fd9960e0cbe03601abaf - languageName: node - linkType: hard - -"use-sync-external-store@npm:^1.4.0": +"use-sync-external-store@npm:^1.2.2, use-sync-external-store@npm:^1.4.0": version: 1.4.0 resolution: "use-sync-external-store@npm:1.4.0" peerDependencies: @@ -12328,14 +11805,14 @@ __metadata: languageName: node linkType: hard -"usehooks-ts@npm:3.1.0": - version: 3.1.0 - resolution: "usehooks-ts@npm:3.1.0" +"usehooks-ts@npm:3.1.1": + version: 3.1.1 + resolution: "usehooks-ts@npm:3.1.1" dependencies: lodash.debounce: "npm:^4.0.8" peerDependencies: - react: ^16.8.0 || ^17 || ^18 - checksum: 10c0/2204d8c95109302bdaaa51a66bf216f3dba750f1d2795c20ecba75ba1c44a070a253935d537ef536514ab6e363bcc02ccc78b5ad63576ff8d880d577cf3fc48f + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + checksum: 10c0/8bbebf52b063f2e705eb27364f08ec2eff987b9e8d28d82a28248652dd89ef53cb514e1f2ee1cbc6ac6e083a8dce86310301c3e92a99902b98c32a26381202d7 languageName: node linkType: hard @@ -12346,12 +11823,12 @@ __metadata: languageName: node linkType: hard -"uuid@npm:11.0.3": - version: 11.0.3 - resolution: "uuid@npm:11.0.3" +"uuid@npm:11.0.5": + version: 11.0.5 + resolution: "uuid@npm:11.0.5" bin: uuid: dist/esm/bin/uuid - checksum: 10c0/cee762fc76d949a2ff9205770334699e0043d52bb766472593a25f150077c9deed821230251ea3d6ab3943a5ea137d2826678797f1d5f6754c7ce5ce27e9f7a6 + checksum: 10c0/6f59f0c605e02c14515401084ca124b9cb462b4dcac866916a49862bcf831874508a308588c23a7718269226ad11a92da29b39d761ad2b86e736623e3a33b6e7 languageName: node linkType: hard @@ -12413,14 +11890,14 @@ __metadata: languageName: node linkType: hard -"vite@npm:6.0.9": - version: 6.0.9 - resolution: "vite@npm:6.0.9" +"vite@npm:6.1.0": + version: 6.1.0 + resolution: "vite@npm:6.1.0" dependencies: esbuild: "npm:^0.24.2" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.49" - rollup: "npm:^4.23.0" + postcss: "npm:^8.5.1" + rollup: "npm:^4.30.1" peerDependencies: "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 jiti: ">=1.21.0" @@ -12461,13 +11938,13 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/b36f0f51318d6c33184da31e280862f23ef89712884e088b864c9edf112d65f6cf6795f201916e370a4434575fd3e2868f07f3bd63c6bdd5c2ae2295fa7f6d8a + checksum: 10c0/e1cad1cfbd29923a37d2dbd60f7387901ed8356758073a0226cbe844fd032425ba3bf41651332cab4965d5c54d0b51d208889ff32ce81bd282d230c0c9f0f8f1 languageName: node linkType: hard "vite@npm:^5.0.0": - version: 5.4.10 - resolution: "vite@npm:5.4.10" + version: 5.4.14 + resolution: "vite@npm:5.4.14" dependencies: esbuild: "npm:^0.21.3" fsevents: "npm:~2.3.3" @@ -12504,7 +11981,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/4ef4807d2fd166a920de244dbcec791ba8a903b017a7d8e9f9b4ac40d23f8152c1100610583d08f542b47ca617a0505cfc5f8407377d610599d58296996691ed + checksum: 10c0/8842933bd70ca6a98489a0bb9c8464bec373de00f9a97c8c7a4e64b24d15c88bfaa8c1acb38a68c3e5eb49072ffbccb146842c2d4edcdd036a9802964cffe3d1 languageName: node linkType: hard @@ -12604,12 +12081,12 @@ __metadata: linkType: hard "whatwg-url@npm:^14.0.0": - version: 14.0.0 - resolution: "whatwg-url@npm:14.0.0" + version: 14.1.0 + resolution: "whatwg-url@npm:14.1.0" dependencies: tr46: "npm:^5.0.0" webidl-conversions: "npm:^7.0.0" - checksum: 10c0/ac32e9ba9d08744605519bbe9e1371174d36229689ecc099157b6ba102d4251a95e81d81f3d80271eb8da182eccfa65653f07f0ab43ea66a6934e643fd091ba9 + checksum: 10c0/f00104f1c67ce086ba8ffedab529cbbd9aefd8c0a6555320026de7aeff31f91c38680f95818b140a7c9cc657cde3781e567835dda552ddb1e2b8faaba0ac3cb6 languageName: node linkType: hard @@ -12623,19 +12100,6 @@ __metadata: languageName: node linkType: hard -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" - dependencies: - is-bigint: "npm:^1.0.1" - is-boolean-object: "npm:^1.1.0" - is-number-object: "npm:^1.0.4" - is-string: "npm:^1.0.5" - is-symbol: "npm:^1.0.3" - checksum: 10c0/0a62a03c00c91dd4fb1035b2f0733c341d805753b027eebd3a304b9cb70e8ce33e25317add2fe9b5fea6f53a175c0633ae701ff812e604410ddd049777cd435e - languageName: node - linkType: hard - "which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": version: 1.1.1 resolution: "which-boxed-primitive@npm:1.1.1" @@ -12682,19 +12146,6 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15": - version: 1.1.15 - resolution: "which-typed-array@npm:1.1.15" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-tostringtag: "npm:^1.0.2" - checksum: 10c0/4465d5348c044032032251be54d8988270e69c6b7154f8fcb2a47ff706fe36f7624b3a24246b8d9089435a8f4ec48c1c1025c5d6b499456b9e5eff4f48212983 - languageName: node - linkType: hard - "which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18": version: 1.1.18 resolution: "which-typed-array@npm:1.1.18" @@ -12720,14 +12171,14 @@ __metadata: languageName: node linkType: hard -"which@npm:^4.0.0": - version: 4.0.0 - resolution: "which@npm:4.0.0" +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" dependencies: isexe: "npm:^3.1.1" bin: node-which: bin/which.js - checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a + checksum: 10c0/e556e4cd8b7dbf5df52408c9a9dd5ac6518c8c5267c8953f5b0564073c66ed5bf9503b14d876d0e9c7844d4db9725fb0dcf45d6e911e17e26ab363dc3965ae7b languageName: node linkType: hard @@ -12847,6 +12298,13 @@ __metadata: languageName: node linkType: hard +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 + languageName: node + linkType: hard + "yaml@npm:^1.10.0": version: 1.10.2 resolution: "yaml@npm:1.10.2" @@ -12919,10 +12377,10 @@ __metadata: linkType: hard "zustand@npm:^4.4.0": - version: 4.5.5 - resolution: "zustand@npm:4.5.5" + version: 4.5.6 + resolution: "zustand@npm:4.5.6" dependencies: - use-sync-external-store: "npm:1.2.2" + use-sync-external-store: "npm:^1.2.2" peerDependencies: "@types/react": ">=16.8" immer: ">=9.0.6" @@ -12934,7 +12392,7 @@ __metadata: optional: true react: optional: true - checksum: 10c0/d04469d76b29c7e4070da269886de4efdadedd3d3824dc2a06ac4ff62e3b5877f925e927afe7382de651829872b99adec48082f1bd69fe486149be666345e626 + checksum: 10c0/5b39aff2ef57e5a8ada647261ec1115697d397be311c51461d9ea81b5b63c6d2c498b960477ad2db72dc21db6aa229a92bdf644f6a8ecf7b1d71df5b4a5e95d3 languageName: node linkType: hard diff --git a/openbas-model/pom.xml b/openbas-model/pom.xml index b5f1fbca1f..0da0d9d574 100644 --- a/openbas-model/pom.xml +++ b/openbas-model/pom.xml @@ -6,7 +6,7 @@ io.openbas openbas-platform - 1.11.4 + 1.11.5 openbas-model diff --git a/openbas-model/src/main/java/io/openbas/database/model/Asset.java b/openbas-model/src/main/java/io/openbas/database/model/Asset.java index eee6bbb5b3..e8dc19a5ea 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Asset.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Asset.java @@ -34,6 +34,7 @@ public class Asset implements Base { @UuidGenerator @JsonProperty("asset_id") @NotBlank + @Queryable(filterable = true) private String id; @Column(name = "asset_type", insertable = false, updatable = false) diff --git a/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraceAction.java b/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraceAction.java index 45ae6a8624..f1de9aaf34 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraceAction.java +++ b/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraceAction.java @@ -1,6 +1,7 @@ package io.openbas.database.model; public enum ExecutionTraceAction { + START, PREREQUISITE_CHECK, PREREQUISITE_EXECUTION, diff --git a/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraces.java b/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraces.java index efdbe10485..2c65d17c10 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraces.java +++ b/openbas-model/src/main/java/io/openbas/database/model/ExecutionTraces.java @@ -85,7 +85,7 @@ public class ExecutionTraces implements Base { private Instant updateDate = now(); public List getIdentifiers() { - return List.of(identifiers); + return identifiers == null ? List.of() : List.of(identifiers); } @Override @@ -94,37 +94,40 @@ public int hashCode() { } public static ExecutionTraces getNewErrorTrace(String message, ExecutionTraceAction action) { - return new ExecutionTraces(null, ExecutionTraceStatus.ERROR, null, message, action, null); + return new ExecutionTraces(null, ExecutionTraceStatus.ERROR, null, message, action, null, null); } public static ExecutionTraces getNewErrorTrace( String message, ExecutionTraceAction action, Agent agent) { - return new ExecutionTraces(null, ExecutionTraceStatus.ERROR, null, message, action, agent); + return new ExecutionTraces( + null, ExecutionTraceStatus.ERROR, null, message, action, agent, null); } public static ExecutionTraces getNewSuccessTrace(String message, ExecutionTraceAction action) { - return new ExecutionTraces(null, ExecutionTraceStatus.SUCCESS, null, message, action, null); + return new ExecutionTraces( + null, ExecutionTraceStatus.SUCCESS, null, message, action, null, null); } public static ExecutionTraces getNewSuccessTrace( String message, ExecutionTraceAction category, List identifiers) { return new ExecutionTraces( - null, ExecutionTraceStatus.SUCCESS, identifiers, message, category, null); + null, ExecutionTraceStatus.SUCCESS, identifiers, message, category, null, null); } public static ExecutionTraces getNewInfoTrace(String message, ExecutionTraceAction action) { - return new ExecutionTraces(null, ExecutionTraceStatus.INFO, null, message, action, null); + return new ExecutionTraces(null, ExecutionTraceStatus.INFO, null, message, action, null, null); } public static ExecutionTraces getNewInfoTrace( String message, ExecutionTraceAction action, List identifiers) { - return new ExecutionTraces(null, ExecutionTraceStatus.INFO, identifiers, message, action, null); + return new ExecutionTraces( + null, ExecutionTraceStatus.INFO, identifiers, message, action, null, null); } public static ExecutionTraces getNewInfoTrace( String message, ExecutionTraceAction action, Agent agent, List identifiers) { return new ExecutionTraces( - null, ExecutionTraceStatus.INFO, identifiers, message, action, agent); + null, ExecutionTraceStatus.INFO, identifiers, message, action, agent, null); } public ExecutionTraces() {} @@ -135,12 +138,13 @@ public ExecutionTraces( List identifiers, String message, ExecutionTraceAction action, - Agent agent) { + Agent agent, + Instant time) { this.injectStatus = injectStatus; this.status = status; this.identifiers = identifiers == null ? new String[0] : identifiers.toArray(new String[0]); this.message = message; - this.time = Instant.now(); + this.time = time == null ? Instant.now() : time; this.action = action; this.agent = agent; } diff --git a/openbas-model/src/main/java/io/openbas/database/model/Grant.java b/openbas-model/src/main/java/io/openbas/database/model/Grant.java index 3da17322bb..60d7dc9337 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Grant.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Grant.java @@ -29,33 +29,35 @@ public enum GRANT_TYPE { @UuidGenerator @JsonProperty("grant_id") @NotBlank + @Schema(description = "Id of the grant") private String id; @Column(name = "grant_name") @JsonProperty("grant_name") @Enumerated(EnumType.STRING) @NotNull + @Schema(description = "Name of the grant") private GRANT_TYPE name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "grant_group") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("grant_group") - @Schema(type = "string") + @Schema(description = "Group ID of the grant") private Group group; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "grant_exercise") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("grant_exercise") - @Schema(type = "string") + @Schema(description = "Simulation ID of the grant") private Exercise exercise; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "grant_scenario") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("grant_scenario") - @Schema(type = "string") + @Schema(description = "Scenario ID of the grant") private Scenario scenario; @Override diff --git a/openbas-model/src/main/java/io/openbas/database/model/InjectStatus.java b/openbas-model/src/main/java/io/openbas/database/model/InjectStatus.java index 940cb1c43e..5ec30e52f4 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/InjectStatus.java +++ b/openbas-model/src/main/java/io/openbas/database/model/InjectStatus.java @@ -1,5 +1,6 @@ package io.openbas.database.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import io.hypersistence.utils.hibernate.type.json.JsonType; import jakarta.persistence.*; @@ -17,7 +18,6 @@ @Table(name = "injects_statuses") public class InjectStatus extends BaseInjectStatus { - // commands lines tracking @Type(JsonType.class) @Column(name = "status_payload_output", columnDefinition = "json") @JsonProperty("status_payload_output") @@ -36,6 +36,7 @@ public List statusIdentifiers() { return this.getTraces().stream().flatMap(ex -> ex.getIdentifiers().stream()).toList(); } + @JsonIgnore public Map getStatusMapIdentifierAgent() { Map info = new HashMap<>(); this.getTraces() @@ -56,26 +57,29 @@ public void addTrace(ExecutionTraces trace) { public void addTrace( ExecutionTraceStatus status, String message, ExecutionTraceAction action, Agent agent) { - ExecutionTraces newTrace = new ExecutionTraces(this, status, List.of(), message, action, agent); + ExecutionTraces newTrace = + new ExecutionTraces(this, status, List.of(), message, action, agent, null); this.getTraces().add(newTrace); } public void addMayBePreventedTrace(String message, ExecutionTraceAction action, Agent agent) { ExecutionTraces newTrace = new ExecutionTraces( - this, ExecutionTraceStatus.MAYBE_PREVENTED, List.of(), message, action, agent); + this, ExecutionTraceStatus.MAYBE_PREVENTED, List.of(), message, action, agent, null); this.getTraces().add(newTrace); } - public void addSuccess(String message, ExecutionTraceAction action, Agent agent) { + public void addErrorTrace(String message, ExecutionTraceAction action) { ExecutionTraces newTrace = - new ExecutionTraces(this, ExecutionTraceStatus.SUCCESS, List.of(), message, action, agent); + new ExecutionTraces( + this, ExecutionTraceStatus.ERROR, List.of(), message, action, null, null); this.getTraces().add(newTrace); } - public void addErrorTrace(String message, ExecutionTraceAction action) { + public void addInfoTrace(String message, ExecutionTraceAction action) { ExecutionTraces newTrace = - new ExecutionTraces(this, ExecutionTraceStatus.ERROR, List.of(), message, action, null); + new ExecutionTraces( + this, ExecutionTraceStatus.INFO, List.of(), message, action, null, null); this.getTraces().add(newTrace); } } diff --git a/openbas-model/src/main/java/io/openbas/database/model/InjectTestStatus.java b/openbas-model/src/main/java/io/openbas/database/model/InjectTestStatus.java index 582dda8aa5..ef026d98bd 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/InjectTestStatus.java +++ b/openbas-model/src/main/java/io/openbas/database/model/InjectTestStatus.java @@ -5,7 +5,6 @@ import java.time.Instant; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; @@ -15,32 +14,7 @@ @Getter @Entity @Table(name = "injects_tests_statuses") -public class InjectTestStatus extends BaseInjectStatus implements Base { - - @JsonProperty("inject_id") - public String getInjectId() { - return inject.getId(); - } - - @JsonProperty("inject_title") - public String getInjectTitle() { - return inject.getTitle(); - } - - @JsonProperty("injector_contract") - public Optional getInjectContract() { - return inject.getInjectorContract(); - } - - @JsonProperty("inject_type") - private String getType() { - return inject - .getInjectorContract() - .map(InjectorContract::getInjector) - .map(Injector::getType) - .orElse(null); - } - +public class InjectTestStatus extends BaseInjectStatus { @OneToMany( mappedBy = "injectTestStatus", cascade = CascadeType.ALL, diff --git a/openbas-model/src/main/java/io/openbas/database/model/InjectorContract.java b/openbas-model/src/main/java/io/openbas/database/model/InjectorContract.java index 7d9f66a301..d8c55d244a 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/InjectorContract.java +++ b/openbas-model/src/main/java/io/openbas/database/model/InjectorContract.java @@ -167,6 +167,8 @@ public int hashCode() { public static final String CONTACT_ELEMENT_CONTENT_KEY = "key"; public static final String CONTACT_ELEMENT_CONTENT_MANDATORY = "mandatory"; public static final String CONTACT_ELEMENT_CONTENT_MANDATORY_GROUPS = "mandatoryGroups"; + public static final String CONTACT_ELEMENT_CONTENT_MANDATORY_CONDITIONAL = + "mandatoryConditionField"; public static final String CONTACT_ELEMENT_CONTENT_KEY_ASSETS = "assets"; public static final String CONTACT_ELEMENT_CONTENT_KEY_TEAMS = "teams"; diff --git a/openbas-model/src/main/java/io/openbas/database/model/KillChainPhase.java b/openbas-model/src/main/java/io/openbas/database/model/KillChainPhase.java index 5e74ebd669..d598b42bbf 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/KillChainPhase.java +++ b/openbas-model/src/main/java/io/openbas/database/model/KillChainPhase.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openbas.annotation.Queryable; import io.openbas.database.audit.ModelBaseListener; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -24,51 +25,61 @@ public class KillChainPhase implements Base { @UuidGenerator @JsonProperty("phase_id") @NotBlank + @Schema(description = "ID of the kill chain phase") private String id; @Column(name = "phase_external_id") @JsonProperty("phase_external_id") @NotBlank + @Schema(description = "External ID of the kill chain phase") private String externalId; @Column(name = "phase_stix_id") @JsonProperty("phase_stix_id") + @Schema(description = "Stix ID of the kill chain phase") private String stixId; @Queryable(searchable = true, filterable = true, sortable = true) @Column(name = "phase_name") @JsonProperty("phase_name") @NotBlank + @Schema(description = "Name of the kill chain phase") private String name; @Column(name = "phase_shortname") @JsonProperty("phase_shortname") @NotBlank + @Schema(description = "Short name of the kill chain phase") private String shortName; @Queryable(searchable = true, sortable = true) @Column(name = "phase_kill_chain_name") @JsonProperty("phase_kill_chain_name") @NotBlank + @Schema(description = "Name of the kill chain") private String killChainName; @Column(name = "phase_description") @JsonProperty("phase_description") + @Schema(description = "Description of the kill chain phase") private String description; @Queryable(sortable = true) @Column(name = "phase_order") @JsonProperty("phase_order") + @Schema(description = "Order of the kill chain phase") private Long order = 0L; @Queryable(sortable = true) @Column(name = "phase_created_at") @JsonProperty("phase_created_at") @NotNull + @Schema(description = "Creation date of the kill chain phase") private Instant createdAt = now(); @Column(name = "phase_updated_at") @JsonProperty("phase_updated_at") @NotNull + @Schema(description = "Update date of the kill chain phase") private Instant updatedAt = now(); } diff --git a/openbas-model/src/main/java/io/openbas/database/model/LessonsCategory.java b/openbas-model/src/main/java/io/openbas/database/model/LessonsCategory.java index af5e0ca099..6d27c5e516 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/LessonsCategory.java +++ b/openbas-model/src/main/java/io/openbas/database/model/LessonsCategory.java @@ -33,43 +33,49 @@ public class LessonsCategory implements Base { @UuidGenerator @JsonProperty("lessonscategory_id") @NotBlank + @Schema(description = "ID of the lesson category") private String id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "lessons_category_exercise") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("lessons_category_exercise") - @Schema(type = "string") + @Schema(description = "Simulation ID of the lesson category") private Exercise exercise; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "lessons_category_scenario") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("lessons_category_scenario") - @Schema(type = "string") + @Schema(description = "Scenario ID of the lesson category") private Scenario scenario; @Column(name = "lessons_category_created_at") @JsonProperty("lessons_category_created_at") @NotNull + @Schema(description = "Creation date of the lesson category") private Instant created = now(); @Column(name = "lessons_category_updated_at") @JsonProperty("lessons_category_updated_at") @NotNull + @Schema(description = "Update date of the lesson category") private Instant updated = now(); @Column(name = "lessons_category_name") @JsonProperty("lessons_category_name") @NotBlank + @Schema(description = "Name of the lesson category") private String name; @Column(name = "lessons_category_description") @JsonProperty("lessons_category_description") + @Schema(description = "Description of the lesson category") private String description; @Column(name = "lessons_category_order") @JsonProperty("lessons_category_order") + @Schema(description = "Order of the lesson category") private int order; @ManyToMany(fetch = FetchType.LAZY) @@ -79,17 +85,19 @@ public class LessonsCategory implements Base { inverseJoinColumns = @JoinColumn(name = "team_id")) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("lessons_category_teams") - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(type = "string", description = "Team IDs of the lesson category")) private List teams = new ArrayList<>(); @OneToMany(mappedBy = "category", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JsonProperty("lessons_category_questions") @JsonSerialize(using = MultiIdListDeserializer.class) - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = @Schema(type = "string", description = "Question IDs of the lesson category")) private List questions = new ArrayList<>(); // region transient @JsonProperty("lessons_category_users") + @Schema(description = "User IDs of the lesson category") public List getUsers() { return getTeams().stream().flatMap(team -> team.getUsers().stream().map(User::getId)).toList(); } diff --git a/openbas-model/src/main/java/io/openbas/database/model/Objective.java b/openbas-model/src/main/java/io/openbas/database/model/Objective.java index 4f7df26c42..db55ec9483 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Objective.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Objective.java @@ -33,52 +33,60 @@ public class Objective implements Base { @UuidGenerator @JsonProperty("objective_id") @NotBlank + @Schema(description = "ID of the objective") private String id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "objective_exercise") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("objective_exercise") - @Schema(type = "string") + @Schema(description = "Simulation ID of the objective") private Exercise exercise; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "objective_scenario") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("objective_scenario") - @Schema(type = "string") + @Schema(description = "Scenario ID of the objective") private Scenario scenario; @Column(name = "objective_title") @JsonProperty("objective_title") + @Schema(description = "Title of the objective") private String title; @Column(name = "objective_description") @JsonProperty("objective_description") + @Schema(description = "Description of the objective") private String description; @Column(name = "objective_priority") @JsonProperty("objective_priority") + @Schema(description = "Priority of the objective") private Short priority; @Column(name = "objective_created_at") @JsonProperty("objective_created_at") @NotNull + @Schema(description = "Creation date of the objective") private Instant createdAt = now(); @Column(name = "objective_updated_at") @JsonProperty("objective_updated_at") @NotNull + @Schema(description = "Update date of the objective") private Instant updatedAt = now(); @ArraySchema(schema = @Schema(type = "string")) @OneToMany(mappedBy = "objective", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("objective_evaluations") + @Schema(description = "Evaluation IDs of the objective") private List evaluations = new ArrayList<>(); // region transient @JsonProperty("objective_score") + @Schema(description = "Score of the objective") public Double getEvaluationAverage() { return getEvaluations().stream().mapToDouble(Evaluation::getScore).average().orElse(0D); } diff --git a/openbas-model/src/main/java/io/openbas/database/model/Scenario.java b/openbas-model/src/main/java/io/openbas/database/model/Scenario.java index b76c024eb3..3381a575dd 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Scenario.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Scenario.java @@ -55,43 +55,52 @@ public enum SEVERITY { @Column(name = "scenario_id") @JsonProperty("scenario_id") @NotBlank + @Schema(description = "Id of the scenario") private String id; @Column(name = "scenario_name") @JsonProperty("scenario_name") @Queryable(filterable = true, searchable = true, sortable = true) @NotBlank + @Schema(description = "Name of the scenario") private String name; @Column(name = "scenario_description") @JsonProperty("scenario_description") + @Schema(description = "Description of the scenario") private String description; @Column(name = "scenario_subtitle") @JsonProperty("scenario_subtitle") + @Schema(description = "Subtitle of the scenario") private String subtitle; @Column(name = "scenario_category") @JsonProperty("scenario_category") @Queryable(filterable = true, sortable = true, dynamicValues = true) + @Schema(description = "Category of the scenario") private String category; @Column(name = "scenario_main_focus") @JsonProperty("scenario_main_focus") + @Schema(description = "Main focus of the scenario") private String mainFocus; @Column(name = "scenario_severity") @Enumerated(EnumType.STRING) @JsonProperty("scenario_severity") @Queryable(filterable = true, sortable = true) + @Schema(description = "Severity of the scenario") private SEVERITY severity; @Column(name = "scenario_external_reference") @JsonProperty("scenario_external_reference") + @Schema(description = "External reference of the scenario") private String externalReference; @Column(name = "scenario_external_url") @JsonProperty("scenario_external_url") + @Schema(description = "External url of the scenario") private String externalUrl; // -- RECURRENCE -- @@ -99,30 +108,36 @@ public enum SEVERITY { @Column(name = "scenario_recurrence") @JsonProperty("scenario_recurrence") @Queryable(filterable = true) + @Schema(description = "Recurrence cron-style of the scenario") private String recurrence; @Column(name = "scenario_recurrence_start") @JsonProperty("scenario_recurrence_start") + @Schema(description = "Start of the recurrence of the scenario") private Instant recurrenceStart; @Column(name = "scenario_recurrence_end") @JsonProperty("scenario_recurrence_end") + @Schema(description = "End of the recurrence of the scenario") private Instant recurrenceEnd; // -- MESSAGE -- @Column(name = "scenario_message_header") @JsonProperty("scenario_message_header") + @Schema(description = "Header of the scenario for mails and communications") private String header = "SIMULATION HEADER"; @Column(name = "scenario_message_footer") @JsonProperty("scenario_message_footer") + @Schema(description = "Footer of the scenario for mails and communications") private String footer = "SIMULATION FOOTER"; @Column(name = "scenario_mail_from") @JsonProperty("scenario_mail_from") @Email @NotBlank + @Schema(description = "Sender of mails and communications for the scenario") private String from; @ElementCollection(fetch = FetchType.EAGER) @@ -131,12 +146,14 @@ public enum SEVERITY { joinColumns = @JoinColumn(name = "scenario_id")) @Column(name = "scenario_reply_to", nullable = false) @JsonProperty("scenario_mails_reply_to") + @Schema(description = "'Reply to' of mails and communications for the scenario") private List replyTos = new ArrayList<>(); // -- AUDIT -- @Column(name = "scenario_created_at") @JsonProperty("scenario_created_at") + @Schema(description = "Creation date of the scenario") @NotNull private Instant createdAt = now(); @@ -144,12 +161,14 @@ public enum SEVERITY { @JsonProperty("scenario_updated_at") @NotNull @Queryable(filterable = true, sortable = true) + @Schema(description = "Update date of the scenario") private Instant updatedAt = now(); // -- RELATION -- @OneToMany(mappedBy = "scenario", fetch = FetchType.EAGER) @JsonIgnore + @Schema(description = "List of grants of the scenario") private List grants = new ArrayList<>(); @ArraySchema(schema = @Schema(type = "string")) @@ -167,6 +186,7 @@ public enum SEVERITY { inverseJoinColumns = @JoinColumn(name = "team_id")) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("scenario_teams") + @Schema(description = "List of team IDs of the scenario") private List teams = new ArrayList<>(); @OneToMany( @@ -176,10 +196,12 @@ public enum SEVERITY { orphanRemoval = true) @JsonProperty("scenario_teams_users") @JsonSerialize(using = MultiModelDeserializer.class) + @Schema(description = "List of 3-tuple linking team IDs and user IDs to this scenario ID") private List teamUsers = new ArrayList<>(); @OneToMany(mappedBy = "scenario", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JsonIgnore + @Schema(description = "List of objective of the scenario") private List objectives = new ArrayList<>(); @ArraySchema(schema = @Schema(type = "string")) @@ -191,6 +213,7 @@ public enum SEVERITY { @JsonSerialize(using = MultiIdSetDeserializer.class) @JsonProperty("scenario_tags") @Queryable(filterable = true, dynamicValues = true, path = "tags.id") + @Schema(description = "List of tag IDs of the scenario") private Set tags = new HashSet<>(); @ArraySchema(schema = @Schema(type = "string")) @@ -201,18 +224,21 @@ public enum SEVERITY { inverseJoinColumns = @JoinColumn(name = "document_id")) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("scenario_documents") + @Schema(description = "List of document IDs of the scenario") private List documents = new ArrayList<>(); @ArraySchema(schema = @Schema(type = "string")) @OneToMany(mappedBy = "scenario", fetch = FetchType.LAZY) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("scenario_articles") + @Schema(description = "List of article IDs of the scenario") private List
articles = new ArrayList<>(); @ArraySchema(schema = @Schema(type = "string")) @OneToMany(mappedBy = "scenario", fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("scenario_lessons_categories") + @Schema(description = "List of article IDs of the scenario") private List lessonsCategories = new ArrayList<>(); @ArraySchema(schema = @Schema(type = "string")) @@ -223,15 +249,18 @@ public enum SEVERITY { inverseJoinColumns = @JoinColumn(name = "exercise_id")) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("scenario_exercises") + @Schema(description = "List of simulation IDs of the scenario") private List exercises; @Getter @Column(name = "scenario_lessons_anonymized") @JsonProperty("scenario_lessons_anonymized") + @Schema(description = "True if the lessons of the scenario are anonymized") private boolean lessonsAnonymized = false; // -- LESSONS -- + @Schema(description = "List of inject IDs of the scenario") public List getInjects() { return new ArrayList<>(this.injects); } @@ -241,6 +270,7 @@ public List getInjects() { @ArraySchema(schema = @Schema(type = "string")) @JsonProperty("scenario_planners") @JsonSerialize(using = MultiIdListDeserializer.class) + @Schema(description = "List of planner IDs of the scenario") public List getPlanners() { return getUsersByType(this.getGrants(), PLANNER); } @@ -248,6 +278,7 @@ public List getPlanners() { @ArraySchema(schema = @Schema(type = "string")) @JsonProperty("scenario_observers") @JsonSerialize(using = MultiIdListDeserializer.class) + @Schema(description = "List of observer IDs of the scenario") public List getObservers() { return getUsersByType(this.getGrants(), PLANNER, OBSERVER); } @@ -255,16 +286,19 @@ public List getObservers() { // -- STATISTICS -- @JsonProperty("scenario_injects_statistics") + @Schema(description = "Map of statistics by inject IDs of the scenario") public Map getInjectStatistics() { return InjectStatisticsHelper.getInjectStatistics(this.getInjects()); } @JsonProperty("scenario_all_users_number") + @Schema(description = "Number of users of the scenario") public long usersAllNumber() { return getTeams().stream().mapToLong(Team::getUsersNumber).sum(); } @JsonProperty("scenario_users_number") + @Schema(description = "Number of teams users of the scenario") public long usersNumber() { return getTeamUsers().stream().map(ScenarioTeamUser::getUser).distinct().count(); } @@ -272,11 +306,13 @@ public long usersNumber() { @ArraySchema(schema = @Schema(type = "string")) @JsonProperty("scenario_users") @JsonSerialize(using = MultiIdListDeserializer.class) + @Schema(description = "Users of the scenario") public List getUsers() { return getTeamUsers().stream().map(ScenarioTeamUser::getUser).distinct().toList(); } @JsonProperty("scenario_communications_number") + @Schema(description = "Number of communications of the scenario") public long getCommunicationsNumber() { return getInjects().stream().mapToLong(Inject::getCommunicationsNumber).sum(); } @@ -290,6 +326,7 @@ public List
getArticlesForChannel(Channel channel) { // -- PLATFORMS -- @JsonProperty("scenario_platforms") @Queryable(filterable = true, path = "injects.injectorContract.platforms", clazz = String[].class) + @Schema(description = "List of platforms of the scenario") public List getPlatforms() { return getInjects().stream() .flatMap( @@ -306,6 +343,7 @@ public List getPlatforms() { filterable = true, dynamicValues = true, path = "injects.injectorContract.attackPatterns.killChainPhases.id") + @Schema(description = "List of kill chain phase of the scenario") public List getKillChainPhases() { return getInjects().stream() .flatMap( diff --git a/openbas-model/src/main/java/io/openbas/database/model/ScenarioTeamUser.java b/openbas-model/src/main/java/io/openbas/database/model/ScenarioTeamUser.java index c6ebe7992c..c6504ce9c3 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/ScenarioTeamUser.java +++ b/openbas-model/src/main/java/io/openbas/database/model/ScenarioTeamUser.java @@ -20,7 +20,7 @@ public class ScenarioTeamUser { @JoinColumn(name = "scenario_id") @JsonProperty("scenario_id") @JsonSerialize(using = MonoIdDeserializer.class) - @Schema(type = "string") + @Schema(type = "string", description = "ID of the scenario") private Scenario scenario; @ManyToOne(fetch = FetchType.LAZY) @@ -28,7 +28,7 @@ public class ScenarioTeamUser { @JoinColumn(name = "team_id") @JsonProperty("team_id") @JsonSerialize(using = MonoIdDeserializer.class) - @Schema(type = "string") + @Schema(type = "string", description = "ID of the team") private Team team; @ManyToOne(fetch = FetchType.LAZY) @@ -36,6 +36,6 @@ public class ScenarioTeamUser { @JoinColumn(name = "user_id") @JsonProperty("user_id") @JsonSerialize(using = MonoIdDeserializer.class) - @Schema(type = "string") + @Schema(type = "string", description = "ID of the user") private User user; } diff --git a/openbas-model/src/main/java/io/openbas/database/model/StatusPayload.java b/openbas-model/src/main/java/io/openbas/database/model/StatusPayload.java index aff48b4662..21570c2e78 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/StatusPayload.java +++ b/openbas-model/src/main/java/io/openbas/database/model/StatusPayload.java @@ -12,6 +12,15 @@ @Setter public class StatusPayload { + @JsonProperty("payload_name") + private String name; + + @JsonProperty("payload_description") + private String description; + + @JsonProperty("payload_type") + private String type; + @JsonProperty("payload_cleanup_executor") private String cleanupExecutor; @@ -29,10 +38,10 @@ public class StatusPayload { private String externalId; @JsonProperty("executable_file") - private Document executableFile; + private StatusPayloadDocument executableFile; @JsonProperty("file_drop_file") - private Document fileDropFile; + private StatusPayloadDocument fileDropFile; @JsonProperty("dns_resolution_hostname") private String hostname; @@ -60,6 +69,9 @@ public class StatusPayload { public StatusPayload() {} public StatusPayload( + String name, + String description, + String type, String protocol, Integer portDst, Integer portSrc, @@ -73,14 +85,21 @@ public StatusPayload( List arguments, List payloadCommandBlocks, String cleanupExecutor) { + this.name = name; + this.description = description; + this.type = type; this.protocol = protocol; this.portDst = portDst; this.portSrc = portSrc; this.ipDst = ipDst; this.ipSrc = ipSrc; this.hostname = hostname; - this.fileDropFile = fileDropFile; - this.executableFile = executableFile; + if (fileDropFile != null) { + this.fileDropFile = new StatusPayloadDocument(fileDropFile); + } + if (executableFile != null) { + this.executableFile = new StatusPayloadDocument(executableFile); + } this.externalId = externalId; this.prerequisites = prerequisites; this.arguments = arguments; diff --git a/openbas-model/src/main/java/io/openbas/database/model/StatusPayloadDocument.java b/openbas-model/src/main/java/io/openbas/database/model/StatusPayloadDocument.java new file mode 100644 index 0000000000..fa152961ed --- /dev/null +++ b/openbas-model/src/main/java/io/openbas/database/model/StatusPayloadDocument.java @@ -0,0 +1,33 @@ +package io.openbas.database.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class StatusPayloadDocument { + + @JsonProperty("document_id") + @NotBlank + private String id; + + @JsonProperty("document_name") + @NotBlank + private String name; + + // Usefully to avoid migration + @JsonCreator + public StatusPayloadDocument( + @JsonProperty("document_id") String id, @JsonProperty("document_name") String name) { + this.id = id; + this.name = name; + } + + public StatusPayloadDocument(Document document) { + this.id = document.getId(); + this.name = document.getName(); + } +} diff --git a/openbas-model/src/main/java/io/openbas/database/model/Tag.java b/openbas-model/src/main/java/io/openbas/database/model/Tag.java index 302f5c4e3a..17eb99fca5 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Tag.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Tag.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openbas.annotation.Queryable; import io.openbas.database.audit.ModelBaseListener; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; import java.util.Objects; @@ -23,6 +24,7 @@ public class Tag implements Base { @UuidGenerator @JsonProperty("tag_id") @NotBlank + @Schema(description = "ID of the tag") private String id; @Getter @@ -30,12 +32,14 @@ public class Tag implements Base { @JsonProperty("tag_name") @Queryable(searchable = true, sortable = true) @NotBlank + @Schema(description = "Name of the tag") private String name; @Getter @Column(name = "tag_color") @JsonProperty("tag_color") @Queryable(sortable = true) + @Schema(description = "Color of the tag") private String color; @JsonIgnore diff --git a/openbas-model/src/main/java/io/openbas/database/model/Team.java b/openbas-model/src/main/java/io/openbas/database/model/Team.java index b4fc13e3b8..b20b9c953e 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/Team.java +++ b/openbas-model/src/main/java/io/openbas/database/model/Team.java @@ -39,31 +39,36 @@ public class Team implements Base { @UuidGenerator @JsonProperty("team_id") @NotBlank + @Schema(description = "ID of the team") private String id; @Column(name = "team_name") @JsonProperty("team_name") @Queryable(searchable = true, sortable = true) @NotBlank + @Schema(description = "Name of the team") private String name; @Queryable(searchable = true, sortable = true) @Column(name = "team_description") @JsonProperty("team_description") + @Schema(description = "Description of the team") private String description; @Column(name = "team_created_at") @JsonProperty("team_created_at") @NotNull + @Schema(description = "Creation date of the team", accessMode = Schema.AccessMode.READ_ONLY) private Instant createdAt = now(); @Queryable(sortable = true) @Column(name = "team_updated_at") @JsonProperty("team_updated_at") @NotNull + @Schema(description = "Update date of the team", accessMode = Schema.AccessMode.READ_ONLY) private Instant updatedAt = now(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "IDs of the tags of the team", type = "string")) @Queryable(filterable = true, dynamicValues = true, path = "tags.id") @ManyToMany(fetch = FetchType.LAZY) @JoinTable( @@ -78,10 +83,10 @@ public class Team implements Base { @JoinColumn(name = "team_organization") @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("team_organization") - @Schema(type = "string") + @Schema(description = "Organization of the team", type = "string") private Organization organization; - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "IDs of the users of the team", type = "string")) @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "users_teams", @@ -91,7 +96,8 @@ public class Team implements Base { @JsonProperty("team_users") private List users = new ArrayList<>(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = @Schema(description = "IDs of the simulations linked to the team", type = "string")) @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "exercises_teams", @@ -101,7 +107,8 @@ public class Team implements Base { @JsonProperty("team_exercises") private List exercises = new ArrayList<>(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = @Schema(description = "IDs of the scenarios linked to the team", type = "string")) @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "scenarios_teams", @@ -113,9 +120,16 @@ public class Team implements Base { @Column(name = "team_contextual") @JsonProperty("team_contextual") + @Schema( + description = + "True if the team is contextual (exists only in the scenario/simulation it is linked to)") private Boolean contextual = false; - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = + @Schema( + description = "List of 3-tuple linking simulation IDs and user IDs to this team ID", + type = "string")) @OneToMany( mappedBy = "team", fetch = FetchType.LAZY, @@ -123,17 +137,24 @@ public class Team implements Base { orphanRemoval = true) @JsonProperty("team_exercises_users") @JsonSerialize(using = MultiModelDeserializer.class) + @Schema(description = "List of 3-tuple linking simulations and users to this team") private List exerciseTeamUsers = new ArrayList<>(); @JsonProperty("team_users_number") + @Schema(description = "Number of users of the team") public long getUsersNumber() { return getUsers().size(); } // region transient - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = + @Schema( + description = "List of inject IDs from all simulations of the team", + type = "string")) @JsonProperty("team_exercise_injects") @JsonSerialize(using = MultiIdListDeserializer.class) + @Schema(description = "List of injects from all simulations of the team") public List getExercisesInjects() { Predicate selectedInject = inject -> inject.isAllTeams() || inject.getTeams().contains(this); @@ -144,13 +165,19 @@ public List getExercisesInjects() { } @JsonProperty("team_exercise_injects_number") + @Schema(description = "Number of injects of all simulations of the team") public long getExercisesInjectsNumber() { return getExercisesInjects().size(); } - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = + @Schema( + description = "List of inject IDs from all scenarios of the team", + type = "string")) @JsonProperty("team_scenario_injects") @JsonSerialize(using = MultiIdListDeserializer.class) + @Schema(description = "List of injects from all scenarios of the team") public List getScenariosInjects() { Predicate selectedInject = inject -> inject.isAllTeams() || inject.getTeams().contains(this); @@ -161,23 +188,29 @@ public List getScenariosInjects() { } @JsonProperty("team_scenario_injects_number") + @Schema(description = "Number of injects of all scenarios of the team") public long getScenariosInjectsNumber() { return getScenariosInjects().size(); } - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema( + schema = + @Schema(description = "List of expectations id linked to this team", type = "string")) @OneToMany(mappedBy = "team", fetch = FetchType.LAZY) @JsonSerialize(using = MultiIdListDeserializer.class) @JsonProperty("team_inject_expectations") + @Schema(description = "List of expectations id linked to this team") private List injectExpectations = new ArrayList<>(); @JsonProperty("team_injects_expectations_number") + @Schema(description = "Number of expectations linked to this team") public long getInjectExceptationsNumber() { return getInjectExpectations().size(); } @JsonProperty("team_injects_expectations_total_score") @NotNull + @Schema(description = "Total score of expectations linked to this team") public double getInjectExceptationsTotalScore() { return getInjectExpectations().stream() .filter((inject) -> inject.getScore() != null) @@ -187,6 +220,7 @@ public double getInjectExceptationsTotalScore() { @JsonProperty("team_injects_expectations_total_score_by_exercise") @NotNull + @Schema(description = "Total score of expectations by simulation linked to this team") public Map getInjectExceptationsTotalScoreByExercise() { return getInjectExpectations().stream() .filter( @@ -201,12 +235,14 @@ public Map getInjectExceptationsTotalScoreByExercise() { @JsonProperty("team_injects_expectations_total_expected_score") @NotNull + @Schema(description = "Total expected score of expectations linked to this team") public double getInjectExceptationsTotalExpectedScore() { return getInjectExpectations().stream().mapToDouble(InjectExpectation::getExpectedScore).sum(); } @JsonProperty("team_injects_expectations_total_expected_score_by_exercise") @NotNull + @Schema(description = "Total expected score of expectations by simulation linked to this team") public Map getInjectExpectationsTotalExpectedScoreByExercise() { return getInjectExpectations().stream() .filter(expectation -> Objects.nonNull(expectation.getExercise())) @@ -219,6 +255,7 @@ public Map getInjectExpectationsTotalExpectedScoreByExercise() { // endregion @JsonProperty("team_communications") + @Schema(description = "List of communications of this team") public List getCommunications() { return getExercisesInjects().stream() .flatMap(inject -> inject.getCommunications().stream()) diff --git a/openbas-model/src/main/java/io/openbas/database/model/TeamSimple.java b/openbas-model/src/main/java/io/openbas/database/model/TeamSimple.java index 551d33f3f2..5163aa3977 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/TeamSimple.java +++ b/openbas-model/src/main/java/io/openbas/database/model/TeamSimple.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.openbas.annotation.Queryable; import io.openbas.database.raw.RawTeam; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.time.Instant; @@ -20,61 +21,80 @@ public class TeamSimple { @JsonProperty("team_id") @NotBlank + @Schema(description = "ID of the team") private String id; @NotBlank @JsonProperty("team_name") @Queryable(searchable = true) + @Schema(description = "Name of the team") private String name; @JsonProperty("team_description") + @Schema(description = "Description of the team") private String description; @JsonProperty("team_created_at") + @Schema(description = "Creation date of the team", accessMode = Schema.AccessMode.READ_ONLY) private Instant createdAt = now(); @JsonProperty("team_updated_at") + @Schema(description = "Update date of the team", accessMode = Schema.AccessMode.READ_ONLY) private Instant updatedAt = now(); @JsonProperty("team_tags") - private Set tags = new HashSet<>(); + @Schema(description = "List of tag IDs of the team") + private Set tags; @JsonProperty("team_organization") + @Schema(description = "Organization ID of the team") private String organization; @JsonProperty("team_users") - private Set users = new HashSet<>(); + @Schema(description = "List of user IDs of the team") + private Set users; @JsonProperty("team_exercises") - private Set exercises = new HashSet<>(); + @Schema(description = "List of simulation IDs of the team") + private Set exercises; @JsonProperty("team_scenarios") - private Set scenarios = new HashSet<>(); + @Schema(description = "List of scenario IDs of the team") + private Set scenarios; @JsonProperty("team_contextual") - private Boolean contextual = false; + @Schema( + description = + "True if the team is contextual (exists only in the scenario/simulation it is linked to)") + private Boolean contextual; @JsonProperty("team_exercises_users") + @Schema(description = "List of 3-tuple linking simulation IDs and user IDs to this team ID") private Set exerciseTeamUsers = new HashSet<>(); @JsonProperty("team_users_number") + @Schema(description = "Number of users of the team") public long getUsersNumber() { return this.users.size(); } // region transient @JsonProperty("team_exercise_injects") - private Set exercisesInjects = new HashSet<>(); + @Schema(description = "List of inject IDs from all simulations of the team") + private Set exercisesInjects; @JsonProperty("team_exercise_injects_number") + @Schema(description = "Number of injects of all simulations of the team") public long getExercisesInjectsNumber() { return this.exercisesInjects.size(); } @JsonProperty("team_scenario_injects") + @Schema(description = "List of inject IDs from all scenarios of the team") Set scenariosInjects = new HashSet<>(); @JsonProperty("team_scenario_injects_number") + @Schema(description = "Number of injects of all scenarios of the team") public long getScenariosInjectsNumber() { return this.scenariosInjects.size(); } @@ -82,6 +102,7 @@ public long getScenariosInjectsNumber() { @JsonIgnore private List injectExpectations = new ArrayList<>(); @JsonProperty("team_inject_expectations") + @Schema(description = "List of expectation ids linked to this team") private Set getInjectExpectationsAsStringList() { return getInjectExpectations().stream() .map(InjectExpectation::getId) @@ -89,12 +110,14 @@ private Set getInjectExpectationsAsStringList() { } @JsonProperty("team_injects_expectations_number") + @Schema(description = "Number of expectations linked to this team") public long getInjectExceptationsNumber() { return getInjectExpectations().size(); } @JsonProperty("team_injects_expectations_total_score") @NotNull + @Schema(description = "Total score of expectations linked to this team") public double getInjectExceptationsTotalScore() { return getInjectExpectations().stream() .filter((inject) -> inject.getScore() != null) @@ -104,6 +127,7 @@ public double getInjectExceptationsTotalScore() { @JsonProperty("team_injects_expectations_total_score_by_exercise") @NotNull + @Schema(description = "Total score of expectations by simulation linked to this team") public Map getInjectExceptationsTotalScoreByExercise() { return getInjectExpectations().stream() .filter( @@ -118,6 +142,7 @@ public Map getInjectExceptationsTotalScoreByExercise() { @JsonProperty("team_injects_expectations_total_expected_score") @NotNull + @Schema(description = "Total expected score of expectations linked to this team") public double getInjectExceptationsTotalExpectedScore() { return getInjectExpectations().stream() .filter(expectation -> Objects.nonNull(expectation.getExpectedScore())) @@ -127,20 +152,20 @@ public double getInjectExceptationsTotalExpectedScore() { @JsonProperty("team_injects_expectations_total_expected_score_by_exercise") @NotNull + @Schema(description = "Total expected score of expectations by simulation linked to this team") public Map getInjectExpectationsTotalExpectedScoreByExercise() { - Map result = - getInjectExpectations().stream() - .filter(expectation -> Objects.nonNull(expectation.getExercise())) - .collect( - Collectors.groupingBy( - expectation -> expectation.getExercise().getId(), - Collectors.summingDouble(InjectExpectation::getExpectedScore))); - return result; + return getInjectExpectations().stream() + .filter(expectation -> Objects.nonNull(expectation.getExercise())) + .collect( + Collectors.groupingBy( + expectation -> expectation.getExercise().getId(), + Collectors.summingDouble(InjectExpectation::getExpectedScore))); } // endregion @JsonProperty("team_communications") + @Schema(description = "List of communications of this team") List communications = new ArrayList<>(); public TeamSimple(RawTeam raw) { diff --git a/openbas-model/src/main/java/io/openbas/database/model/User.java b/openbas-model/src/main/java/io/openbas/database/model/User.java index ccd89a3c18..940e8ffd18 100644 --- a/openbas-model/src/main/java/io/openbas/database/model/User.java +++ b/openbas-model/src/main/java/io/openbas/database/model/User.java @@ -43,6 +43,8 @@ public class User implements Base { public static final String THEME_DEFAULT = "default"; public static final String LANG_AUTO = "auto"; + public static final List ALL_ROLES = Arrays.asList(ROLE_ADMIN, ROLE_USER); + @Setter @Id @Column(name = "user_id") @@ -50,30 +52,35 @@ public class User implements Base { @UuidGenerator @JsonProperty("user_id") @NotBlank + @Schema(description = "User ID") private String id; @Setter @Column(name = "user_firstname") @JsonProperty("user_firstname") @Queryable(filterable = true, searchable = true, sortable = true) + @Schema(description = "First name of the user") private String firstname; @Setter @Column(name = "user_lastname") @JsonProperty("user_lastname") @Queryable(filterable = true, searchable = true, sortable = true) + @Schema(description = "Last name of the user") private String lastname; @Getter(NONE) @Setter @Column(name = "user_lang") @JsonProperty("user_lang") + @Schema(description = "Language of the user") private String lang = LANG_AUTO; @Getter(NONE) @Setter @Column(name = "user_theme") @JsonProperty("user_theme") + @Schema(description = "Theme of the user") private String theme = THEME_DEFAULT; @Getter(NONE) @@ -81,27 +88,32 @@ public class User implements Base { @JsonProperty("user_email") @Queryable(filterable = true, searchable = true, sortable = true) @NotBlank + @Schema(description = "Email of the user") private String email; @Setter @Column(name = "user_phone") @JsonProperty("user_phone") + @Schema(description = "Phone number of the user") private String phone; @Setter @Column(name = "user_phone2") @JsonProperty("user_phone2") + @Schema(description = "Secondary phone number of the user") private String phone2; @Setter @Column(name = "user_pgp_key") @JsonProperty("user_pgp_key") + @Schema(description = "PGP key of the user") private String pgpKey; @Setter @Column(name = "user_status") @JsonProperty("user_status") @NotNull + @Schema(description = "Status of the user") private Short status = 0; @Setter @@ -113,12 +125,14 @@ public class User implements Base { @Column(name = "user_created_at") @JsonProperty("user_created_at") @NotNull + @Schema(description = "Creation date of the user", accessMode = Schema.AccessMode.READ_ONLY) private Instant createdAt = now(); @Setter @Column(name = "user_updated_at") @JsonProperty("user_updated_at") @NotNull + @Schema(description = "Update date of the user", accessMode = Schema.AccessMode.READ_ONLY) private Instant updatedAt = now(); @Setter @@ -127,26 +141,29 @@ public class User implements Base { @JsonSerialize(using = MonoIdDeserializer.class) @JsonProperty("user_organization") @Queryable(dynamicValues = true, filterable = true, sortable = true, path = "organization.id") - @Schema(type = "string") + @Schema(description = "Organization ID of the user", type = "string") private Organization organization; @Setter @Column(name = "user_admin") @JsonProperty("user_admin") @Queryable(filterable = true, sortable = true) + @Schema(description = "True if the user is admin") private boolean admin = false; @Setter @Column(name = "user_country") @JsonProperty("user_country") + @Schema(description = "Country of the user") private String country; @Setter @Column(name = "user_city") @JsonProperty("user_city") + @Schema(description = "City of the user") private String city; - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "Group IDs of the user", type = "string")) @Setter // @ManyToMany(fetch = FetchType.LAZY) @ManyToMany(fetch = FetchType.EAGER) @@ -158,7 +175,7 @@ public class User implements Base { @JsonProperty("user_groups") private List groups = new ArrayList<>(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "Team IDs of the user", type = "string")) @Setter @ManyToMany(fetch = FetchType.LAZY) @JoinTable( @@ -169,7 +186,7 @@ public class User implements Base { @JsonProperty("user_teams") private List teams = new ArrayList<>(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "Tag IDs of the user", type = "string")) @Setter @ManyToMany(fetch = FetchType.LAZY) @JoinTable( @@ -181,7 +198,7 @@ public class User implements Base { @Queryable(dynamicValues = true, filterable = true, sortable = true, path = "tags.id") private Set tags = new HashSet<>(); - @ArraySchema(schema = @Schema(type = "string")) + @ArraySchema(schema = @Schema(description = "Communication IDs of the user", type = "string")) @Setter @ManyToMany(fetch = FetchType.LAZY) @JoinTable( @@ -222,11 +239,13 @@ public void setEmail(final String email) { } @JsonProperty("user_gravatar") + @Schema(description = "Gravatar of the user") public String getGravatar() { return UserHelper.getGravatar(getEmail()); } @JsonProperty("user_is_planner") + @Schema(description = "True if the user is planner") public boolean isPlanner() { return isAdmin() || getGroups().stream() @@ -235,16 +254,19 @@ public boolean isPlanner() { } @JsonProperty("user_is_observer") + @Schema(description = "True if the user is observer") public boolean isObserver() { return isAdmin() || getGroups().stream().mapToLong(group -> group.getGrants().size()).sum() > 0; } @JsonProperty("user_is_manager") + @Schema(description = "True if the user is manager") public boolean isManager() { return isPlanner() || isObserver(); } @JsonProperty("user_is_player") + @Schema(description = "True if the user is player") public boolean isPlayer() { return isAdmin() || isPlanner() || isObserver() || !getTeams().isEmpty(); } @@ -258,6 +280,7 @@ public Optional getLastComcheck() { } @JsonProperty("user_is_external") + @Schema(description = "True if the user is external") public boolean isExternal() { return this.getId().equals(ADMIN_UUID); } @@ -268,6 +291,7 @@ public String getName() { } @JsonProperty("user_is_only_player") + @Schema(description = "True if the user is only a player") public boolean isOnlyPlayer() { return !isAdmin() && !isManager(); } diff --git a/openbas-model/src/main/java/io/openbas/database/raw/RawPaginationScenario.java b/openbas-model/src/main/java/io/openbas/database/raw/RawPaginationScenario.java index 01d60670a9..be62694ddb 100644 --- a/openbas-model/src/main/java/io/openbas/database/raw/RawPaginationScenario.java +++ b/openbas-model/src/main/java/io/openbas/database/raw/RawPaginationScenario.java @@ -1,6 +1,7 @@ package io.openbas.database.raw; import io.openbas.database.model.Scenario.SEVERITY; +import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; import java.util.Arrays; import java.util.HashSet; @@ -10,13 +11,28 @@ @Data public class RawPaginationScenario { + @Schema(description = "Id of the scenario") private String scenario_id; + + @Schema(description = "Name of the scenario") private String scenario_name; + + @Schema(description = "Severity of the scenario") private SEVERITY scenario_severity; + + @Schema(description = "Category of the scenario") private String scenario_category; + + @Schema(description = "Recurrence cron-style of the scenario") private String scenario_recurrence; + + @Schema(description = "Update date of the scenario") private Instant scenario_updated_at; + + @Schema(description = "List of tag IDs of the scenario") private Set scenario_tags; + + @Schema(description = "List of platforms of the scenario") private Set scenario_platforms; public RawPaginationScenario( diff --git a/openbas-model/src/main/java/io/openbas/database/repository/AgentRepository.java b/openbas-model/src/main/java/io/openbas/database/repository/AgentRepository.java index 60eea48c95..e9ed14a080 100644 --- a/openbas-model/src/main/java/io/openbas/database/repository/AgentRepository.java +++ b/openbas-model/src/main/java/io/openbas/database/repository/AgentRepository.java @@ -2,15 +2,15 @@ import io.openbas.database.model.Agent; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface AgentRepository - extends CrudRepository, JpaSpecificationExecutor { + extends JpaRepository, JpaSpecificationExecutor { @Query("SELECT a FROM Agent a WHERE a.asset.id IN :assetIds") List findAgentsByAssetIds(@Param("assetIds") List assetIds); diff --git a/openbas-model/src/main/java/io/openbas/database/repository/InjectStatusRepository.java b/openbas-model/src/main/java/io/openbas/database/repository/InjectStatusRepository.java index 1d599b81f9..703a8d8991 100644 --- a/openbas-model/src/main/java/io/openbas/database/repository/InjectStatusRepository.java +++ b/openbas-model/src/main/java/io/openbas/database/repository/InjectStatusRepository.java @@ -23,5 +23,7 @@ public interface InjectStatusRepository "select c from InjectStatus c where c.name = 'PENDING' and c.inject.injectorContract.injector.type = :injectType") List pendingForInjectType(@Param("injectType") String injectType); + Optional findByInjectId(@NotNull String injectId); + Optional findByInject(@NotNull Inject inject); } diff --git a/openbas-model/src/main/java/io/openbas/helper/InjectModelHelper.java b/openbas-model/src/main/java/io/openbas/helper/InjectModelHelper.java index bf9630f926..c533efd512 100644 --- a/openbas-model/src/main/java/io/openbas/helper/InjectModelHelper.java +++ b/openbas-model/src/main/java/io/openbas/helper/InjectModelHelper.java @@ -50,46 +50,58 @@ public static boolean isReady( } ObjectNode contractContent = injectorContract.getConvertedContent(); - List contractMandatoryFields = + List contractFields = StreamSupport.stream(contractContent.get(CONTACT_CONTENT_FIELDS).spliterator(), false) - .filter( - field -> { - String key = field.get(CONTACT_ELEMENT_CONTENT_KEY).asText(); - boolean isMandatory = field.get(CONTACT_ELEMENT_CONTENT_MANDATORY).asBoolean(); - boolean isMandatoryGroup = - field.hasNonNull(CONTACT_ELEMENT_CONTENT_MANDATORY_GROUPS) - && field.get(CONTACT_ELEMENT_CONTENT_MANDATORY_GROUPS).asBoolean(); - return key.equals(CONTACT_ELEMENT_CONTENT_KEY_ASSETS) - || isMandatory - || isMandatoryGroup; - }) .toList(); boolean isReady = true; - for (JsonNode jsonField : contractMandatoryFields) { + for (JsonNode jsonField : contractFields) { + + // if field is mandatory or if field is asset, check if the field is set String key = jsonField.get(CONTACT_ELEMENT_CONTENT_KEY).asText(); + if (jsonField.get(CONTACT_ELEMENT_CONTENT_MANDATORY).asBoolean() + || (jsonField.hasNonNull(CONTACT_ELEMENT_CONTENT_MANDATORY_GROUPS) + && jsonField.get(CONTACT_ELEMENT_CONTENT_MANDATORY_GROUPS).asBoolean() + || CONTACT_ELEMENT_CONTENT_KEY_ASSETS.equals(key))) { + isReady = + isFieldSet( + allTeams, teams, assets, assetGroups, jsonField, content, injectContractFields); + } - switch (key) { - case CONTACT_ELEMENT_CONTENT_KEY_TEAMS -> { - if (teams.isEmpty() && !allTeams) { - isReady = false; - } - } - case CONTACT_ELEMENT_CONTENT_KEY_ASSETS -> { - if (assets.isEmpty() && assetGroups.isEmpty()) { - isReady = false; - } - } - default -> { - if (isTextOrTextarea(jsonField) && !isFieldValid(content, injectContractFields, key)) { + // if field is mandatory conditional, if the conditional field is set check if the current + // field is set + if (jsonField.hasNonNull(CONTACT_ELEMENT_CONTENT_MANDATORY_CONDITIONAL)) { + String mandatoryOnConditionFieldKey = + jsonField.get(CONTACT_ELEMENT_CONTENT_MANDATORY_CONDITIONAL).asText(); + Optional mandatoryOnConditionField = + contractFields.stream() + .filter( + jsonNode -> + mandatoryOnConditionFieldKey.equals( + jsonNode.get(CONTACT_ELEMENT_CONTENT_KEY).asText())) + .findFirst(); + if (mandatoryOnConditionField.isPresent()) { + if (isFieldSet( + allTeams, + teams, + assets, + assetGroups, + mandatoryOnConditionField.get(), + content, + injectContractFields) + && !isFieldSet( + allTeams, teams, assets, assetGroups, jsonField, content, injectContractFields)) { isReady = false; } + } else { + isReady = false; } } if (!isReady) { break; } } + return isReady; } @@ -101,7 +113,6 @@ private static boolean isTextOrTextarea(JsonNode jsonField) { private static boolean isFieldValid( ObjectNode content, ArrayNode injectContractFields, String key) { JsonNode fieldValue = content.get(key); - if (fieldValue == null || fieldValue.asText().isEmpty()) { for (JsonNode contractField : injectContractFields) { if (key.equals(contractField.get(CONTACT_ELEMENT_CONTENT_KEY).asText())) { @@ -123,15 +134,17 @@ public static Instant computeInjectDate( Instant standardExecutionDate = source.plusSeconds(duration); // Compute execution dates with previous terminated pauses Instant afterPausesExecutionDate = standardExecutionDate; - List sortedPauses = - new ArrayList<>( - exercise.getPauses().stream() - .sorted( - (pause0, pause1) -> - pause0.getDate().equals(pause1.getDate()) - ? 0 - : pause0.getDate().isBefore(pause1.getDate()) ? -1 : 1) - .toList()); + List sortedPauses = new ArrayList<>(); + if (exercise != null) { + sortedPauses.addAll( + exercise.getPauses().stream() + .sorted( + (pause0, pause1) -> + pause0.getDate().equals(pause1.getDate()) + ? 0 + : pause0.getDate().isBefore(pause1.getDate()) ? -1 : 1) + .toList()); + } long previousPauseDelay = 0L; for (Pause pause : sortedPauses) { if (pause.getDate().isAfter(afterPausesExecutionDate)) { @@ -142,14 +155,16 @@ public static Instant computeInjectDate( } // Add current pause duration in date computation if needed - long currentPauseDelay; + long currentPauseDelay = 0; Instant finalAfterPausesExecutionDate = afterPausesExecutionDate; - currentPauseDelay = - exercise - .getCurrentPause() - .filter(pauseTime -> pauseTime.isBefore(finalAfterPausesExecutionDate)) - .map(pauseTime -> between(pauseTime, now()).getSeconds()) - .orElse(0L); + if (exercise != null) { + currentPauseDelay = + exercise + .getCurrentPause() + .filter(pauseTime -> pauseTime.isBefore(finalAfterPausesExecutionDate)) + .map(pauseTime -> between(pauseTime, now()).getSeconds()) + .orElse(0L); + } long globalPauseDelay = previousPauseDelay + currentPauseDelay; long minuteAlignModulo = globalPauseDelay % 60; long alignedPauseDelay = @@ -184,4 +199,39 @@ public static Instant getSentAt(Optional status) { } return null; } + + public static boolean isFieldSet( + final boolean allTeams, + @NotNull final List teams, + @NotNull final List assets, + @NotNull final List assetGroups, + @NotNull final JsonNode jsonField, + @NotNull final ObjectNode content, + @NotNull final ArrayNode injectContractFields) { + boolean isSet = true; + String key = jsonField.get(CONTACT_ELEMENT_CONTENT_KEY).asText(); + switch (key) { + case CONTACT_ELEMENT_CONTENT_KEY_TEAMS -> { + if (teams.isEmpty() && !allTeams) { + isSet = false; + } + } + case CONTACT_ELEMENT_CONTENT_KEY_ASSETS -> { + if (assets.isEmpty() && assetGroups.isEmpty()) { + isSet = false; + } + } + default -> { + if (isTextOrTextarea(jsonField) && !isFieldValid(content, injectContractFields, key)) { + isSet = false; + } else if (content.get(key) == null + || (content.get(key).isArray() && content.get(key).isEmpty()) + || (content.get(key).isObject() && content.get(key).isEmpty()) + || (content.get(key).isTextual() && content.get(key).asText().isEmpty())) { + isSet = false; + } + } + } + return isSet; + } } diff --git a/pom.xml b/pom.xml index 8c3ae916a2..7aa4c7d2c7 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ io.openbas openbas-platform - 1.11.4 + 1.11.5 pom OpenBAS platform