From addc2dee683928968d9f06d7904064228f675113 Mon Sep 17 00:00:00 2001 From: Andrew Pham Date: Tue, 3 Dec 2024 09:54:58 -0500 Subject: [PATCH 01/13] #16585 Add Maine to Network Map SVG --- .../src/content/about/our-network.mdx | 1 + frontend-react/src/content/live.json | 368 +++++++++--------- .../src/content/usa_w_territories.svg | 2 +- 3 files changed, 188 insertions(+), 183 deletions(-) diff --git a/frontend-react/src/content/about/our-network.mdx b/frontend-react/src/content/about/our-network.mdx index ba51792dc8d..6f73b1a0281 100644 --- a/frontend-react/src/content/about/our-network.mdx +++ b/frontend-react/src/content/about/our-network.mdx @@ -59,6 +59,7 @@ ReportStream has established connections to report public health data for each o - Iowa - Kansas - Louisiana +- Maine - Marshall Islands - Maryland - Massachusetts diff --git a/frontend-react/src/content/live.json b/frontend-react/src/content/live.json index b936784daac..53bac2f7169 100644 --- a/frontend-react/src/content/live.json +++ b/frontend-react/src/content/live.json @@ -1,184 +1,188 @@ { - "data": [ - { - "status": "Live", - "state": "Alabama" - }, - { - "status": "Live", - "state": "Alaska" - }, - { - "status": "Live", - "state": "Arkansas" - }, - { - "status": "Live", - "state": "Arizona" - }, - { - "status": "Live", - "state": "California" - }, - { - "status": "Live", - "state": "Colorado" - }, - { - "status": "Live", - "state": "Delaware" - }, - { - "status": "Live", - "state": "Florida" - }, - { - "status": "Live", - "state": "Guam" - }, - { - "status": "Live", - "state": "Hawaii" - }, - { - "status": "Live", - "state": "Idaho" - }, - { - "status": "Live", - "state": "Illinois" - }, - { - "status": "Live", - "state": "Indiana" - }, - { - "status": "Live", - "state": "Iowa" - }, - { - "status": "Live", - "state": "Kansas" - }, - { - "status": "Live", - "state": "Louisiana" - }, - { - "status": "Live", - "state": "Marshall Islands" - }, - { - "status": "Live", - "state": "Maryland" - }, - { - "status": "Live", - "state": "Massachusetts" - }, - { - "status": "Live", - "state": "Minnesota" - }, - { - "status": "Live", - "state": "Mississippi" - }, - { - "status": "Live", - "state": "Montana" - }, - { - "status": "Live", - "state": "Missouri" - }, - { - "status": "Live", - "state": "Nevada" - }, - { - "status": "Live", - "state": "New Jersey" - }, - { - "status": "Live", - "state": "New Hampshire" - }, - { - "status": "Live", - "state": "New Mexico" - }, - { - "status": "Live", - "state": "New York" - }, - { - "status": "Live", - "state": "North Dakota" - }, - { - "status": "Live", - "state": "Oklahoma" - }, - { - "status": "Live", - "state": "Ohio" - }, - { - "status": "Live", - "state": "Oregon" - }, - { - "status": "Live", - "state": "Pennsylvania" - }, - { - "status": "Live", - "state": "Puerto Rico" - }, - { - "status": "Live", - "state": "Rhode Island" - }, - { - "status": "Live", - "state": "South Dakota" - }, - { - "status": "Live", - "state": "South Carolina" - }, - { - "status": "Live", - "state": "Tennessee" - }, - { - "status": "Live", - "state": "Texas" - }, - { - "status": "Live", - "state": "Utah" - }, - { - "status": "Live", - "state": "Vermont" - }, - { - "status": "Live", - "state": "Virgin Islands" - }, - { - "status": "Live", - "state": "Washington" - }, - { - "status": "Live", - "state": "Wisconsin" - }, - { - "status": "Live", - "state": "Wyoming" - } - ] + "data": [ + { + "status": "Live", + "state": "Alabama" + }, + { + "status": "Live", + "state": "Alaska" + }, + { + "status": "Live", + "state": "Arkansas" + }, + { + "status": "Live", + "state": "Arizona" + }, + { + "status": "Live", + "state": "California" + }, + { + "status": "Live", + "state": "Colorado" + }, + { + "status": "Live", + "state": "Delaware" + }, + { + "status": "Live", + "state": "Florida" + }, + { + "status": "Live", + "state": "Guam" + }, + { + "status": "Live", + "state": "Hawaii" + }, + { + "status": "Live", + "state": "Idaho" + }, + { + "status": "Live", + "state": "Illinois" + }, + { + "status": "Live", + "state": "Indiana" + }, + { + "status": "Live", + "state": "Iowa" + }, + { + "status": "Live", + "state": "Kansas" + }, + { + "status": "Live", + "state": "Louisiana" + }, + { + "status": "Live", + "state": "Maine" + }, + { + "status": "Live", + "state": "Marshall Islands" + }, + { + "status": "Live", + "state": "Maryland" + }, + { + "status": "Live", + "state": "Massachusetts" + }, + { + "status": "Live", + "state": "Minnesota" + }, + { + "status": "Live", + "state": "Mississippi" + }, + { + "status": "Live", + "state": "Montana" + }, + { + "status": "Live", + "state": "Missouri" + }, + { + "status": "Live", + "state": "Nevada" + }, + { + "status": "Live", + "state": "New Jersey" + }, + { + "status": "Live", + "state": "New Hampshire" + }, + { + "status": "Live", + "state": "New Mexico" + }, + { + "status": "Live", + "state": "New York" + }, + { + "status": "Live", + "state": "North Dakota" + }, + { + "status": "Live", + "state": "Oklahoma" + }, + { + "status": "Live", + "state": "Ohio" + }, + { + "status": "Live", + "state": "Oregon" + }, + { + "status": "Live", + "state": "Pennsylvania" + }, + { + "status": "Live", + "state": "Puerto Rico" + }, + { + "status": "Live", + "state": "Rhode Island" + }, + { + "status": "Live", + "state": "South Dakota" + }, + { + "status": "Live", + "state": "South Carolina" + }, + { + "status": "Live", + "state": "Tennessee" + }, + { + "status": "Live", + "state": "Texas" + }, + { + "status": "Live", + "state": "Utah" + }, + { + "status": "Live", + "state": "Vermont" + }, + { + "status": "Live", + "state": "Virgin Islands" + }, + { + "status": "Live", + "state": "Washington" + }, + { + "status": "Live", + "state": "Wisconsin" + }, + { + "status": "Live", + "state": "Wyoming" + } + ] } diff --git a/frontend-react/src/content/usa_w_territories.svg b/frontend-react/src/content/usa_w_territories.svg index 8b25f185c93..0d7b09350a3 100644 --- a/frontend-react/src/content/usa_w_territories.svg +++ b/frontend-react/src/content/usa_w_territories.svg @@ -34,7 +34,7 @@ .la, /* Louisiana */ .ma, /* Massachusetts */ .md, /* Maryland */ - /* .me, Maine */ + .me, /* Maine */ .mh, /* Marshall Islands */ /* .mi, Michigan */ .mn, /* Minnesota */ From 66c3691491755ecd67a45d9c4f04c335a2fe22c0 Mon Sep 17 00:00:00 2001 From: Jamie Albinson Date: Thu, 5 Dec 2024 11:02:11 -0500 Subject: [PATCH 02/13] 14601 authorization api (#16495) --- auth/build.gradle.kts | 14 +- auth/docs/setup.md | 56 ++++++++ .../auth/AuthApplicationConstants.kt | 8 +- .../auth/client/OktaGroupsClient.kt | 37 +++++ .../auth/config/ApplicationConfig.kt | 9 +- .../auth/config/OktaClientConfig.kt | 46 +++++++ .../reportstream/auth/config/RouteConfig.kt | 27 ---- .../auth/config/SubmissionsConfig.kt | 12 -- .../auth/controller/HealthController.kt | 3 + .../AppendOktaGroupsGatewayFilterFactory.kt | 61 +++++++++ .../auth/service/OktaGroupsJWTWriter.kt | 64 +++++++++ .../auth/service/OktaGroupsService.kt | 20 +++ auth/src/main/resources/application.yml | 27 +++- .../auth/client/OktaGroupsClientTest.kt | 86 ++++++++++++ .../auth/config/TestOktaClientConfig.kt | 26 ++++ .../auth/controller/HealthControllerTest.kt | 3 + ...ppendOktaGroupsGatewayFilterFactoryTest.kt | 128 ++++++++++++++++++ .../auth/service/OktaGroupsJWTWriterTest.kt | 63 +++++++++ .../auth/service/OktaGroupsServiceTest.kt | 40 ++++++ .../auth/util/KeyGenerationUtils.kt | 45 ++++++ auth/src/test/resources/application.yml | 43 +++++- ...eportstream.project-conventions.gradle.kts | 6 +- shared/build.gradle.kts | 1 + .../reportstream/shared/StringUtilities.kt | 7 + .../reportstream/shared/auth/AuthZService.kt | 64 +++++++++ .../shared/auth/jwt/OktaGroupsJWT.kt | 9 ++ .../shared/auth/jwt/OktaGroupsJWTConstants.kt | 10 ++ .../shared/auth/jwt/OktaGroupsJWTReader.kt | 41 ++++++ .../shared/StringUtilitiesTests.kt | 15 ++ .../shared/auth/AuthZServiceTest.kt | 63 +++++++++ .../auth/jwt/OktaGroupsJWTReaderTest.kt | 112 +++++++++++++++ submissions/build.gradle.kts | 10 +- .../submissions/SubmissionsApplication.kt | 2 + .../submissions/config/AuthConfig.kt | 28 ++++ .../submissions/config/SecurityConfig.kt | 1 + .../controllers/SubmissionController.kt | 10 ++ .../src/main/resources/application.yml | 8 +- .../SubmissionControllerIntegrationTest.kt | 17 ++- .../test/kotlin/SubmissionControllerTest.kt | 65 ++++++++- 39 files changed, 1206 insertions(+), 81 deletions(-) create mode 100644 auth/docs/setup.md create mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClient.kt create mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/OktaClientConfig.kt delete mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/RouteConfig.kt delete mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/SubmissionsConfig.kt create mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactory.kt create mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriter.kt create mode 100644 auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsService.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClientTest.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/config/TestOktaClientConfig.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactoryTest.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriterTest.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsServiceTest.kt create mode 100644 auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/util/KeyGenerationUtils.kt create mode 100644 shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZService.kt create mode 100644 shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWT.kt create mode 100644 shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTConstants.kt create mode 100644 shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReader.kt create mode 100644 shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZServiceTest.kt create mode 100644 shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReaderTest.kt create mode 100644 submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/AuthConfig.kt diff --git a/auth/build.gradle.kts b/auth/build.gradle.kts index 7984f5cc768..e3265185757 100644 --- a/auth/build.gradle.kts +++ b/auth/build.gradle.kts @@ -1,7 +1,7 @@ apply(from = rootProject.file("buildSrc/shared.gradle.kts")) plugins { - id("org.springframework.boot") version "3.3.5" + id("org.springframework.boot") version "3.4.0" id("io.spring.dependency-management") version "1.1.6" id("reportstream.project-conventions") kotlin("plugin.spring") version "2.0.21" @@ -26,16 +26,16 @@ dependencies { runtimeOnly("com.nimbusds:oauth2-oidc-sdk:11.20.1") + // okta + implementation("com.okta.sdk:okta-sdk-api:20.0.0") + runtimeOnly("com.okta.sdk:okta-sdk-impl:20.0.0") + // Swagger implementation("org.springdoc:springdoc-openapi-starter-webflux-ui:2.6.0") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.security:spring-security-test") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") - testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0") - testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0") - - testRuntimeOnly("org.junit.platform:junit-platform-launcher") + testImplementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner") compileOnly("org.springframework.boot:spring-boot-devtools") } @@ -49,7 +49,7 @@ configurations.all { dependencyManagement { imports { mavenBom("com.azure.spring:spring-cloud-azure-dependencies:5.18.0") - mavenBom("org.springframework.cloud:spring-cloud-dependencies:2023.0.3") + mavenBom("org.springframework.cloud:spring-cloud-dependencies:2024.0.0") } } diff --git a/auth/docs/setup.md b/auth/docs/setup.md new file mode 100644 index 00000000000..4b421abd7d8 --- /dev/null +++ b/auth/docs/setup.md @@ -0,0 +1,56 @@ +# Running the Auth Microservice + +## Prerequisites + +A few secrets are required to run the Auth which are not committed to source. These values are +configured in Okta. + +| Environment variable | Value | +|----------------------|---------------------------------| +| OKTA_ADMIN_CLIENT_API_ENCODED_PRIVATE_KEY | Base 64 encoded private key pem | +| SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENT_SECRET | Base 64 encoded secret | + +## How to run application locally + +```bash +# from project root +# start ReportStream and all dependent docker containers +./gradlew quickRun +# start submissions service +./ gradlew submissions:bootRun +# start auth service +./gradlew auth:bootRun +``` + +## Setup a Sender + +- Sign in to Admin Okta +- Applications -> Application tab +- Click "Create App Integration" +- Select "API Services" and click next +- Name your sender +- Copy your client ID and client secret or private key locally to be used while calling the /token endpoint +- Add the user to the appropriate sender group + - You can find this option on the small gear next to your newly created application + - Ensure the group has the prefix DHSender_ + +## Submitting reports locally + +- Retrieve an access token directly from Okta and ensure the JWT contains the "sender" scope + - Make a well-formed request to https://reportstream.oktapreview.com/oauth2/default/v1/token to retrieve your access token + - [See Okta documentation on that endpoint here](https://developer.okta.com/docs/guides/implement-oauth-for-okta-serviceapp/main/#get-an-access-token) +- Submit your report to http://localhost:9000/api/v1/reports + - Note the it's port 9000 which is auth rather than directly to 8880 which is submissions + - See endpoint definition in [SubmissionController](../../submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/controllers/SubmissionController.kt) + - Add the access token you retrieved from Okta as a `Bearer` token in the `Authorization` header +- Inspect the logs if you received a 401 or a 403. This indicates there is an issue with your access token. + +## Notes on secrets + +The Okta-Groups JWT signing key pair has a local dev value already set up appropriately in auth and +downstream in submissions. New values _must_ be generated for deployed environments. You can look +at [KeyGenerationUtils](../src/test/kotlin/gov/cdc/prime/reportstream/auth/util/KeyGenerationUtils.kt) +for scripts to run to generate new keys. + +By Default, we are connecting to the Staging Okta. We cannot post connection secrets directly in this document so +you will have to ask someone for those values. diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/AuthApplicationConstants.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/AuthApplicationConstants.kt index ce68c2e0efc..8822627d6f0 100644 --- a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/AuthApplicationConstants.kt +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/AuthApplicationConstants.kt @@ -12,10 +12,8 @@ object AuthApplicationConstants { const val HEALTHCHECK_ENDPOINT_V1 = "/api/v1/healthcheck" } - /** - * All Submissions service endpoints defined here - */ - object SubmissionsEndpoints { - const val REPORTS_ENDPOINT_V1 = "/api/v1/reports" + object Scopes { + const val ORGANIZATION_SCOPE = "organization" + const val SUBJECT_SCOPE = "sub" } } \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClient.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClient.kt new file mode 100644 index 00000000000..84f9b1530db --- /dev/null +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClient.kt @@ -0,0 +1,37 @@ +package gov.cdc.prime.reportstream.auth.client + +import com.okta.sdk.resource.api.ApplicationGroupsApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.apache.logging.log4j.kotlin.Logging +import org.springframework.stereotype.Service + +@Service +class OktaGroupsClient( + private val applicationGroupsApi: ApplicationGroupsApi, +) : Logging { + + /** + * Get all application groups from the Okta Admin API + * + * Group names are found at json path "_embedded.group.profile.name" + * + * @see https://developer.okta.com/docs/api/openapi/okta-management/management/tag/ApplicationGroups/#tag/ApplicationGroups/operation/listApplicationGroupAssignments + */ + suspend fun getApplicationGroups(appId: String): List { + return withContext(Dispatchers.IO) { + try { + val groups = applicationGroupsApi + .listApplicationGroupAssignments(appId, null, null, null, "group") + .map { it.embedded?.get("group") as Map<*, *> } + .map { it["profile"] as Map<*, *> } + .map { it["name"] as String } + logger.info("$appId is a member of ${groups.joinToString()}") + groups + } catch (ex: Exception) { + logger.error("Error retrieving application groups from Okta API", ex) + throw ex + } + } + } +} \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/ApplicationConfig.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/ApplicationConfig.kt index 28db94952fc..a55c87d6184 100644 --- a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/ApplicationConfig.kt +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/ApplicationConfig.kt @@ -2,15 +2,15 @@ package gov.cdc.prime.reportstream.auth.config import gov.cdc.prime.reportstream.auth.model.Environment import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.bind.ConstructorBinding import org.springframework.context.annotation.Bean +import java.time.Clock import kotlin.time.TimeSource /** * Simple class to automatically read configuration from application.yml (or environment variable overrides) */ @ConfigurationProperties(prefix = "app") -data class ApplicationConfig @ConstructorBinding constructor( +data class ApplicationConfig( val environment: Environment, ) { @@ -18,4 +18,9 @@ data class ApplicationConfig @ConstructorBinding constructor( fun timeSource(): TimeSource { return TimeSource.Monotonic } + + @Bean + fun clock(): Clock { + return Clock.systemUTC() + } } \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/OktaClientConfig.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/OktaClientConfig.kt new file mode 100644 index 00000000000..66085dbb9c7 --- /dev/null +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/OktaClientConfig.kt @@ -0,0 +1,46 @@ +package gov.cdc.prime.reportstream.auth.config + +import com.okta.sdk.client.AuthorizationMode +import com.okta.sdk.client.Clients +import com.okta.sdk.resource.api.ApplicationGroupsApi +import com.okta.sdk.resource.client.ApiClient +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile + +@Configuration +@Profile("!test") +class OktaClientConfig( + private val oktaClientProperties: OktaClientProperties, +) { + + @Bean + fun apiClient(): ApiClient { + return Clients.builder() + .setOrgUrl(oktaClientProperties.orgUrl) + .setAuthorizationMode(AuthorizationMode.PRIVATE_KEY) + .setClientId(oktaClientProperties.clientId) + .setScopes(oktaClientProperties.requiredScopes) + .setPrivateKey(oktaClientProperties.apiPrivateKey) + // .setCacheManager(...) TODO: investigate caching since groups don't often change + .build() + } + + @Bean + fun applicationGroupsApi(): ApplicationGroupsApi { + return ApplicationGroupsApi(apiClient()) + } + + @ConfigurationProperties(prefix = "okta.admin-client") + data class OktaClientProperties( + val orgUrl: String, + val clientId: String, + val requiredScopes: Set, + private val apiEncodedPrivateKey: String, + ) { + // PEM encoded format + val apiPrivateKey = apiEncodedPrivateKey.base64Decode() + } +} \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/RouteConfig.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/RouteConfig.kt deleted file mode 100644 index d1aac8c15e6..00000000000 --- a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/RouteConfig.kt +++ /dev/null @@ -1,27 +0,0 @@ -package gov.cdc.prime.reportstream.auth.config - -import gov.cdc.prime.reportstream.auth.AuthApplicationConstants -import org.springframework.cloud.gateway.route.RouteLocator -import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -/** - * Configuration class to set up route forwarding - */ -@Configuration -class RouteConfig( - private val submissionsConfig: SubmissionsConfig, -) { - - @Bean - fun routes(builder: RouteLocatorBuilder): RouteLocator { - return builder.routes() - .route { - it - .path(AuthApplicationConstants.SubmissionsEndpoints.REPORTS_ENDPOINT_V1) - .uri(submissionsConfig.baseUrl) - } - .build() - } -} \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/SubmissionsConfig.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/SubmissionsConfig.kt deleted file mode 100644 index 703b9a8bccd..00000000000 --- a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/config/SubmissionsConfig.kt +++ /dev/null @@ -1,12 +0,0 @@ -package gov.cdc.prime.reportstream.auth.config - -import org.springframework.boot.context.properties.ConfigurationProperties -import org.springframework.boot.context.properties.bind.ConstructorBinding - -/** - * Configuration for Submissions microservice - */ -@ConfigurationProperties(prefix = "submissions") -data class SubmissionsConfig @ConstructorBinding constructor( - val baseUrl: String, -) \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthController.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthController.kt index f90ee051982..98979e5f801 100644 --- a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthController.kt +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthController.kt @@ -14,6 +14,9 @@ class HealthController( private val applicationStart = timeSource.markNow() + /** + * Simple endpoint that returns a healthcheck with uptime + */ @GetMapping( AuthApplicationConstants.Endpoints.HEALTHCHECK_ENDPOINT_V1, produces = [MediaType.APPLICATION_JSON_VALUE] diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactory.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactory.kt new file mode 100644 index 00000000000..e618da63f76 --- /dev/null +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactory.kt @@ -0,0 +1,61 @@ +package gov.cdc.prime.reportstream.auth.filter + +import gov.cdc.prime.reportstream.auth.AuthApplicationConstants +import gov.cdc.prime.reportstream.auth.service.OktaGroupsService +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTConstants +import kotlinx.coroutines.reactor.mono +import org.springframework.cloud.gateway.filter.GatewayFilter +import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication +import org.springframework.stereotype.Component +import reactor.core.publisher.Mono + +/** + * This filter defines how the Okta-Groups header is added to requests. It follows the conventions + * defined in spring-cloud-gateway and is instantiated via configuration under a route's filters. + */ +@Component +class AppendOktaGroupsGatewayFilterFactory( + private val oktaGroupsService: OktaGroupsService, +) : AbstractGatewayFilterFactory() { + + /** + * function used only in testing to create our filter without any configuration + */ + fun apply(): GatewayFilter { + return apply { _: Any? -> } + } + + override fun apply(config: Any?): GatewayFilter { + return GatewayFilter { exchange, chain -> + exchange + .getPrincipal() + .flatMap { oktaAccessTokenJWT -> + val appId = oktaAccessTokenJWT + .tokenAttributes[AuthApplicationConstants.Scopes.SUBJECT_SCOPE] as String + val organizations = oktaAccessTokenJWT + .tokenAttributes[AuthApplicationConstants.Scopes.ORGANIZATION_SCOPE] as List<*>? + + // If there is no organization claim present, then we have an application user and + // require appending our custom header + if (organizations == null) { + mono { oktaGroupsService.generateOktaGroupsJWT(appId) } + } else { + Mono.empty() + } + } + .map { oktaGroupsJWT: String -> + exchange.request + .mutate() + .headers { + it.add(OktaGroupsJWTConstants.OKTA_GROUPS_HEADER, oktaGroupsJWT) + } + .build() + } + .switchIfEmpty(Mono.just(exchange.request)) // drop back in original unmodified request if not an app + .flatMap { request -> + chain.filter(exchange.mutate().request(request).build()) + } + } + } +} \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriter.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriter.kt new file mode 100644 index 00000000000..0533882ed21 --- /dev/null +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriter.kt @@ -0,0 +1,64 @@ +package gov.cdc.prime.reportstream.auth.service + +import com.nimbusds.jose.JWSAlgorithm +import com.nimbusds.jose.JWSHeader +import com.nimbusds.jose.crypto.RSASSASigner +import com.nimbusds.jose.jwk.JWK +import com.nimbusds.jwt.JWTClaimsSet +import com.nimbusds.jwt.SignedJWT +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTConstants +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.stereotype.Service +import java.time.Clock +import java.time.Duration +import java.util.Date +import java.util.UUID + +@Service +class OktaGroupsJWTWriter( + private val jwtConfig: OktaGroupsJWTConfig, + private val clock: Clock, +) { + + /** + * generate and sign our custom JWT containing Okta group information for a particular application + */ + fun write(model: OktaGroupsJWT): String { + val now = clock.instant() + val expires = now.plus(jwtConfig.ttl) + val nbf = now.minus(jwtConfig.nbf) + val claimsSetBuilder = JWTClaimsSet.Builder() + .subject(model.appId) + .issuer(jwtConfig.issuer) + .jwtID(UUID.randomUUID().toString()) + .issueTime(Date.from(now)) + .notBeforeTime(Date.from(nbf)) + .expirationTime(Date.from(expires)) + .claim(OktaGroupsJWTConstants.OKTA_GROUPS_JWT_GROUP_CLAIM, model.groups) + + val signedJWT = SignedJWT( + JWSHeader.Builder(JWSAlgorithm.RS256).build(), + claimsSetBuilder.build() + ) + + signedJWT.sign(RSASSASigner(jwtConfig.jwtPrivateKeyJWK.toRSAKey())) + + return signedJWT.serialize() + } + + /** + * Configuration for Submissions microservice + */ + @ConfigurationProperties(prefix = "okta.jwt") + data class OktaGroupsJWTConfig( + private val jwtEncodedPrivateKeyJWK: String, + val ttl: Duration, + val nbf: Duration, + val issuer: String, + ) { + // JWK json format + val jwtPrivateKeyJWK: JWK = JWK.parse(jwtEncodedPrivateKeyJWK.base64Decode()) + } +} \ No newline at end of file diff --git a/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsService.kt b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsService.kt new file mode 100644 index 00000000000..d25edf1c5da --- /dev/null +++ b/auth/src/main/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsService.kt @@ -0,0 +1,20 @@ +package gov.cdc.prime.reportstream.auth.service + +import gov.cdc.prime.reportstream.auth.client.OktaGroupsClient +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT +import org.springframework.stereotype.Service + +@Service +class OktaGroupsService( + private val oktaGroupsClient: OktaGroupsClient, + private val oktaGroupsJWTWriter: OktaGroupsJWTWriter, +) { + + /** + * Grab Okta groups from the Okta API and write the JWT + */ + suspend fun generateOktaGroupsJWT(appId: String): String { + val groups = oktaGroupsClient.getApplicationGroups(appId) + return oktaGroupsJWTWriter.write(OktaGroupsJWT(appId, groups)) + } +} \ No newline at end of file diff --git a/auth/src/main/resources/application.yml b/auth/src/main/resources/application.yml index eea5a2c8ec6..e60d2ed073c 100644 --- a/auth/src/main/resources/application.yml +++ b/auth/src/main/resources/application.yml @@ -1,21 +1,41 @@ spring: application: name: "auth" + profiles: + active: "local" security: oauth2: resourceserver: opaquetoken: # Set client secret in SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENT_SECRET env variable client-id: 0oaek8tip2lhrhHce1d7 introspection-uri: https://reportstream.oktapreview.com/oauth2/ausekaai7gUuUtHda1d7/v1/introspect + cloud: + gateway: + routes: + - id: reports_route + uri: http://localhost:8880 + predicates: + - Path=/api/v1/reports + filters: + - AppendOktaGroups server.port: 9000 app: environment: local -# submissions microservice configuration -submissions: - baseUrl: http://localhost:8080 +okta: + adminClient: + orgUrl: https://reportstream.oktapreview.com + clientId: 0oahfz3wazBEHJLEL1d7 + requiredScopes: + - okta.apps.read + # set base 64 encoded pem string in OKTA_ADMIN_CLIENT_API_ENCODED_PRIVATE_KEY env variable + jwt: + nbf: 5s + ttl: 5m + issuer: http://localhost:9000 + jwtEncodedPrivateKeyJWK: eyJwIjoieC1yaFlLVVM2TnpRd0FCYjVmakNEMGl1NlM0MFAySUtQd3pnaUJqU3VjTDZ3VFpoYU4tbTBfZHBEdGhwMHZVQjQyR01LQ2ZHNklWNlFHSV91eF80c3I1QTBRSF9sY09jNC1DbTBWal9Udy1DcFRYbnRaVlJSSDlSN00tdDJ1WXNvT1ZyaXJsUUwxdW1ybThPdjkzVnBUWnJ4QlB6UXBlejZvVGJxZUQ0WF9jIiwia3R5IjoiUlNBIiwicSI6InlYYlhQamJHRmo0cUN3RWJqSUpMQ3hQS1FkTnduX2MtQ0M0ZVBma3UyNTR2VW1jeE1IQ1Q0UGtmQ3ZiTXlKU2plWUxzRFZwY0M1eThqeGJwLXpVMUF3WDJvZk15ZEhJa0RfSW51cjVXM1J2U1ZGUFFqR01YVk5Qc09LU1hxRUUzb3BfSU9QZEtUcXhBR3NZMkhYVEZDYVJSU25SdHMwQnV4ZS10SlZjbnpHcyIsImQiOiJQdmk3YnpOZy1ZekZQcWxsRlNHdXk0UnV5cGE0SDctN1lIZnZEb1pKVktqZFZIcHBqVHNsbjRmZWxicEYxQWJ1c2R2blJnU2QzSHVWQWVTTi1rT2dRbDR6SlNJLThvdDhSd29EQU4wSXNadGg0UDhSbTMwa0JFcFdMR0xPb3Q3ZkFWRDRMSzJFTjVEUlU5dWVVWmNoaFpmcDJwaGl2cHJ4TVluTnlhMzNXSm1oTHdSUFRRVjBIY3JmYk9kVG82a2FHUllfZkpCdHRjd2QzWlQ0dzljOXd6ZzFJT0t6Ul96S2g5VkR1b2Y3SWF0ekNab0ZzeUZ5ZHgwbHZxalZjRXAxSllQMTFBY0VOaUdYOHBSTXpzVktmaUhuNlBET2ZoSXBTU1lBd21wYWI3WGF6V2ZWbEZyam5VQXlpN2wyZV90U1lwMGc1RnpZcjB6NDZrTWo1YnBsIiwiZSI6IkFRQUIiLCJxaSI6IkdWbTR6WllDeTNVNEF6TmhSdE5FWFhzVl9ZYm9CZXR5SS1FRjhhcHNsUGc4YTBhMElzXzFZTTZndTQ4ZlNndVE1WFRpN2RVMURJLTZaR2JSbmVvMXVGb0R1M2RsVGR1dXdrcWx6XzJIREphY1dWZjFWQkRSNkdBSjJ3eWNXckdMM0VkM0k4eGtBeHUzMnlYUGJ0YjlpUy1pRF9WQmo1LVJoSktIUXhHbGNSTSIsImRwIjoid0p5V1JHMEd5UUJteDNZUkZJTVZSWEI3eFFIVktQUW1keFRMQjVVVEFoTFBVWFE1YWJlQm5sdVRCdENQTk1jRjZMTkZQRE1HdTJST290V0dIWjN5R1JTZ2tqN2dwc1J1MWtiTnNvbVNnZk9wcGM5SHpYVnRkUmRPTVdEdVdpYkZfTWJOVkR5eS1zM015LWNJU09kTVBmOHUyUjEzbEVOZ19xUy1sdS1fbllVIiwiZHEiOiJyRXd2MzJ4VzB4VU5QZVlQbW9hZ0NYUS1hVGVjdmFKazhmZ0hNemRXUk1zdmE0a0hmNGI0WWRLTkl3Slp0ejJ2NWE3N2xKdnYxcHFRaE11ekJuM0Z2YlV1N2VpaEFRZlJJYllYRmxYTTBrTUdDY3E0dENmV18xeFRUVW91emQ0ZzU3dEJNTDhGVk8xcDBid3M4ZG80M1hzamJzck9PeHhpNEhPUG9EeS1zOHMiLCJuIjoiblZRNVQ1MFk3Q3NBZkhfWllzQjBhRVFHYnlYcklQdDU1dG5OTGZNSWQwbWJYM1ljdVB6cVVQbVJzYlhiNmNPYmlXT1k1Znk2UGxfaEZDeUs2em9qU1JxaFdCd2dMcHo2NUg3NVJ2bVk5Y2FQbndLSXdPOWhpS2ZHTW5DMkdvS3U2S1otcFFLNXlHaUUwRGhVRGE0Q3gxa0h4NlJUUzVoSXlHZHRFOXk5eGlCU0RJODI0eXVwZ1Z5SkYtU1cteHBINVFYdy1saUxGdVBwSFpnWnQyNEhVRlBPM1JqcXJXTmNkWUZ0S00tZGhzWkxMQXp0cEZSMGlqY3M1SEdjbUVlWnRpaVBJYzFpUF9NWlZGSV9SbnVQdzBxbENFRDF4UGdqeXhzT3ZScDlIdU85NDVfenlib2tyYzlVbTljZnpTTEd3WmdJSW9HZVdtc2VRYWR0Zy1ud1BRIn0= # Ensure these are disabled in production springdoc: @@ -29,3 +49,4 @@ springdoc: # level: # web: debug # org.springframework.web: debug +# com.okta: debug diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClientTest.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClientTest.kt new file mode 100644 index 00000000000..40fcd31459a --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/client/OktaGroupsClientTest.kt @@ -0,0 +1,86 @@ +package gov.cdc.prime.reportstream.auth.client + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.okta.sdk.resource.api.ApplicationGroupsApi +import com.okta.sdk.resource.model.ApplicationGroupAssignment +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import kotlin.test.Test +import kotlin.test.assertEquals + +class OktaGroupsClientTest { + + class Fixture { + val appId = "appId" + + // truncated response from staging + val apiResponse = """ + [ + { + "id":"00gek8f3iuksaVp1e1d7", + "_embedded":{ + "group":{ + "id":"00gek8f3iuksaVp1e1d7", + "objectClass":[ + "okta:user_group" + ], + "type":"OKTA_GROUP", + "profile":{ + "name":"ArnejTestGroup", + "description":"Using this group to play around with scopes" + } + } + } + }, + { + "id":"00g9fxoz8jR9JEbhp1d7", + "priority":2, + "_embedded":{ + "group":{ + "id":"00g9fxoz8jR9JEbhp1d7", + "objectClass":[ + "okta:user_group" + ], + "type":"OKTA_GROUP", + "profile":{ + "name":"DHflexion", + "description":"Flexion org receiver group" + } + } + } + } + ] + """.trimIndent() + + val mapper = jacksonObjectMapper() + var parsedResponse: List = mapper + .readValue( + apiResponse, + mapper.typeFactory.constructCollectionType(List::class.java, ApplicationGroupAssignment::class.java) + ) + + val applicationGroupsApi: ApplicationGroupsApi = mockk() + val client = OktaGroupsClient(applicationGroupsApi) + } + + @Test + fun `fetch groups returns group names`() { + val f = Fixture() + + every { + f.applicationGroupsApi.listApplicationGroupAssignments( + f.appId, + null, + null, + null, + "group" + ) + }.returns(f.parsedResponse) + + assertEquals( + runBlocking { f.client.getApplicationGroups(f.appId) }, + listOf("ArnejTestGroup", "DHflexion") + ) + } +} \ No newline at end of file diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/config/TestOktaClientConfig.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/config/TestOktaClientConfig.kt new file mode 100644 index 00000000000..f5446568763 --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/config/TestOktaClientConfig.kt @@ -0,0 +1,26 @@ +package gov.cdc.prime.reportstream.auth.config + +import com.okta.sdk.resource.api.ApplicationGroupsApi +import com.okta.sdk.resource.client.ApiClient +import io.mockk.mockk +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Profile + +/** + * We don't want the Okta client to actually attempt to connect to staging Okta during tests + */ +@TestConfiguration +@Profile("test") +class TestOktaClientConfig { + + @Bean + fun apiClient(): ApiClient { + return mockk() + } + + @Bean + fun applicationGroupsApi(): ApplicationGroupsApi { + return mockk() + } +} \ No newline at end of file diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthControllerTest.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthControllerTest.kt index 9a643e15c11..46fef5e71b0 100644 --- a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthControllerTest.kt +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/controller/HealthControllerTest.kt @@ -1,11 +1,13 @@ package gov.cdc.prime.reportstream.auth.controller import gov.cdc.prime.reportstream.auth.AuthApplicationConstants +import gov.cdc.prime.reportstream.auth.config.TestOktaClientConfig import gov.cdc.prime.reportstream.auth.model.ApplicationStatus import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient import org.springframework.boot.test.context.SpringBootTest +import org.springframework.context.annotation.Import import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.test.web.reactive.server.WebTestClient import kotlin.test.Test @@ -13,6 +15,7 @@ import kotlin.test.Test @ExtendWith(SpringExtension::class) @SpringBootTest @AutoConfigureWebTestClient +@Import(TestOktaClientConfig::class) class HealthControllerTest @Autowired constructor( private val webTestClient: WebTestClient, ) { diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactoryTest.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactoryTest.kt new file mode 100644 index 00000000000..384ed4852ae --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/filter/AppendOktaGroupsGatewayFilterFactoryTest.kt @@ -0,0 +1,128 @@ +package gov.cdc.prime.reportstream.auth.filter + +import com.github.tomakehurst.wiremock.client.WireMock.aResponse +import com.github.tomakehurst.wiremock.client.WireMock.get +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo +import gov.cdc.prime.reportstream.auth.config.TestOktaClientConfig +import gov.cdc.prime.reportstream.auth.service.OktaGroupsService +import io.mockk.coEvery +import io.mockk.mockk +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock +import org.springframework.cloud.gateway.route.RouteLocator +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Import +import org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.mockOpaqueToken +import org.springframework.test.context.junit.jupiter.SpringExtension +import org.springframework.test.web.reactive.server.WebTestClient + +/** + * The testing strategy here was modeled off how Spring Cloud Gateway tested their own add request filter. + * + * A Wiremock endpoint is set up to take the request header and return it as a part of the body. We then check + * that the body matches what we expect. + */ +@ExtendWith(SpringExtension::class) +@AutoConfigureWebTestClient +@SpringBootTest +@AutoConfigureWireMock(port = 0) +@Import(TestOktaClientConfig::class) +class AppendOktaGroupsGatewayFilterFactoryTest @Autowired constructor( + private val client: WebTestClient, + private val oktaGroupsService: OktaGroupsService, +) { + + @TestConfiguration + class Config( + @Value("\${wiremock.server.port}") val port: Int, + ) { + + @Bean + fun oktaGroupsService(): OktaGroupsService { + return mockk() + } + + @Bean + fun appendOktaGroupsGatewayFilterFactory(): AppendOktaGroupsGatewayFilterFactory { + return AppendOktaGroupsGatewayFilterFactory(oktaGroupsService()) + } + + @Bean + fun testRouteLocator(builder: RouteLocatorBuilder): RouteLocator { + val filterFactory = appendOktaGroupsGatewayFilterFactory() + return builder.routes() + .route("wiremock_route") { + it + .path("/get") + .filters { filter -> + filter.filter(filterFactory.apply()) + } + .uri("http://localhost:$port") + } + .build() + } + } + + @BeforeEach + fun setUp() { + stubFor( + get( + urlEqualTo("/get") + ) + .willReturn( + aResponse() + .withTransformers("response-template") + .withBody("{{ request.headers.Okta-Groups }}") // reflect the request header back into the body + ) + ) + } + + @Test + fun `Successfully pass Okta-Groups header when sender scope is present`() { + val expectedJwt = "okta-groups-jwt" + + coEvery { oktaGroupsService.generateOktaGroupsJWT(any()) } + .returns(expectedJwt) + + client + .mutateWith( + mockOpaqueToken() + .attributes { map -> + map["sub"] = "appId" + map["scope"] = listOf("sender") + } + ) + .get() + .uri("/get") + .exchange() + .expectBody(String::class.java) + .isEqualTo(expectedJwt) + } + + @Test + fun `Do not pass Okta-Groups header when organization scope is present`() { + client + .mutateWith( + mockOpaqueToken() + .attributes { map -> + map["sub"] = "email@cdc.gov" + map["scope"] = listOf("openid", "email") + map["organization"] = listOf("org") + } + ) + .get() + .uri("/get") + .exchange() + .expectBody() + .isEmpty + } +} \ No newline at end of file diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriterTest.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriterTest.kt new file mode 100644 index 00000000000..ba395c37461 --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsJWTWriterTest.kt @@ -0,0 +1,63 @@ +package gov.cdc.prime.reportstream.auth.service + +import com.nimbusds.jose.JWSAlgorithm +import com.nimbusds.jose.crypto.RSASSAVerifier +import com.nimbusds.jwt.SignedJWT +import gov.cdc.prime.reportstream.auth.util.KeyGenerationUtils +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Encode +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT +import java.time.Clock +import java.time.Duration +import java.time.Instant +import java.time.ZoneId +import kotlin.test.Test +import kotlin.test.assertEquals + +class OktaGroupsJWTWriterTest { + + inner class Fixture { + val now = Instant.now() + private val fixedClock = Clock.fixed(now, ZoneId.systemDefault()) + + val pair = KeyGenerationUtils.generateRSAKeyPair() + val privateKey = pair.first + val publicKey = pair.second + + val verifier = RSASSAVerifier(publicKey) + + val config = OktaGroupsJWTWriter.OktaGroupsJWTConfig( + jwtEncodedPrivateKeyJWK = privateKey.toJSONString().base64Encode(), + ttl = Duration.ofMinutes(5), + nbf = Duration.ofSeconds(5), + issuer = "I'm the issuer" + ) + + val oktaGroups = OktaGroupsJWT("appId", listOf("DHSender_org")) + + val jwtWriter = OktaGroupsJWTWriter(config, fixedClock) + } + + @Test + fun `successfully write JWT`() { + val f = Fixture() + + val jwt = f.jwtWriter.write(f.oktaGroups) + + val parsed = SignedJWT.parse(jwt) + val claims = parsed.jwtClaimsSet + + // expected signing algorithm + assertEquals(parsed.header.algorithm, JWSAlgorithm.RS256) + + // all expected claims there + assertEquals(claims.subject, f.oktaGroups.appId) + assertEquals(claims.getStringListClaim("groups"), f.oktaGroups.groups) + assertEquals(claims.issuer, "I'm the issuer") + assertEquals(claims.issueTime.toInstant().epochSecond, f.now.epochSecond) + assertEquals(claims.notBeforeTime.toInstant().epochSecond, f.now.minusSeconds(5).epochSecond) + assertEquals(claims.expirationTime.toInstant().epochSecond, f.now.plusSeconds(5 * 60).epochSecond) + + // correctly signed + assertEquals(parsed.verify(f.verifier), true) + } +} \ No newline at end of file diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsServiceTest.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsServiceTest.kt new file mode 100644 index 00000000000..31957da20d4 --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/service/OktaGroupsServiceTest.kt @@ -0,0 +1,40 @@ +package gov.cdc.prime.reportstream.auth.service + +import gov.cdc.prime.reportstream.auth.client.OktaGroupsClient +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import kotlin.test.Test +import kotlin.test.assertEquals + +class OktaGroupsServiceTest { + + inner class Fixture { + val appId = "appId" + val groups = listOf("group1", "group2") + val oktaGroupsJWT = OktaGroupsJWT(appId, groups) + val jwt = "jwt" + + val oktaGroupsClient: OktaGroupsClient = mockk() + val oktaGroupsJWTWriter: OktaGroupsJWTWriter = mockk() + + val service = OktaGroupsService(oktaGroupsClient, oktaGroupsJWTWriter) + } + + @Test + fun `write JWT given the groups`() { + val f = Fixture() + + coEvery { f.oktaGroupsClient.getApplicationGroups(f.appId) } + .returns(f.groups) + every { f.oktaGroupsJWTWriter.write(f.oktaGroupsJWT) } + .returns(f.jwt) + + assertEquals( + runBlocking { f.service.generateOktaGroupsJWT(f.appId) }, + f.jwt + ) + } +} \ No newline at end of file diff --git a/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/util/KeyGenerationUtils.kt b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/util/KeyGenerationUtils.kt new file mode 100644 index 00000000000..5fd6c30a6b5 --- /dev/null +++ b/auth/src/test/kotlin/gov/cdc/prime/reportstream/auth/util/KeyGenerationUtils.kt @@ -0,0 +1,45 @@ +package gov.cdc.prime.reportstream.auth.util + +import com.nimbusds.jose.jwk.RSAKey +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Encode +import java.security.KeyPairGenerator +import java.security.interfaces.RSAPrivateKey +import java.security.interfaces.RSAPublicKey +import kotlin.test.Ignore +import kotlin.test.Test + +/** + * Handy RSA key generation scripts in JUnit test form for easy running + */ +class KeyGenerationUtils { + + /** + * If you remove the @Ignore annotation below and run this test you can create + * a random 2048-bit RSA key pair. This will be useful for key rotations. + */ + @Ignore + @Test + fun generateAndPrintRSAKeyPair() { + val (privateJWK, publicJWK) = generateRSAKeyPair() + + println("private JWK: $privateJWK") + println("public JWK: $publicJWK") + + println("Encoded private JWK: ${privateJWK.toJSONString().base64Encode()}") + println("Encoded public JWK: ${publicJWK.toJSONString().base64Encode()}") + } + + companion object { + fun generateRSAKeyPair(): Pair { + val keyGen = KeyPairGenerator.getInstance("RSA") + keyGen.initialize(2048) + val keyPair = keyGen.generateKeyPair() + + val privateJWK = RSAKey.Builder(keyPair.public as RSAPublicKey) + .privateKey(keyPair.private as RSAPrivateKey) + .build() + val publicJWK = privateJWK.toPublicJWK() + return Pair(privateJWK, publicJWK) + } + } +} \ No newline at end of file diff --git a/auth/src/test/resources/application.yml b/auth/src/test/resources/application.yml index 0ec6f98f25f..68b84ac2249 100644 --- a/auth/src/test/resources/application.yml +++ b/auth/src/test/resources/application.yml @@ -2,7 +2,7 @@ spring: application: name: "auth" profiles: - active: test + active: "test" security: oauth2: resourceserver: @@ -10,8 +10,43 @@ spring: client-id: mockClient client-secret: mockSecret introspection-uri: https://localhost:9999/oauth2/default/v1/introspect # should never be hit + cloud: + gateway: + routes: + - id: test_route + uri: http://fakeurl.io + predicates: + - Path=/get + filters: + - AppendOktaGroups +server.port: 9000 +app: + environment: local -server.port: 9000 -app.environment: local -submissions.baseUrl: http://localhost:8080 \ No newline at end of file +okta: + adminClient: + orgUrl: https://reportstream.oktapreview.com + clientId: 0oahfz3wazBEHJLEL1d7 + requiredScopes: + - okta.apps.read + apiEncodedPrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQ0Njd0dBN0JLUG9oZlQKYmZwdW9vZGFIU3o4VSs2cmVrUEFMdzdNbVJMSHovb3JkZ2pmaWl3RFIzaCtjSkpkVEZBd0NiSFJlVUFpZ0VIYwovZWtMTEpKak1LQUlpM2tJOTJJV0M2bUNRckErRVUweTZsRGpxRGNtZG1Gak9YZUJVUVRtYklzQVROdnU4KzZiCkY0bndWZnE2YTFuUmRuRGJOemNYaE9TbTRlV2JDcmMvUTVIYUZGY2F4S3E5NVRobjBPdXJFbG82TVgwTjJtNUMKT28zTjQvMjArZ21Rc2cyamtiMjdqdGNSVjZIUHBmRFhRZHMwNmZRVzhGZVMxZlIrN1pDOEdzbEIwMjlhL1ZXTAp4QWNIL240cE5FSldSM04vL3JNYys1R2VtOHM2MlJNVEVCbmZBK1BEL01DMWJtN1I0ZVVHTXNKOUgwRHBIY1pMCmtlaWdRZnlaQWdNQkFBRUNnZ0VBQlRGdzRPSUZCeVRMMEFYenowMjNGN1pMb1N2eU4yOWhuUmdDZmRDbU44QW0KMUc0WmdsU3MxZUNWZ21zVzJKSCtLenRua2RCQzVseTJ3b1oxTFpXenFqRTRYYjYzcmN5elllOUs2ejJlYUlvbAp5WjRjWkVQQkZrM21LSjRVRE5qZDJoSitJaC90TFlFV2dhUVpRTEVianlwUTVBN1VCVllZWWw1Ty8vbkVPenpPCmE5cDBhckdIeDRHelBTMnAxeVZhSThQUkMyUnFsNUdnTUxnRlhxTmNZaXpsbmYrNzhLaWtRSzExYkhCTXRCRlUKbzdDWWd5Z0NOQWMxa3lGSXJOSVNxYldFaWJ0OGJYMElVQ2Fpem1RTUtuRG83dXRVbnA0ZTZwU1lQbkU5SVkvdApVdTNKNXVqaktEUDdxUk1wdUNEMDU3WjNHbXI5YWRkcmw0dnFWS2szZFFLQmdRQzMzWVB5YlgzTXRQalRoeXM0CmpWSk5LL2VOTFJ2RjgxTUplS0xIa3VIbkUzSHZzL0ovU2ZVL1U2S2JHT3pOQlBzR3ZwUzZsczMrWUd1TTd4WHYKd3ZZODc0eVBZTS9oRkUrTWhEbVNDZWNmdm1qZTRDU2RBYjFPRWQ5ZHRjYTJHVU5FNEhBRHlVWVRPeWt0c0hndwp4UnZiWDlHZk1ERHdURVhudXVjSDhLcFZ6d0tCZ1FDMW9LZ2xKbGFFelJKUk1QSnE3RlY2WUV4NEo3cVB3aG1GClZJTkNHQUZOSWxhUjRDWG5OYjFma0htM1VkVmdyV3lKby94OCtZSDRweXZWZjNWM0NUWjRhMzdMOVRtQjBTNksKYU9IOFplc295Mi9tOWlqRk9wT3FwQ0ZTaFJmWTUyU29WanVISnFPY0I4aE52Vm1vK1dDVGl5blFzWDhveXE2Mgp1eHEvcVJBSkZ3S0JnUUN4MjlKYm5KYm9ndGVBcDJ5ajAvRWRQYjdHRGpDamwvRm5aQTd5eDU5SERJUld2OWVBClVtYXV6NVNvTzhBMXd1K2hZcEkwdk5TZmtWMzRndjdSWStNV3B4TnRUdFZJZ1lGQ0NGWTRjdVBrelNoZEVLM2EKUTJpQU1NSEZ3S1ZzV1p1ODhPN3FlclVTdlZQa0lxVGhhSXE5OXo2cm9zNTBaUlBxU2Q1YXkrKzUrUUtCZ0d5QgpQZkp6cE54UlpzLzZYZGhpdCs0VCtac09vUFdoRDM0SHJ5S2RGS253Q2FlOE1PaWZ3aktGTFRISFFhSXYrTmVCCmtDVlpLYnhTb20wNWFBTmxEWldESW96V1F6UzZzd01kQldTenZuandrRGw2ZFlEZUxibVR0QlNJVG1iV1ZkdjcKS0RUbGNIaVdiYU9EcXp5M1Btcm1pR1NVcFZMSlF2Y0hjRU52ekpTaEFvR0JBSUxIa2U3aG1Md0JWRDU1SEwzUQpBMDFHUGVWTk9DeCthTlNMMHdTbVlXc3F5MDcvRHAzc3hVVUN0Q1YvN25JY2hnVjFDQTZ4dCs0MkF5VWhzVW9kCmh2MnNQTUw2OFZBSGVSQ3lwTDh5bW5seWZjNmpMS2FqaHBWSmxQcWduSUVNTGZvNXM0UXB1VG9RVUkrZXI3dGIKSTlGRVBGYzlKa21hYWlzcjkxOHNnT0IyCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= + jwt: + nbf: 5s + ttl: 5m + issuer: http://localhost:9000 + jwtEncodedPrivateKeyJWK: eyJwIjoieC1yaFlLVVM2TnpRd0FCYjVmakNEMGl1NlM0MFAySUtQd3pnaUJqU3VjTDZ3VFpoYU4tbTBfZHBEdGhwMHZVQjQyR01LQ2ZHNklWNlFHSV91eF80c3I1QTBRSF9sY09jNC1DbTBWal9Udy1DcFRYbnRaVlJSSDlSN00tdDJ1WXNvT1ZyaXJsUUwxdW1ybThPdjkzVnBUWnJ4QlB6UXBlejZvVGJxZUQ0WF9jIiwia3R5IjoiUlNBIiwicSI6InlYYlhQamJHRmo0cUN3RWJqSUpMQ3hQS1FkTnduX2MtQ0M0ZVBma3UyNTR2VW1jeE1IQ1Q0UGtmQ3ZiTXlKU2plWUxzRFZwY0M1eThqeGJwLXpVMUF3WDJvZk15ZEhJa0RfSW51cjVXM1J2U1ZGUFFqR01YVk5Qc09LU1hxRUUzb3BfSU9QZEtUcXhBR3NZMkhYVEZDYVJSU25SdHMwQnV4ZS10SlZjbnpHcyIsImQiOiJQdmk3YnpOZy1ZekZQcWxsRlNHdXk0UnV5cGE0SDctN1lIZnZEb1pKVktqZFZIcHBqVHNsbjRmZWxicEYxQWJ1c2R2blJnU2QzSHVWQWVTTi1rT2dRbDR6SlNJLThvdDhSd29EQU4wSXNadGg0UDhSbTMwa0JFcFdMR0xPb3Q3ZkFWRDRMSzJFTjVEUlU5dWVVWmNoaFpmcDJwaGl2cHJ4TVluTnlhMzNXSm1oTHdSUFRRVjBIY3JmYk9kVG82a2FHUllfZkpCdHRjd2QzWlQ0dzljOXd6ZzFJT0t6Ul96S2g5VkR1b2Y3SWF0ekNab0ZzeUZ5ZHgwbHZxalZjRXAxSllQMTFBY0VOaUdYOHBSTXpzVktmaUhuNlBET2ZoSXBTU1lBd21wYWI3WGF6V2ZWbEZyam5VQXlpN2wyZV90U1lwMGc1RnpZcjB6NDZrTWo1YnBsIiwiZSI6IkFRQUIiLCJxaSI6IkdWbTR6WllDeTNVNEF6TmhSdE5FWFhzVl9ZYm9CZXR5SS1FRjhhcHNsUGc4YTBhMElzXzFZTTZndTQ4ZlNndVE1WFRpN2RVMURJLTZaR2JSbmVvMXVGb0R1M2RsVGR1dXdrcWx6XzJIREphY1dWZjFWQkRSNkdBSjJ3eWNXckdMM0VkM0k4eGtBeHUzMnlYUGJ0YjlpUy1pRF9WQmo1LVJoSktIUXhHbGNSTSIsImRwIjoid0p5V1JHMEd5UUJteDNZUkZJTVZSWEI3eFFIVktQUW1keFRMQjVVVEFoTFBVWFE1YWJlQm5sdVRCdENQTk1jRjZMTkZQRE1HdTJST290V0dIWjN5R1JTZ2tqN2dwc1J1MWtiTnNvbVNnZk9wcGM5SHpYVnRkUmRPTVdEdVdpYkZfTWJOVkR5eS1zM015LWNJU09kTVBmOHUyUjEzbEVOZ19xUy1sdS1fbllVIiwiZHEiOiJyRXd2MzJ4VzB4VU5QZVlQbW9hZ0NYUS1hVGVjdmFKazhmZ0hNemRXUk1zdmE0a0hmNGI0WWRLTkl3Slp0ejJ2NWE3N2xKdnYxcHFRaE11ekJuM0Z2YlV1N2VpaEFRZlJJYllYRmxYTTBrTUdDY3E0dENmV18xeFRUVW91emQ0ZzU3dEJNTDhGVk8xcDBid3M4ZG80M1hzamJzck9PeHhpNEhPUG9EeS1zOHMiLCJuIjoiblZRNVQ1MFk3Q3NBZkhfWllzQjBhRVFHYnlYcklQdDU1dG5OTGZNSWQwbWJYM1ljdVB6cVVQbVJzYlhiNmNPYmlXT1k1Znk2UGxfaEZDeUs2em9qU1JxaFdCd2dMcHo2NUg3NVJ2bVk5Y2FQbndLSXdPOWhpS2ZHTW5DMkdvS3U2S1otcFFLNXlHaUUwRGhVRGE0Q3gxa0h4NlJUUzVoSXlHZHRFOXk5eGlCU0RJODI0eXVwZ1Z5SkYtU1cteHBINVFYdy1saUxGdVBwSFpnWnQyNEhVRlBPM1JqcXJXTmNkWUZ0S00tZGhzWkxMQXp0cEZSMGlqY3M1SEdjbUVlWnRpaVBJYzFpUF9NWlZGSV9SbnVQdzBxbENFRDF4UGdqeXhzT3ZScDlIdU85NDVfenlib2tyYzlVbTljZnpTTEd3WmdJSW9HZVdtc2VRYWR0Zy1ud1BRIn0= + +# Ensure these are disabled in production +springdoc: + swagger-ui: + path: /swagger/ui.html + api-docs: + path: /swagger/api-docs + +#Uncomment for verbose logging +logging: + level: + web: debug + org.springframework.web: debug + com.okta: debug diff --git a/buildSrc/src/main/kotlin/reportstream.project-conventions.gradle.kts b/buildSrc/src/main/kotlin/reportstream.project-conventions.gradle.kts index 34c9d7b3d99..f8f9a6bd43d 100644 --- a/buildSrc/src/main/kotlin/reportstream.project-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/reportstream.project-conventions.gradle.kts @@ -69,10 +69,10 @@ dependencies { // Common test dependencies testImplementation(kotlin("test-junit5")) testImplementation("io.mockk:mockk:1.13.11") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.11.3") testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.28.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.2") - testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.11.3") + testImplementation("org.junit.jupiter:junit-jupiter:5.11.3") testImplementation("org.testcontainers:testcontainers:1.19.8") testImplementation("org.testcontainers:junit-jupiter:1.19.8") testImplementation("org.testcontainers:postgresql:1.19.8") diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index d372ead6770..0ecd142fbee 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -13,6 +13,7 @@ repositories { dependencies { implementation("org.apache.commons:commons-lang3:3.17.0") + implementation("com.nimbusds:nimbus-jose-jwt:9.41.1") testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.28.1") testImplementation("org.apache.commons:commons-compress:1.27.1") diff --git a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/StringUtilities.kt b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/StringUtilities.kt index ad331af2b38..5e3d4d8d9c1 100644 --- a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/StringUtilities.kt +++ b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/StringUtilities.kt @@ -1,6 +1,7 @@ package gov.cdc.prime.reportstream.shared import org.apache.commons.lang3.StringUtils +import java.util.Base64 /** * A collection of string utilities @@ -44,4 +45,10 @@ object StringUtilities { } return truncated.trimEnd() } + + /** + * Handy extension functions for base 64 encoding/decoding + */ + fun String.base64Encode(): String = Base64.getEncoder().encodeToString(this.toByteArray(Charsets.UTF_8)) + fun String.base64Decode(): String = String(Base64.getDecoder().decode(this), Charsets.UTF_8) } \ No newline at end of file diff --git a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZService.kt b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZService.kt new file mode 100644 index 00000000000..52668e7cfd3 --- /dev/null +++ b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZService.kt @@ -0,0 +1,64 @@ +package gov.cdc.prime.reportstream.shared.auth + +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTConstants +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTReader + +/** + * Shared authorization service to allow routes to check if an incoming request should be allowed access + */ +class AuthZService( + private val oktaGroupsJWTReader: OktaGroupsJWTReader, +) { + + private val adminGroup = "DHPrimeAdmins" + private val senderPrefix = "DHSender_" + + /** + * Is a sender authorized access given the client ID header? + * + * This function takes in a request headers function to be web framework agnostic. It will + * do the work of reading the Okta-Groups header, parsing the JWT, and checking the values within. + */ + fun isSenderAuthorized(clientId: String, requestHeaderFn: (String) -> String?): Boolean { + return requestHeaderFn(OktaGroupsJWTConstants.OKTA_GROUPS_HEADER)?.let { oktaGroupsHeader -> + val oktaGroupsJWT = oktaGroupsJWTReader.read(oktaGroupsHeader) + isSenderAuthorized(clientId, oktaGroupsJWT.groups) + } ?: false + } + + /** + * Simpler sender authorization check function that assumings you have the JWT parsing already completed + */ + fun isSenderAuthorized(clientId: String, oktaGroups: List): Boolean { + return oktaGroups.any { senderAuthorized(clientId, it) } + } + + /** + * Check that a sender matches our client id + * + * A user with an admin group will always be authorized + * + * For other users, we will ensure that our group name suffix matches the organization name prefix + * ex: + * clientId=org.test, oktaGroup=DHSender_org, authorized=true + * clientId=org.test, oktaGroup=DHSender_differentOrg, authorized=false + */ + private fun senderAuthorized(clientId: String, oktaGroup: String): Boolean { + return if (oktaGroup == adminGroup) { + true + } else if (oktaGroup.startsWith(senderPrefix)) { + val oktaOrganization = oktaGroup + .substringAfter(senderPrefix) + .trim() + + val parsedClientId = clientId + .split(".") + .first() + .trim() + + parsedClientId == oktaOrganization + } else { + false + } + } +} \ No newline at end of file diff --git a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWT.kt b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWT.kt new file mode 100644 index 00000000000..2c05b37bdf6 --- /dev/null +++ b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWT.kt @@ -0,0 +1,9 @@ +package gov.cdc.prime.reportstream.shared.auth.jwt + +/** + * Model containing the useful fields from our Okta Groups JWT + */ +data class OktaGroupsJWT( + val appId: String, + val groups: List, +) \ No newline at end of file diff --git a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTConstants.kt b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTConstants.kt new file mode 100644 index 00000000000..9ce11dbfed9 --- /dev/null +++ b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTConstants.kt @@ -0,0 +1,10 @@ +package gov.cdc.prime.reportstream.shared.auth.jwt + +object OktaGroupsJWTConstants { + + // Custom okta groups header name + const val OKTA_GROUPS_HEADER = "Okta-Groups" + + // Non-application users have okta groups automatically injected into this claim + const val OKTA_GROUPS_JWT_GROUP_CLAIM = "groups" +} \ No newline at end of file diff --git a/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReader.kt b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReader.kt new file mode 100644 index 00000000000..3f3c7c116f3 --- /dev/null +++ b/shared/src/main/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReader.kt @@ -0,0 +1,41 @@ +package gov.cdc.prime.reportstream.shared.auth.jwt + +import com.nimbusds.jose.crypto.RSASSAVerifier +import com.nimbusds.jose.jwk.JWK +import com.nimbusds.jose.proc.SecurityContext +import com.nimbusds.jwt.SignedJWT +import com.nimbusds.jwt.proc.BadJWTException +import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode + +/** + * Common Okta Groups JWT reader and validator + */ +class OktaGroupsJWTReader( + publicKey: JWK, +) { + + constructor(encodedJWK: String) : this(JWK.parse(encodedJWK.base64Decode())) + + private val verifier = RSASSAVerifier(publicKey.toRSAKey()) + private val claimsVerifier = DefaultJWTClaimsVerifier( + null, + setOf(OktaGroupsJWTConstants.OKTA_GROUPS_JWT_GROUP_CLAIM), + ) + + /** + * Ensures our JWT is valid, properly signed, active, and contains the correct claims + */ + fun read(token: String): OktaGroupsJWT { + val parsedToken = SignedJWT.parse(token) + return if (parsedToken.verify(verifier)) { + claimsVerifier.verify(parsedToken.jwtClaimsSet, null) + OktaGroupsJWT( + parsedToken.jwtClaimsSet.subject, + parsedToken.jwtClaimsSet.getStringListClaim(OktaGroupsJWTConstants.OKTA_GROUPS_JWT_GROUP_CLAIM) + ) + } else { + throw BadJWTException("Invalid signature") + } + } +} \ No newline at end of file diff --git a/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/StringUtilitiesTests.kt b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/StringUtilitiesTests.kt index 894eb7614a3..2c6f6ea7dbf 100644 --- a/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/StringUtilitiesTests.kt +++ b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/StringUtilitiesTests.kt @@ -3,9 +3,12 @@ package gov.cdc.prime.reportstream.shared import assertk.assertThat import assertk.assertions.isEqualTo import assertk.assertions.isNull +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode +import gov.cdc.prime.reportstream.shared.StringUtilities.base64Encode import gov.cdc.prime.reportstream.shared.StringUtilities.toIntOrDefault import gov.cdc.prime.reportstream.shared.StringUtilities.trimToNull import org.junit.jupiter.api.Test +import kotlin.test.assertEquals class StringUtilitiesTests { @Test @@ -27,4 +30,16 @@ class StringUtilitiesTests { assertThat(bar.toIntOrDefault()).isEqualTo(0) assertThat(bar.toIntOrDefault(42)).isEqualTo(42) } + + @Test + fun `test base64 encoding and decoding`() { + val testString = "test string!" + + val encoded = testString.base64Encode() + + assertEquals( + encoded.base64Decode(), + testString + ) + } } \ No newline at end of file diff --git a/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZServiceTest.kt b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZServiceTest.kt new file mode 100644 index 00000000000..9f78b361223 --- /dev/null +++ b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/AuthZServiceTest.kt @@ -0,0 +1,63 @@ +package gov.cdc.prime.reportstream.shared.auth + +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTReader +import io.mockk.every +import io.mockk.mockk +import kotlin.test.Test +import kotlin.test.assertEquals + +class AuthZServiceTest { + + inner class Fixture { + val oktaGroupsJWTReader: OktaGroupsJWTReader = mockk() + val service = AuthZService(oktaGroupsJWTReader) + } + + @Test + fun `admin allowed access regardless of client_id`() { + val f = Fixture() + + assertEquals( + f.service.isSenderAuthorized("org.sender", listOf("DHPrimeAdmins")), + true + ) + } + + @Test + fun `sender authorized`() { + val f = Fixture() + + assertEquals( + f.service.isSenderAuthorized("org.sender", listOf("DHSender_org")), + true + ) + } + + @Test + fun `not a sender`() { + val f = Fixture() + + assertEquals( + f.service.isSenderAuthorized("org.sender", listOf("DHSomething_else")), + false + ) + } + + @Test + fun `handle jwt reading`() { + val f = Fixture() + + every { f.oktaGroupsJWTReader.read("jwt") } returns OktaGroupsJWT( + "appId", + listOf("DHSender_org") + ) + + val requestHeaders = mapOf("Okta-Groups" to "jwt") + + assertEquals( + f.service.isSenderAuthorized("org.sender", requestHeaders::getValue), + true + ) + } +} \ No newline at end of file diff --git a/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReaderTest.kt b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReaderTest.kt new file mode 100644 index 00000000000..b645ba76779 --- /dev/null +++ b/shared/src/test/kotlin/gov/cdc/prime/reportstream/shared/auth/jwt/OktaGroupsJWTReaderTest.kt @@ -0,0 +1,112 @@ +package gov.cdc.prime.reportstream.shared.auth.jwt + +import com.nimbusds.jose.JWSAlgorithm +import com.nimbusds.jose.JWSHeader +import com.nimbusds.jose.crypto.RSASSASigner +import com.nimbusds.jose.jwk.RSAKey +import com.nimbusds.jwt.JWTClaimsSet +import com.nimbusds.jwt.SignedJWT +import com.nimbusds.jwt.proc.BadJWTException +import org.junit.jupiter.api.assertThrows +import java.security.KeyPairGenerator +import java.security.interfaces.RSAPrivateKey +import java.security.interfaces.RSAPublicKey +import java.time.Clock +import java.time.Duration +import java.time.Instant +import java.time.ZoneId +import java.util.Date +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertEquals + +class OktaGroupsJWTReaderTest { + + inner class Fixture { + val clock = Clock.fixed(Instant.now(), ZoneId.of("UTC")) + val keyPair = generateRSAKeyPair() + val privateKey = keyPair.first + val publicKey = keyPair.second + val service = OktaGroupsJWTReader(publicKey) + + fun generateRSAKeyPair(): Pair { + val keyGen = KeyPairGenerator.getInstance("RSA") + keyGen.initialize(2048) + val keyPair = keyGen.generateKeyPair() + + val privateJWK = RSAKey.Builder(keyPair.public as RSAPublicKey) + .privateKey(keyPair.private as RSAPrivateKey) + .build() + val publicJWK = privateJWK.toPublicJWK() + return Pair(privateJWK, publicJWK) + } + + fun writeJWT( + extraClaims: Map, + privateKey: RSAKey, + ): String { + val now = clock.instant() + val expires = now.plus(Duration.ofMinutes(10)) + val nbf = now.minus(Duration.ofSeconds(5)) + val claimsSetBuilder = JWTClaimsSet.Builder() + .subject("appId") + .issuer("issuer") + .jwtID(UUID.randomUUID().toString()) + .issueTime(Date.from(now)) + .notBeforeTime(Date.from(nbf)) + .expirationTime(Date.from(expires)) + + extraClaims.forEach { (key, value) -> claimsSetBuilder.claim(key, value) } + + val signedJWT = SignedJWT( + JWSHeader.Builder(JWSAlgorithm.RS256).build(), + claimsSetBuilder.build() + ) + + signedJWT.sign(RSASSASigner(privateKey)) + + return signedJWT.serialize() + } + } + + @Test + fun `successfully read and validate JWT`() { + val f = Fixture() + + val jwt = f.writeJWT( + mapOf(OktaGroupsJWTConstants.OKTA_GROUPS_JWT_GROUP_CLAIM to listOf("oktaGroup")), + f.privateKey + ) + + val parsed = f.service.read(jwt) + + assertEquals( + parsed, + OktaGroupsJWT("appId", listOf("oktaGroup")) + ) + } + + @Test + fun `missing required claim`() { + val f = Fixture() + + val jwt = f.writeJWT(emptyMap(), f.privateKey) + + assertThrows { + f.service.read(jwt) + } + } + + @Test + fun `invalid signature`() { + val f = Fixture() + + val (badPrivateKey, _) = f.generateRSAKeyPair() + + val jwt = f.writeJWT(emptyMap(), badPrivateKey) + + assertThrows { + f.service.read(jwt) + } + } +} \ No newline at end of file diff --git a/submissions/build.gradle.kts b/submissions/build.gradle.kts index 63f690bc6c9..5138b4bcee5 100644 --- a/submissions/build.gradle.kts +++ b/submissions/build.gradle.kts @@ -1,7 +1,7 @@ apply(from = rootProject.file("buildSrc/shared.gradle.kts")) plugins { - id("org.springframework.boot") version "3.3.5" + id("org.springframework.boot") version "3.4.0" id("io.spring.dependency-management") version "1.1.6" id("reportstream.project-conventions") kotlin("plugin.spring") version "2.0.21" @@ -10,9 +10,8 @@ plugins { group = "gov.cdc.prime" version = "0.0.1-SNAPSHOT" -extra["springCloudAzureVersion"] = "5.14.0" - dependencies { + implementation(project(":shared")) implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") @@ -27,13 +26,10 @@ dependencies { testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.boot:spring-boot-testcontainers") testImplementation("org.xmlunit:xmlunit-core:2.10.0") - testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0") testImplementation("org.apache.commons:commons-compress:1.27.1") testImplementation("org.springframework.security:spring-security-test") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.9.0") - implementation(project(":shared")) } // There is a conflict in logging implementations. Excluded these in favor of using log4j-slf4j2-impl @@ -44,7 +40,7 @@ configurations.all { dependencyManagement { imports { - mavenBom("com.azure.spring:spring-cloud-azure-dependencies:${property("springCloudAzureVersion")}") + mavenBom("com.azure.spring:spring-cloud-azure-dependencies:5.18.0") } } diff --git a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/SubmissionsApplication.kt b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/SubmissionsApplication.kt index 4dead92d92b..883247f21cf 100644 --- a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/SubmissionsApplication.kt +++ b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/SubmissionsApplication.kt @@ -2,9 +2,11 @@ package gov.cdc.prime.reportstream.submissions import com.microsoft.applicationinsights.attach.ApplicationInsights import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication @SpringBootApplication +@ConfigurationPropertiesScan class SubmissionsApplication fun main(args: Array) { diff --git a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/AuthConfig.kt b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/AuthConfig.kt new file mode 100644 index 00000000000..88ad05e1115 --- /dev/null +++ b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/AuthConfig.kt @@ -0,0 +1,28 @@ +package gov.cdc.prime.reportstream.submissions.config + +import gov.cdc.prime.reportstream.shared.auth.AuthZService +import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTReader +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +/** + * Configuration class that sets up our various shared Okta groups JWT classes with + * our configured public key + */ +@Configuration +class AuthConfig( + private val jwtKeyConfig: JWTKeyConfig, +) { + + @Bean + fun authZService(): AuthZService { + val oktaGroupsJWTReader = OktaGroupsJWTReader(jwtKeyConfig.jwtEncodedPublicKeyJWK) + return AuthZService(oktaGroupsJWTReader) + } + + @ConfigurationProperties(prefix = "auth") + data class JWTKeyConfig( + val jwtEncodedPublicKeyJWK: String, + ) +} \ No newline at end of file diff --git a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/SecurityConfig.kt b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/SecurityConfig.kt index 437bebe4921..7c87a68ab3b 100644 --- a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/SecurityConfig.kt +++ b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/config/SecurityConfig.kt @@ -21,6 +21,7 @@ class SecurityConfig { .authorizeHttpRequests { authorize -> authorize // TODO: add routes which require authentication here when required + .requestMatchers("/api/v1/reports").authenticated() .anyRequest().permitAll() // currently allow all requests unauthenticated } .oauth2ResourceServer { diff --git a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/controllers/SubmissionController.kt b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/controllers/SubmissionController.kt index cec852bc193..1a38591c233 100644 --- a/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/controllers/SubmissionController.kt +++ b/submissions/src/main/kotlin/gov/cdc/prime/reportstream/submissions/controllers/SubmissionController.kt @@ -8,6 +8,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import gov.cdc.prime.reportstream.shared.BlobUtils import gov.cdc.prime.reportstream.shared.QueueMessage import gov.cdc.prime.reportstream.shared.Submission +import gov.cdc.prime.reportstream.shared.auth.AuthZService import gov.cdc.prime.reportstream.submissions.SubmissionDetails import gov.cdc.prime.reportstream.submissions.SubmissionReceivedEvent import gov.cdc.prime.reportstream.submissions.TelemetryService @@ -16,6 +17,7 @@ import jakarta.servlet.http.HttpServletRequest import org.slf4j.LoggerFactory import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.authorization.AuthorizationDeniedException import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken import org.springframework.web.bind.MissingRequestHeaderException @@ -46,6 +48,7 @@ class SubmissionController( private val tableClient: TableClient, private val telemetryService: TelemetryService, private val allowedParametersConfig: AllowedParametersConfig, + private val authZService: AuthZService, ) { /** * Submits a report. @@ -62,6 +65,7 @@ class SubmissionController( * @return a ResponseEntity containing the reportID, status, and timestamp */ @PostMapping("/api/v1/reports", consumes = ["application/hl7-v2", "application/fhir+ndjson"]) + @PreAuthorize("hasAuthority('SCOPE_sender')") fun submitReport( @RequestHeader headers: Map, @RequestHeader("Content-Type") contentType: String, @@ -72,6 +76,12 @@ class SubmissionController( @RequestBody data: String, request: HttpServletRequest, ): ResponseEntity<*> { + val authorized = authZService.isSenderAuthorized(clientId, request::getHeader) + if (!authorized) { + logger.warn("Sender is not authorized to submit reports as $clientId") + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null) + } + val reportId = UUID.randomUUID() val reportReceivedTime = Instant.now() val contentTypeMime = contentType.substringBefore(';') diff --git a/submissions/src/main/resources/application.yml b/submissions/src/main/resources/application.yml index b4794b2d1fa..394bb54d6d6 100644 --- a/submissions/src/main/resources/application.yml +++ b/submissions/src/main/resources/application.yml @@ -6,8 +6,12 @@ spring: resourceserver: jwt: issuer-uri: https://reportstream.oktapreview.com/oauth2/ausekaai7gUuUtHda1d7 - server: - port: 8880 + +server: + port: 8880 + +auth: + jwtEncodedPublicKeyJWK: eyJrdHkiOiJSU0EiLCJlIjoiQVFBQiIsIm4iOiJuVlE1VDUwWTdDc0FmSF9aWXNCMGFFUUdieVhySVB0NTV0bk5MZk1JZDBtYlgzWWN1UHpxVVBtUnNiWGI2Y09iaVdPWTVmeTZQbF9oRkN5SzZ6b2pTUnFoV0J3Z0xwejY1SDc1UnZtWTljYVBud0tJd085aGlLZkdNbkMyR29LdTZLWi1wUUs1eUdpRTBEaFVEYTRDeDFrSHg2UlRTNWhJeUdkdEU5eTl4aUJTREk4MjR5dXBnVnlKRi1TVy14cEg1UVh3LWxpTEZ1UHBIWmdadDI0SFVGUE8zUmpxcldOY2RZRnRLTS1kaHNaTExBenRwRlIwaWpjczVIR2NtRWVadGlpUEljMWlQX01aVkZJX1JudVB3MHFsQ0VEMXhQZ2p5eHNPdlJwOUh1Tzk0NV96eWJva3JjOVVtOWNmelNMR3daZ0lJb0dlV21zZVFhZHRnLW53UFEifQ== azure: storage: diff --git a/submissions/src/test/kotlin/SubmissionControllerIntegrationTest.kt b/submissions/src/test/kotlin/SubmissionControllerIntegrationTest.kt index f2c87c11f50..86a148dd650 100644 --- a/submissions/src/test/kotlin/SubmissionControllerIntegrationTest.kt +++ b/submissions/src/test/kotlin/SubmissionControllerIntegrationTest.kt @@ -21,6 +21,8 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.annotation.Import import org.springframework.http.MediaType +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.DynamicPropertyRegistry import org.springframework.test.context.DynamicPropertySource @@ -96,11 +98,22 @@ class SubmissionControllerIntegrationTest { mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.valueOf("application/hl7-v2")) - .header("client_id", "testClient") + .header("client_id", "org.test") .header("payloadname", "testPayload") .header("x-azure-clientip", "127.0.0.1") + .header( + "Okta-Groups", + "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhcHBJZCIsIm5iZiI6MTczMDkxMTczMiwiaXNzIjoiSSdtIHRoZSBpc3N1ZXIiLCJ" + + "ncm91cHMiOlsiREhTZW5kZXJfb3JnIl0sImV4cCI6NDg4NDUxMTczNywiaWF0IjoxNzMwOTExNzM3LCJqdGkiOiI1YjA" + + "5MjhjMC1jMDZmLTQ5OGItOWFmZS1kZDEwODJlNDliMmIifQ.EP3v_kCzWGTWIhhibwTWSzQGMSYVvogbqvrLiwSbTD0X" + + "ADRhiBlD4AIJwa_aUp9Zxnc6fbNKPIHWydzYZNUzzMmRkIzSYfmcj1oRjvf0HiXqw-8tSBT1sTBOlpGxWpTuPPnvV9A7" + + "ZqqJ614v8x_NyxPdswOdfFpgtSb_nDFLaLR3Tzo5A0JFeNWtlOd8U2gp6a57vggCFt9vDMhrOq8QC6gYJPUn1u7Z_Xfd" + + "C1XSm7r3DwcItMbqtVVY1ngixMI7CB0bChcJPgHI37P03IMsVscFrXlPPwxSUkdAe1xZW9w9i0-sI7iLIy78k4gMMXgH" + + "W64oopgua3Fdalo-LhDsJA" + ) ) .andExpect(MockMvcResultMatchers.status().isCreated) @@ -124,7 +137,7 @@ class SubmissionControllerIntegrationTest { // val queueMessageContent = objectMapper.readValue(/* content = */ messages[0].body.toString(), /* valueType = */ // QueueMessage.ReceiveQueueMessage::class.java) val headers = deserializedMessage.headers as Map<*, *> - assertEquals("testClient", headers["client_id"]) + assertEquals("org.test", headers["client_id"]) assertEquals("application/hl7-v2;charset=UTF-8", headers["Content-Type"]) assertEquals("testPayload", headers["payloadname"]) assertEquals("127.0.0.1", headers["x-azure-clientip"]) diff --git a/submissions/src/test/kotlin/SubmissionControllerTest.kt b/submissions/src/test/kotlin/SubmissionControllerTest.kt index 74314d5b291..59f0ae710b4 100644 --- a/submissions/src/test/kotlin/SubmissionControllerTest.kt +++ b/submissions/src/test/kotlin/SubmissionControllerTest.kt @@ -10,9 +10,9 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import gov.cdc.prime.reportstream.shared.QueueMessage import gov.cdc.prime.reportstream.shared.QueueMessage.ObjectMapperProvider +import gov.cdc.prime.reportstream.shared.auth.AuthZService import gov.cdc.prime.reportstream.submissions.TelemetryService import gov.cdc.prime.reportstream.submissions.config.AllowedParametersConfig -import gov.cdc.prime.reportstream.submissions.config.AzureConfig import gov.cdc.prime.reportstream.submissions.config.SecurityConfig import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -32,9 +32,12 @@ import org.mockito.MockitoAnnotations import org.mockito.kotlin.argumentCaptor import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Import import org.springframework.http.MediaType +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.jwt import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders import org.springframework.test.web.servlet.result.MockMvcResultMatchers @@ -44,24 +47,55 @@ import java.util.Base64 import java.util.UUID @WebMvcTest(SubmissionController::class) -@Import(AzureConfig::class, SecurityConfig::class, AllowedParametersConfig::class) +@Import(SecurityConfig::class, AllowedParametersConfig::class) class SubmissionControllerTest { @Autowired private lateinit var mockMvc: MockMvc - @MockBean + @Autowired private lateinit var blobContainerClient: BlobContainerClient - @MockBean + @Autowired private lateinit var queueClient: QueueClient - @MockBean + @Autowired private lateinit var tableClient: TableClient - @MockBean + @Autowired private lateinit var telemetryService: TelemetryService + @Autowired + private lateinit var authZService: AuthZService + + @TestConfiguration + class Config { + @Bean + fun blobContainerClient(): BlobContainerClient { + return mock() + } + + @Bean + fun queueClient(): QueueClient { + return mock() + } + + @Bean + fun tableClient(): TableClient { + return mock() + } + + @Bean + fun telemetryService(): TelemetryService { + return mock() + } + + @Bean + fun authZService(): AuthZService { + return mock() + } + } + private lateinit var objectMapper: ObjectMapper private lateinit var blobClient: BlobClient @@ -125,9 +159,12 @@ class SubmissionControllerTest { `when`(blobClient.blobUrl).thenReturn(expectedBlobUrl) `when`(queueClient.sendMessage(anyString())).thenReturn(sendMessageResult) + `when`(authZService.isSenderAuthorized(org.mockito.kotlin.any(), org.mockito.kotlin.any<(String) -> String>())) + .thenReturn(true) mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.valueOf("application/hl7-v2")) .header("client_id", "testClient") @@ -171,9 +208,12 @@ class SubmissionControllerTest { `when`(blobClient.blobUrl).thenReturn(expectedBlobUrl) `when`(queueClient.sendMessage(anyString())).thenReturn(sendMessageResult) + `when`(authZService.isSenderAuthorized(org.mockito.kotlin.any(), org.mockito.kotlin.any<(String) -> String>())) + .thenReturn(true) mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.valueOf("application/fhir+ndjson")) .header("client_id", "testClient") @@ -205,6 +245,7 @@ class SubmissionControllerTest { mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.APPLICATION_JSON) .header("client_id", "testClient") @@ -221,6 +262,7 @@ class SubmissionControllerTest { mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.valueOf("application/hl7-v2")) .header("payloadname", "testPayload") @@ -238,11 +280,14 @@ class SubmissionControllerTest { val data = mapOf("key" to "value") val requestBody = objectMapper.writeValueAsString(data) + `when`(authZService.isSenderAuthorized(org.mockito.kotlin.any(), org.mockito.kotlin.any<(String) -> String>())) + .thenReturn(true) doThrow(RuntimeException("Blob storage failure")) .`when`(blobClient).upload(any(ByteArrayInputStream::class.java), anyLong()) mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.parseMediaType("application/hl7-v2")) .header("client_id", "testClient") @@ -260,11 +305,14 @@ class SubmissionControllerTest { val data = mapOf("key" to "value") val requestBody = objectMapper.writeValueAsString(data) + `when`(authZService.isSenderAuthorized(org.mockito.kotlin.any(), org.mockito.kotlin.any<(String) -> String>())) + .thenReturn(true) doNothing().`when`(blobClient).upload(any(ByteArrayInputStream::class.java), anyLong()) doThrow(RuntimeException("Queue service failure")).`when`(queueClient).sendMessage(anyString()) mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.parseMediaType("application/hl7-v2")) .header("client_id", "testClient") @@ -300,9 +348,12 @@ class SubmissionControllerTest { // Mock the UUID generation to ensure a predictable report ID val uuidMockedStatic = mockStatic(UUID::class.java) uuidMockedStatic.`when` { UUID.randomUUID() }.thenReturn(reportId) + `when`(authZService.isSenderAuthorized(org.mockito.kotlin.any(), org.mockito.kotlin.any<(String) -> String>())) + .thenReturn(true) mockMvc.perform( MockMvcRequestBuilders.post("/api/v1/reports") + .with(jwt().authorities(SimpleGrantedAuthority("SCOPE_sender"))) .content(requestBody) .contentType(MediaType.valueOf("application/hl7-v2")) .header("client_id", "testClient") From e564319f2aa26991eb614d66ff4232894d006934 Mon Sep 17 00:00:00 2001 From: david-navapbc <165852085+david-navapbc@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:55:43 -0700 Subject: [PATCH 03/13] Platform/david navapbc/15514/hl7 oml aui fhir mapping (#16619) * probably not quite right yet * asdf * mr push face * asdfA * asdf * tests pass * test still failing * expression works but test still fails * no it was right the first time and it's still not working: * mr not working face * working * PR Feedback * MSH-10 is a required field * Adding Coverage/IN1 integration test * Build failing because of file name case sensitivity, maybe * Reapplying after merge * Adding IN1 Coverage to OML integration test * PR feedback * Few more small changes --------- Co-authored-by: David Holiday Co-authored-by: Josh Fisk --- .../hl7/datatypes/AUI/AUIExtension.yml | 46 +++++++++++++ .../HL7/catchall/hl7/message/OML_O21.yml | 7 ++ .../catchall/hl7/segments/IN1/Coverage.yml | 16 +++++ .../hl7_mapping/OML_O21/OML_O21-base.yml | 9 +++ .../datatypes/extensionAUI/AUI.yml | 15 +++++ .../hl7_mapping/resources/Coverage/IN1.yml | 12 ++++ .../catchall/aui/AUIExtensionTests.kt | 16 +++++ .../mappinginventory/catchall/in1/IN1Tests.kt | 16 +++++ .../catchall/aui/AUI-to-Extension.fhir | 67 +++++++++++++++++++ .../catchall/aui/AUI-to-Extension.hl7 | 3 + .../catchall/in1/IN1-to-Coverage.fhir | 67 +++++++++++++++++++ .../catchall/in1/IN1-to-Coverage.hl7 | 3 + .../catchall/omlo21/oml_o21-full.fhir | 26 +++++++ .../catchall/omlo21/oml_o21-full.hl7 | 1 + 14 files changed, 304 insertions(+) create mode 100644 prime-router/metadata/HL7/catchall/hl7/datatypes/AUI/AUIExtension.yml create mode 100644 prime-router/metadata/HL7/catchall/hl7/segments/IN1/Coverage.yml create mode 100644 prime-router/src/main/resources/metadata/hl7_mapping/datatypes/extensionAUI/AUI.yml create mode 100644 prime-router/src/main/resources/metadata/hl7_mapping/resources/Coverage/IN1.yml create mode 100644 prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/aui/AUIExtensionTests.kt create mode 100644 prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/in1/IN1Tests.kt create mode 100644 prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.fhir create mode 100644 prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.hl7 create mode 100644 prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.fhir create mode 100644 prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.hl7 diff --git a/prime-router/metadata/HL7/catchall/hl7/datatypes/AUI/AUIExtension.yml b/prime-router/metadata/HL7/catchall/hl7/datatypes/AUI/AUIExtension.yml new file mode 100644 index 00000000000..af09ea3cb7d --- /dev/null +++ b/prime-router/metadata/HL7/catchall/hl7/datatypes/AUI/AUIExtension.yml @@ -0,0 +1,46 @@ +# $schema: ./../../../../../json_schema/fhir/hl7-to-fhir-mapping-resource-template.json + +url: + type: STRING + valueOf: IN1.14 + +extension: + generateList: true + expressionType: nested + expressions: + - expressionType: nested + vars: + aui1: STRING_ALL, AUI.1 + condition: $aui1 NOT_NULL + expressionsMap: + url: + type: STRING + valueOf: AUI.1 + valueString: + type: STRING + expressionType: HL7Spec + valueOf: AUI.1 + - expressionType: nested + vars: + aui2: STRING_ALL, AUI.2 + condition: $aui2 NOT_NULL + expressionsMap: + url: + type: STRING + valueOf: AUI.2 + valueString: + type: STRING + expressionType: HL7Spec + valueOf: AUI.2 + - expressionType: nested + vars: + aui3: STRING_ALL, AUI.3 + condition: $aui3 NOT_NULL + expressionsMap: + url: + type: STRING + valueOf: AUI.3 + valueString: + type: STRING + expressionType: HL7Spec + valueOf: AUI.3 diff --git a/prime-router/metadata/HL7/catchall/hl7/message/OML_O21.yml b/prime-router/metadata/HL7/catchall/hl7/message/OML_O21.yml index 0ea61641d00..f3940d00669 100644 --- a/prime-router/metadata/HL7/catchall/hl7/message/OML_O21.yml +++ b/prime-router/metadata/HL7/catchall/hl7/message/OML_O21.yml @@ -77,6 +77,13 @@ resources: additionalSegments: - MSH + - resourceName: Coverage + segment: .IN1 + group: PATIENT.INSURANCE + resourcePath: segments/IN1/Coverage + repeats: false + isReferenced: false + - resourceName: ServiceRequest segment: .ORC group: ORDER diff --git a/prime-router/metadata/HL7/catchall/hl7/segments/IN1/Coverage.yml b/prime-router/metadata/HL7/catchall/hl7/segments/IN1/Coverage.yml new file mode 100644 index 00000000000..8479f85f8bc --- /dev/null +++ b/prime-router/metadata/HL7/catchall/hl7/segments/IN1/Coverage.yml @@ -0,0 +1,16 @@ +# $schema: ./../../../../../json_schema/fhir/hl7-to-fhir-mapping-resource-template.json + +resourceType: Coverage + +id: + type: STRING + valueOf: "GeneralUtils.generateResourceId()" + expressionType: JEXL + +extension: + expressionType: nested + generateList: true + expressions: + - expressionType: resource + valueOf: datatypes/AUI/AUIExtension + specs: IN1.14 \ No newline at end of file diff --git a/prime-router/src/main/resources/metadata/hl7_mapping/OML_O21/OML_O21-base.yml b/prime-router/src/main/resources/metadata/hl7_mapping/OML_O21/OML_O21-base.yml index 408334e10f3..305e890b694 100644 --- a/prime-router/src/main/resources/metadata/hl7_mapping/OML_O21/OML_O21-base.yml +++ b/prime-router/src/main/resources/metadata/hl7_mapping/OML_O21/OML_O21-base.yml @@ -34,6 +34,15 @@ elements: resourceIndex: patientIndex schema: classpath:/metadata/hl7_mapping/OML_O21/base/patient/patient-base.yml + - name: insurance + resource: 'Bundle.entry.resource.ofType(Coverage)' + # todo: update logic when Coverage.subscriber is mapped (IN1-16/IN1-17) + # https://github.com/CDCgov/prime-reportstream/issues/15500 + # resource: 'Bundle.entry.resource.ofType(Coverage).where(subscriber.resolve().id = %resource.entry.resource.ofType(Patient).id)' + schema: classpath:/metadata/hl7_mapping/resources/Coverage/IN1.yml + constants: + hl7SegmentGroup: '/PATIENT/INSURANCE' + - name: order-base resource: 'Bundle.entry.resource.ofType(ServiceRequest).where(subject.resolve().id = %resource.entry.resource.ofType(Patient).id)' resourceIndex: orderIndex diff --git a/prime-router/src/main/resources/metadata/hl7_mapping/datatypes/extensionAUI/AUI.yml b/prime-router/src/main/resources/metadata/hl7_mapping/datatypes/extensionAUI/AUI.yml new file mode 100644 index 00000000000..c04a3d83386 --- /dev/null +++ b/prime-router/src/main/resources/metadata/hl7_mapping/datatypes/extensionAUI/AUI.yml @@ -0,0 +1,15 @@ +# $schema: ./../../../../../../../metadata/json_schema/fhir/fhir-to-hl7-mapping.json + +elements: + + - name: aui-authorization-number + value: [ '%resource.extension.where(url = "AUI.1").value' ] + hl7Spec: [ '%{auiField}-1' ] + + - name: aui-date + value: [ '%resource.extension.where(url = "AUI.2").value' ] + hl7Spec: [ '%{auiField}-2' ] + + - name: aui-source + value: [ '%resource.extension.where(url = "AUI.3").value' ] + hl7Spec: [ '%{auiField}-3' ] diff --git a/prime-router/src/main/resources/metadata/hl7_mapping/resources/Coverage/IN1.yml b/prime-router/src/main/resources/metadata/hl7_mapping/resources/Coverage/IN1.yml new file mode 100644 index 00000000000..fe437d13fce --- /dev/null +++ b/prime-router/src/main/resources/metadata/hl7_mapping/resources/Coverage/IN1.yml @@ -0,0 +1,12 @@ +# $schema: ./../../../../../../../metadata/json_schema/fhir/fhir-to-hl7-mapping.json + +constants: + hl7IN1Field: '%{hl7SegmentGroup}/IN1' + +elements: + + - name: aui-extension + resource: '%resource.extension.where(url = "IN1.14")' + schema: classpath:/metadata/hl7_mapping/datatypes/extensionAUI/AUI.yml + constants: + auiField: '%{hl7IN1Field}-14' \ No newline at end of file diff --git a/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/aui/AUIExtensionTests.kt b/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/aui/AUIExtensionTests.kt new file mode 100644 index 00000000000..a4801c7c450 --- /dev/null +++ b/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/aui/AUIExtensionTests.kt @@ -0,0 +1,16 @@ +package gov.cdc.prime.router.datatests.mappinginventory.aui + +import gov.cdc.prime.router.datatests.mappinginventory.verifyHL7ToFHIRToHL7Mapping +import org.junit.jupiter.api.Test + +class AUIExtensionTests { + @Test + fun `test AUI mapped to AUIExtension`() { + assert( + verifyHL7ToFHIRToHL7Mapping( + "catchall/aui/AUI-to-Extension", + outputSchema = "classpath:/metadata/hl7_mapping/OML_O21/OML_O21-test.yml" + ).passed + ) + } +} \ No newline at end of file diff --git a/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/in1/IN1Tests.kt b/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/in1/IN1Tests.kt new file mode 100644 index 00000000000..691f8ce6023 --- /dev/null +++ b/prime-router/src/testIntegration/kotlin/datatests/mappinginventory/catchall/in1/IN1Tests.kt @@ -0,0 +1,16 @@ +package gov.cdc.prime.router.datatests.mappinginventory.in1 + +import gov.cdc.prime.router.datatests.mappinginventory.verifyHL7ToFHIRToHL7Mapping +import org.junit.jupiter.api.Test + +class IN1Tests { + @Test + fun `test IN1 mapped to Coverage`() { + assert( + verifyHL7ToFHIRToHL7Mapping( + "catchall/in1/IN1-to-Coverage", + outputSchema = "classpath:/metadata/hl7_mapping/OML_O21/OML_O21-test.yml" + ).passed + ) + } +} \ No newline at end of file diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.fhir b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.fhir new file mode 100644 index 00000000000..bac350c4bb3 --- /dev/null +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.fhir @@ -0,0 +1,67 @@ +{ + "resourceType": "Bundle", + "id": "1732324230716018000.38edba19-1d39-4040-85af-9f5f6248813c", + "meta": { + "lastUpdated": "2024-11-22T17:10:30.720-08:00" + }, + "identifier": { + "system": "https://reportstream.cdc.gov/prime-router", + "value": "MSG00001" + }, + "type": "message", + "entry": [ + { + "fullUrl": "MessageHeader/1732324230752828000.fc7cea9d-d7ca-4378-91d4-ea97c86b4787", + "resource": { + "resourceType": "MessageHeader", + "id": "1732324230752828000.fc7cea9d-d7ca-4378-91d4-ea97c86b4787", + "meta": { + "tag": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0103", + "code": "P" + } + ] + }, + "eventCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v2-0003", + "code": "O21", + "display": "OML^O21^OML_O21" + } + } + }, + { + "fullUrl": "Patient/1732324231018814000.533db9a5-5375-4746-be23-f7140d4a3280", + "resource": { + "resourceType": "Patient", + "id": "1732324231018814000.533db9a5-5375-4746-be23-f7140d4a3280" + } + }, + { + "fullUrl": "Coverage/1732324231019741000.a36368bf-6c63-4970-8948-034a92248964", + "resource": { + "resourceType": "Coverage", + "id": "1732324231019741000.a36368bf-6c63-4970-8948-034a92248964", + "extension": [ + { + "url": "IN1.14", + "extension": [ + { + "url": "AUI.1", + "valueString": "1701" + }, + { + "url": "AUI.2", + "valueString": "19700101" + }, + { + "url": "AUI.3", + "valueString": "DR TEETH AND THE ELECTRIC MAYHEM" + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.hl7 b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.hl7 new file mode 100644 index 00000000000..6d424a80fa2 --- /dev/null +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/aui/AUI-to-Extension.hl7 @@ -0,0 +1,3 @@ +MSH|^~\&|||||||OML^O21^OML_O21|MSG00001|P|2.5.1 +PID|1 +IN1||||||||||||||1701^19700101^DR TEETH AND THE ELECTRIC MAYHEM \ No newline at end of file diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.fhir b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.fhir new file mode 100644 index 00000000000..bac350c4bb3 --- /dev/null +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.fhir @@ -0,0 +1,67 @@ +{ + "resourceType": "Bundle", + "id": "1732324230716018000.38edba19-1d39-4040-85af-9f5f6248813c", + "meta": { + "lastUpdated": "2024-11-22T17:10:30.720-08:00" + }, + "identifier": { + "system": "https://reportstream.cdc.gov/prime-router", + "value": "MSG00001" + }, + "type": "message", + "entry": [ + { + "fullUrl": "MessageHeader/1732324230752828000.fc7cea9d-d7ca-4378-91d4-ea97c86b4787", + "resource": { + "resourceType": "MessageHeader", + "id": "1732324230752828000.fc7cea9d-d7ca-4378-91d4-ea97c86b4787", + "meta": { + "tag": [ + { + "system": "http://terminology.hl7.org/CodeSystem/v2-0103", + "code": "P" + } + ] + }, + "eventCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v2-0003", + "code": "O21", + "display": "OML^O21^OML_O21" + } + } + }, + { + "fullUrl": "Patient/1732324231018814000.533db9a5-5375-4746-be23-f7140d4a3280", + "resource": { + "resourceType": "Patient", + "id": "1732324231018814000.533db9a5-5375-4746-be23-f7140d4a3280" + } + }, + { + "fullUrl": "Coverage/1732324231019741000.a36368bf-6c63-4970-8948-034a92248964", + "resource": { + "resourceType": "Coverage", + "id": "1732324231019741000.a36368bf-6c63-4970-8948-034a92248964", + "extension": [ + { + "url": "IN1.14", + "extension": [ + { + "url": "AUI.1", + "valueString": "1701" + }, + { + "url": "AUI.2", + "valueString": "19700101" + }, + { + "url": "AUI.3", + "valueString": "DR TEETH AND THE ELECTRIC MAYHEM" + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.hl7 b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.hl7 new file mode 100644 index 00000000000..6d424a80fa2 --- /dev/null +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/in1/IN1-to-Coverage.hl7 @@ -0,0 +1,3 @@ +MSH|^~\&|||||||OML^O21^OML_O21|MSG00001|P|2.5.1 +PID|1 +IN1||||||||||||||1701^19700101^DR TEETH AND THE ELECTRIC MAYHEM \ No newline at end of file diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.fhir b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.fhir index 049fc4fbdce..214a988f494 100644 --- a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.fhir +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.fhir @@ -13240,6 +13240,32 @@ ] } }, + { + "fullUrl": "Coverage/1732739201962559000.af1bd55f-2269-4782-a205-39c76d162b0d", + "resource": { + "resourceType": "Coverage", + "id": "1732739201962559000.af1bd55f-2269-4782-a205-39c76d162b0d", + "extension": [ + { + "url": "IN1.14", + "extension": [ + { + "url": "AUI.1", + "valueString": "1701" + }, + { + "url": "AUI.2", + "valueString": "19700101" + }, + { + "url": "AUI.3", + "valueString": "DR TEETH AND THE ELECTRIC MAYHEM" + } + ] + } + ] + } + }, { "fullUrl": "ServiceRequest/1732560947529907000.d8a09a6a-8364-469a-b25b-3af90b0b03a7", "resource": { diff --git a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.hl7 b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.hl7 index 749a5f886cf..23863a51bb8 100644 --- a/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.hl7 +++ b/prime-router/src/testIntegration/resources/datatests/mappinginventory/catchall/omlo21/oml_o21-full.hl7 @@ -8,6 +8,7 @@ NK1|1|SURYAN&Prefix&Own&SpousePrefix&Spouse^GENARO^GR^JR^Sir^Md^L^I^CON&Context NK1|2|SUPERMAN&Prefix&Own&SpousePrefix&Spouse^GENARO^GR^JR^Sir^Md^L^I^CON&Context the namee&HL70448^2000&2030^G^20000501102531^2030501102531^Dr|OTH^Other^HL70063^OT^OTHER RELATIONSHIP^L|4861 20TH AVE^^THUNDER MOUNTAIN^IG^99999^USA^H|^PRN^PH^example2@exmaple.com^1^720^5553954^2^any^^^+1 720 555 3955|^WPN^PH^^1^555^4672293^^^^^+1 555 467 2294|F^Federal Agency^HL70131|20220501102531-0400|20230501102531-0400|||052479^^^^^^20160822|HospitalsRUs^^112233^^^^^^^HRU||N^Not Applicable^HL70001|19860505||||E^English^HL70296|||||||||||^WPN^PH^^1^720^5553954^^^^^+1 720 555 3955|4861 20TH AVE^#B^AURORA^IG^99999^USA^H^World^King^12^8^2017&2025^2020^2021|052479^^^^^^^20210428|||||||^VHN^SAT^^1^314^5553131^^^^^+1 314 555 3132|^AWN^FX^^1^281^5558181^^^^^+1 281 555 8182 PV1|1|O|A&Point OF Care&C^1&Room&3^B&Bed&A^Hospital Assigned&2.4.4.4&ISO^^R^&Building^&Floor^Totally A Real Location^Comprehensive&&UID4This^AA&AssigningAUTH&ISO|R^Routine^HL70007|232323|^^^Hospital Prio&2.4.4.4&ISO^active^location type^^^Description^Entity ID&NAME&UNI&ISO^ASSIGNEE&222.1111.22222&UUID|1^BEETHOVEN^LUDWIG^B^2ND^DR^MD^^Namespace&AssigningSystem&UUID^B^^^DL^^^^^^^^MD~1^BEETHOVEN2^LUDWIG^B^2ND^DR^MD^^Namespace&AssigningSystem&UUID^B^^^DL^^^^^^^^MD|1^MOZART~1^MOZARTJR|1^CHOPIN~1^CHOPINSR|URO^Urology Service^HL70069|^^^^^^^^Its Temporary|P^Passed^HL70087|R^Re-admission^HL70092|RL^Real Life^HL70023||VIP^Very Interesting Person^HL70099|1^BACH~1^BACHtheSecond|H^Human Patient^HL70018|22|||||||||||20020101|C^Collectors^HL70021|1|0|Y^Yes^HL70111|20080101|H^Happy^HL70112|^202305061200|F^Fed^HL70114|H^A Hospital Of Course^HL70115||A^Active^HL70117|^^^^^^^^Pending Location|^^^^^^^^Prior Location|20240801102531-0400|20240801102531-0400|100|199|142|130|alternate visit|A^Account Level^HL70326||Service Description|episode identifier PV2|^^^Hospital PriorPending&2.4.4.4&ISO^active^location type^^^Description^Entity ID&NAME&UNI&ISO^ASSIGNEE&222.1111.22222&UUID||1^AD||||413^V~423^X|20230601102531-0400|20230701102531-0400|5|12|Description|1^BEETHOVEN&VAN&Referral Source Code1&VAL&ROGER^LUDWIG^B^2ND^DR^MD^SRC^&AssigningSystem&ISO^B^A^NPI^DL^^A^NameContext^^G^20220501102531-0400^20230501102531-0400^MD^AssignJ^AssignA~1^BEETHOVEN&VAN&Referral Source Code2&VAL&ROGER^LUDWIG^B^2ND^DR^MD^SRC^&AssigningSystem&ISO^B^A^NPI^DL^^A^NameContext^^G^20220501102531-0400^20230501102531-0400^MD^AssignJ^AssignA||EMP_ILL||||||100^PublicCode|SEC|Org1^1234-5&TestText&LN&1234-5&TestAltText&LN&1&2&OriginalText^123^Check Digit^C1^Assigning Authority&2.1.4.1&ISO^MD^Hospital A&2.16.840.1.113883.9.11&ISO~Org2^1234-5&TestText&LN&1234-5&TestAltText&LN&1&2&OriginalText^123^Check Digit^C1^Assigning Authority&2.1.4.1&ISO^MD^Hospital A&2.16.840.1.113883.9.11&ISO||3^Elective^HL70217|20230501102531-0400|||20220501102531-0400|||||||||444^MODE||123^CARELEVEL1 +IN1||||||||||||||1701^19700101^DR TEETH AND THE ELECTRIC MAYHEM ORC|RE|Specimen123^SPHL-000048^2.16.840.1.114222.4.1.10765^ISO|Specimen12311^SPHL-000048^2.16.840.1.114222.4.1.10765^ISO|Specimen12322^SPHL-000048^2.16.840.1.114222.4.1.10765^ISO|CM|E||Specimen12333&SPHL-000048&2.16.840.1.114222.4.1.10765&ISO^Specimen12333454&SPHL-000048&2.16.840.1.114222.4.1.10765&ISO|20230725|71^^ORC.10Name~71^^ORC.10Name2|82^^ORC.11Name~82^^ORC.11Name2|93^^ORC.12Name~93^^ORC.12Name2|12.12.12&enter location id&L|123^^^+123~1234^^^+1234|202101021000||EO^entering org text^HL79999|ED^entering device text^HL79999|60^^ORC.19Name~60^^ORC.19Name2||CDPH, Viral and Rickettsial Disease Laboratory^^^^^STARLIMS.CDC.Stag&2.16.840.1.114222.4.3.3.2.1.2&ISO^XX^STARLINKS.CDC.Stag&2.16.840.1.114222.8.7.6.5.4.1&ISO^A^SPHL-000048~CDPH, Viral and Rickettsial Disease Laboratory part two^^^^^STARLIMS.CDC.Stag&2.16.840.1.114222.4.3.3.2.1.2&ISO|111 Street St^^Streetsville^ST~112 Street St^^Streetsville^ST|456^^^+456~4567^^^+4567|111 Road Rd^^Roadsville^RD~112 Road Rd^^Roadsville^RD|OS^order status^HL79999||20260404|EMP^Employee^HL70177|I^Inpatient Order^HL70482|EL^Electronic^HL70483|UMM^Universal Modifier^HL70000|20250403|33~332 OBR|1|Placer Identifier^Placer Identifier Namespace^Placer Universal ID^ISO|Filler Identifier^Filler Identifier Namespace^Filler Universal ID^ISO|123^Universal service identifier||202202021022||20240220|1771|1^Collector&VAN&Identifier&VAL&ROGER^LUDWIG^B^2ND^DR^MD^SRC^&AssigningSystem&ISO^B^A^NPI^DL^^A^NameContext~1^Collectorx2&VAN&Identifier&VAL&ROGER^LUDWIG^B^2ND^DR^MD^SRC^&AssigningSystem&ISO^B^A^NPI^DL^^A^NameContext|G|512^Danger code|R^relevent info^ISO|202102021000|ID^BOUIN&Bouin's solution&HL70371^Collection Method^LN&Left Naris&HL70163^^CMMC&Collection Method Modifer Code&HL7|1^Ordering&VAN&Provider&VAL&JollyROGER~2^Ordering&VAN&Provider&VAL&JollyROGER|^WPN^BP^^1^260^7595016^^^^^+1 260 759 5016~^WPN^Internet^order.callback@email.com~^WPN^BP^^1^260^7595016^^^^^+1 260 759 5016~^WPN^Internet^order.callback2@email.com|placer1|placer2|filler1|filler2||100&$^16&code|OTH|F|444&ParentId^888^ParentOBSdescriptor||1^result&VAN&copiesto&VAL&NotSoJollyROGER~2^results&VAN&copiesto&VAL&NotSoJollyROGER|adb4a5cc-50ec-4f1e-95d7-0c1f77cacee1&CSV&11D1111111&CLIA^f34b0f57-1601-4480-ae8a-d4006e50f38d&Other CSV&22D2222222&CLIA2||3216^ReasonForStudy~3216^ReasonForStudy2||123&Assistant&Results Interpreter&S&ESQ&DR&MD&&Assigning Authority&2.1.4.1&ISO^20230401102531-0400^20230501102531-0400^Point of Care^Room 101^Bed A^Hospital A&2.16.840.1.113883.9.11&ISO^active^^Building 123^Floor A~123&Assistant&Results Interpreter&S&ESQ&DR&MD&&Assigning Authority&2.1.4.1&ISO^20230401102531-0400^20230501102531-0400^Point of Care^Room 101^Bed A^Hospital A&2.16.840.1.113883.9.11&ISO^active^^Building 123^Floor A|||20230806123359-0500|||4438^Collectors Comment~4438^Collectors Comment2|||||5019^Procedure Code|887766^Procedure Code Modifier~887766^Procedure Code Modifier2|7461^Placer Supplemental~7461^Placer Supplemental2|8811^Fillter Supplemental~8811^Fillter Supplemental2|71435^Medically Necessary Duplicate Procedure|N|443331^Parent Universal Service Identifier|||Alt^Placer Order~Alt^Placer Order2|adb4a5cc-50ec-4f1e-95d7-0c1f77cacee1&CSV&11D1111111&CLIA^f34b0f57-1601-4480-ae8a-d4006e50f38d&Other CSV&22D2222222&CLIA2 NTE|1|L|Note about the observation request~second~third~fourth|||20230207|20230208|20230209|CC^Coded Request note From b1c4b88d13023025b5b9bad316a08865b196897e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:44:44 +0000 Subject: [PATCH 04/13] Bump the linting-and-formatting group across 1 directory with 4 updates (#16724) * Bump the linting-and-formatting group across 1 directory with 4 updates Bumps the linting-and-formatting group with 4 updates in the /frontend-react directory: [@eslint/compat](https://github.com/eslint/rewrite), [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js), [eslint](https://github.com/eslint/eslint) and [prettier](https://github.com/prettier/prettier). Updates `@eslint/compat` from 1.2.2 to 1.2.4 - [Release notes](https://github.com/eslint/rewrite/releases) - [Changelog](https://github.com/eslint/rewrite/blob/main/release-please-config.json) - [Commits](https://github.com/eslint/rewrite/compare/compat-v1.2.2...compat-v1.2.4) Updates `@eslint/js` from 9.13.0 to 9.16.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/commits/v9.16.0/packages/js) Updates `eslint` from 9.13.0 to 9.16.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.13.0...v9.16.0) Updates `prettier` from 3.3.3 to 3.4.2 - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.3...3.4.2) --- updated-dependencies: - dependency-name: "@eslint/compat" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: linting-and-formatting - dependency-name: "@eslint/js" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: linting-and-formatting - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor dependency-group: linting-and-formatting - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor dependency-group: linting-and-formatting ... Signed-off-by: dependabot[bot] * format autofix --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joseph Andersen <12385932+jpandersen87@users.noreply.github.com> --- frontend-react/README.md | 30 ++++---- frontend-react/package.json | 8 +- frontend-react/yarn.lock | 148 +++++++++++++++++++----------------- 3 files changed, 99 insertions(+), 87 deletions(-) diff --git a/frontend-react/README.md b/frontend-react/README.md index 1b4ca5897f6..ff940173e9d 100644 --- a/frontend-react/README.md +++ b/frontend-react/README.md @@ -5,8 +5,8 @@ Our new React front-end is easy to get up and running on your machine. First, ensure the following dependencies installed: -- `node` (see .nvmrc for version specification) via `nvm` -- `yarn` package manager +- `node` (see .nvmrc for version specification) via `nvm` +- `yarn` package manager Use the directions here to install nvm: https://github.com/nvm-sh/nvm#install--update-script Then: @@ -276,19 +276,19 @@ These overwrites will ONLY be scoped to your particular component. ### General -- [Best Practices](docs/best-practices.md) -- [Content](docs/content.md) -- [Data fetching patterns](docs/data-fetching-patterns.md) -- [Feature flags](docs/feature-flags.md) -- [RS Auth Element](docs/rs-auth-element.md) -- [RS Error Boundary and Suspense](docs/rs-error-boundary-and-suspense.md) -- [RS IA Content System](docs/rs-ia-content-system.md) -- [RS IA Template System](docs/rs-ia-template-system.md) -- [RS React Testing Network Calls](docs/rs-react-testing-network-calls.md) -- [Test Conventions](docs/test-conventions.md) +- [Best Practices](docs/best-practices.md) +- [Content](docs/content.md) +- [Data fetching patterns](docs/data-fetching-patterns.md) +- [Feature flags](docs/feature-flags.md) +- [RS Auth Element](docs/rs-auth-element.md) +- [RS Error Boundary and Suspense](docs/rs-error-boundary-and-suspense.md) +- [RS IA Content System](docs/rs-ia-content-system.md) +- [RS IA Template System](docs/rs-ia-template-system.md) +- [RS React Testing Network Calls](docs/rs-react-testing-network-calls.md) +- [Test Conventions](docs/test-conventions.md) ### Proposals -- [Permissions Layer](docs/proposals/0001-permissions-layer-proposal.md) -- [Domain Driven Directory Structure](docs/proposals/0002-domain-driven-directory-structure.md) -- [USWDS React Components](docs/proposals/0003-uswds-react-components.md) +- [Permissions Layer](docs/proposals/0001-permissions-layer-proposal.md) +- [Domain Driven Directory Structure](docs/proposals/0002-domain-driven-directory-structure.md) +- [USWDS React Components](docs/proposals/0003-uswds-react-components.md) diff --git a/frontend-react/package.json b/frontend-react/package.json index 56fd2bfc740..ec561e7c947 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -109,8 +109,8 @@ ] }, "devDependencies": { - "@eslint/compat": "^1.2.2", - "@eslint/js": "^9.13.0", + "@eslint/compat": "^1.2.4", + "@eslint/js": "^9.16.0", "@mdx-js/react": "^3.1.0", "@mdx-js/rollup": "^3.1.0", "@playwright/test": "^1.49.0", @@ -154,7 +154,7 @@ "chromatic": "^11.20.0", "cross-env": "^7.0.3", "dotenv-flow": "^4.1.0", - "eslint": "9.13.0", + "eslint": "9.16.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-import": "^2.31.0", @@ -178,7 +178,7 @@ "otpauth": "^9.3.5", "patch-package": "^8.0.0", "postcss": "^8.4.49", - "prettier": "^3.3.3", + "prettier": "^3.4.2", "react-error-boundary": "^4.1.2", "remark-frontmatter": "^5.0.0", "remark-mdx-frontmatter": "^5.0.0", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 05b41cdfdbb..ff370bbd8a0 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -833,46 +833,48 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0": +"@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: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 languageName: node linkType: hard -"@eslint/compat@npm:^1.2.2": - version: 1.2.2 - resolution: "@eslint/compat@npm:1.2.2" +"@eslint/compat@npm:^1.2.4": + version: 1.2.4 + resolution: "@eslint/compat@npm:1.2.4" peerDependencies: eslint: ^9.10.0 peerDependenciesMeta: eslint: optional: true - checksum: 02708de14b32870f44b4fbb78d1bf9e7fb8741a3038bcaea91239a161a0884b676b4c9b5a2346a145d76981710427f5a2d56f65e5bc0579bd288286e88f43ee2 + checksum: d68b0e5d4f2890c86b439cd2e4c0f9c6e7eae09230a69cf80a0b647f7242ed5c662cc286a06d6eb06d95e3def62ed26e9e1eac494538d58b4e2cfc355d37c176 languageName: node linkType: hard -"@eslint/config-array@npm:^0.18.0": - version: 0.18.0 - resolution: "@eslint/config-array@npm:0.18.0" +"@eslint/config-array@npm:^0.19.0": + version: 0.19.1 + resolution: "@eslint/config-array@npm:0.19.1" dependencies: - "@eslint/object-schema": ^2.1.4 + "@eslint/object-schema": ^2.1.5 debug: ^4.3.1 minimatch: ^3.1.2 - checksum: 5ff748e1788745bfb3160c3b3151d62a7c054e336e9fe8069e86cfa6106f3abbd59b24f1253122268295f98c66803e9a7b23d7f947a8c00f62d2060cc44bc7fc + checksum: 421aad712a5ef1a3d118b5e0857f79c080f9dd619a76ce19d20105d381521583786f7abb1195744af9e62a5124e6657066eb6780e920f4001846bd91c1a665f0 languageName: node linkType: hard -"@eslint/core@npm:^0.7.0": - version: 0.7.0 - resolution: "@eslint/core@npm:0.7.0" - checksum: 91d4aa2805f356fb0bba693411deab91590472666e22c9c03304ba03b288b74403a5e120db16d0926ea94281e15563a8d4d519cd1e565d514e2d5015a84b8575 +"@eslint/core@npm:^0.9.0": + version: 0.9.1 + resolution: "@eslint/core@npm:0.9.1" + dependencies: + "@types/json-schema": ^7.0.15 + checksum: 33c8159842cc3a646caa267c008cb567ca60e0220bcdcf6e426128409953b8f6a9b142246db616c71d06331edf769c192d7e2792b3f19c2a6b8179e491512d89 languageName: node linkType: hard -"@eslint/eslintrc@npm:^3.1.0": - version: 3.1.0 - resolution: "@eslint/eslintrc@npm:3.1.0" +"@eslint/eslintrc@npm:^3.2.0": + version: 3.2.0 + resolution: "@eslint/eslintrc@npm:3.2.0" dependencies: ajv: ^6.12.4 debug: ^4.3.2 @@ -883,30 +885,30 @@ __metadata: js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: b0a9bbd98c8b9e0f4d975b042ff9b874dde722b20834ea2ff46551c3de740d4f10f56c449b790ef34d7f82147cbddfc22b004a43cc885dbc2664bb134766b5e4 + checksum: c898e4d12f4c9a79a61ee3c91e38eea5627a04e021cb749191e8537445858bfe32f810eca0cb2dc9902b8ad8b65ca07ef7221dc4bad52afe60cbbf50ec56c236 languageName: node linkType: hard -"@eslint/js@npm:9.13.0, @eslint/js@npm:^9.13.0": - version: 9.13.0 - resolution: "@eslint/js@npm:9.13.0" - checksum: ad5dd72aa75bd8d5bd3c1ffe68cf748aed7edef5fcf97193eb52af35dbb89a1999f526a0e2c169ef5572afbbbbb5f37d6fd0af2991d9ccdc29f753da5cc0f532 +"@eslint/js@npm:9.16.0, @eslint/js@npm:^9.16.0": + version: 9.16.0 + resolution: "@eslint/js@npm:9.16.0" + checksum: ba2d7f7266df827df72cec069df9284ad5e7edb4894a8c58c41db0d489136b22815dc76cd34cf565284979feb4d3a8197b511e08529c03f30c80b5235d25030b languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/object-schema@npm:2.1.4" - checksum: 5a03094115bcdab7991dbbc5d17a9713f394cebb4b44d3eaf990d7487b9b8e1877b817997334ab40be52e299a0384595c6f6ba91b389901e5e1d21efda779271 +"@eslint/object-schema@npm:^2.1.5": + version: 2.1.5 + resolution: "@eslint/object-schema@npm:2.1.5" + checksum: 5facffc832bae93c510f4d38f0f1cbfebd3d7ec772ece6b801bd09bf2dce52e781f4dea500aa133d02257e04ed6a3958fa18cbaed1f9623974a804ee60a8ca54 languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.2.0": - version: 0.2.2 - resolution: "@eslint/plugin-kit@npm:0.2.2" +"@eslint/plugin-kit@npm:^0.2.3": + version: 0.2.4 + resolution: "@eslint/plugin-kit@npm:0.2.4" dependencies: levn: ^0.4.1 - checksum: 08935d81f59f8b2ccc6df1e2517684d6cb9911390e210dacd861be60a000224b0b2f5aa9364ff78e4b14152d1d777aa621f587479aae07d0670b2e14a5a18ef6 + checksum: 5693465dca5fc6f27b090f987b51bc738f48c6a6b5678dcc1791522921834206388b462578edd362d458e8de6dcd21cce1a2e8cff47d1512411ba0389112c231 languageName: node linkType: hard @@ -917,7 +919,7 @@ __metadata: languageName: node linkType: hard -"@humanfs/node@npm:^0.16.5": +"@humanfs/node@npm:^0.16.6": version: 0.16.6 resolution: "@humanfs/node@npm:0.16.6" dependencies: @@ -934,13 +936,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/retry@npm:^0.3.0, @humanwhocodes/retry@npm:^0.3.1": +"@humanwhocodes/retry@npm:^0.3.0": version: 0.3.1 resolution: "@humanwhocodes/retry@npm:0.3.1" checksum: 7e5517bb51dbea3e02ab6cacef59a8f4b0ca023fc4b0b8cbc40de0ad29f46edd50b897c6e7fba79366a0217e3f48e2da8975056f6c35cfe19d9cc48f1d03c1dd languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.4.1": + version: 0.4.1 + resolution: "@humanwhocodes/retry@npm:0.4.1" + checksum: f11167c28e8266faba470fd273cbaafe2827523492bc18c5623015adb7ed66f46b2e542e3d756fed9ca614300249267814220c2f5f03a59e07fdfa64fc14ad52 + languageName: node + linkType: hard + "@inquirer/confirm@npm:^3.0.0": version: 3.0.0 resolution: "@inquirer/confirm@npm:3.0.0" @@ -4609,7 +4618,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -4620,6 +4629,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.5": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + languageName: node + linkType: hard + "css-color-keywords@npm:^1.0.0": version: 1.0.0 resolution: "css-color-keywords@npm:1.0.0" @@ -5814,7 +5834,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^8.1.0": +"eslint-scope@npm:^8.2.0": version: 8.2.0 resolution: "eslint-scope@npm:8.2.0" dependencies: @@ -5831,37 +5851,37 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.1.0, eslint-visitor-keys@npm:^4.2.0": +"eslint-visitor-keys@npm:^4.2.0": version: 4.2.0 resolution: "eslint-visitor-keys@npm:4.2.0" checksum: 779c604672b570bb4da84cef32f6abb085ac78379779c1122d7879eade8bb38ae715645324597cf23232d03cef06032c9844d25c73625bc282a5bfd30247e5b5 languageName: node linkType: hard -"eslint@npm:9.13.0": - version: 9.13.0 - resolution: "eslint@npm:9.13.0" +"eslint@npm:9.16.0": + version: 9.16.0 + resolution: "eslint@npm:9.16.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.11.0 - "@eslint/config-array": ^0.18.0 - "@eslint/core": ^0.7.0 - "@eslint/eslintrc": ^3.1.0 - "@eslint/js": 9.13.0 - "@eslint/plugin-kit": ^0.2.0 - "@humanfs/node": ^0.16.5 + "@eslint-community/regexpp": ^4.12.1 + "@eslint/config-array": ^0.19.0 + "@eslint/core": ^0.9.0 + "@eslint/eslintrc": ^3.2.0 + "@eslint/js": 9.16.0 + "@eslint/plugin-kit": ^0.2.3 + "@humanfs/node": ^0.16.6 "@humanwhocodes/module-importer": ^1.0.1 - "@humanwhocodes/retry": ^0.3.1 + "@humanwhocodes/retry": ^0.4.1 "@types/estree": ^1.0.6 "@types/json-schema": ^7.0.15 ajv: ^6.12.4 chalk: ^4.0.0 - cross-spawn: ^7.0.2 + cross-spawn: ^7.0.5 debug: ^4.3.2 escape-string-regexp: ^4.0.0 - eslint-scope: ^8.1.0 - eslint-visitor-keys: ^4.1.0 - espree: ^10.2.0 + eslint-scope: ^8.2.0 + eslint-visitor-keys: ^4.2.0 + espree: ^10.3.0 esquery: ^1.5.0 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 @@ -5876,7 +5896,6 @@ __metadata: minimatch: ^3.1.2 natural-compare: ^1.4.0 optionator: ^0.9.3 - text-table: ^0.2.0 peerDependencies: jiti: "*" peerDependenciesMeta: @@ -5884,11 +5903,11 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 99e878d6883864b8361bfaf2a2304f1e133347ac19976c79e1430623cd311cb38253bbd122100788082eded947693cce5c7e67dfd2b5173e6f05edb92dcb2206 + checksum: d7b77caed2e319dba9bdf5fd3275c643332e4c79fcfe62cf19031fc430c27fe691daa718474d29a1050b83348085f8df50e04f260e081e5b1fbee1d2ca9c5c74 languageName: node linkType: hard -"espree@npm:^10.0.1, espree@npm:^10.2.0": +"espree@npm:^10.0.1, espree@npm:^10.3.0": version: 10.3.0 resolution: "espree@npm:10.3.0" dependencies: @@ -9694,12 +9713,12 @@ __metadata: languageName: node linkType: hard -"prettier@npm:^3.3.3": - version: 3.3.3 - resolution: "prettier@npm:3.3.3" +"prettier@npm:^3.4.2": + version: 3.4.2 + resolution: "prettier@npm:3.4.2" bin: prettier: bin/prettier.cjs - checksum: bc8604354805acfdde6106852d14b045bb20827ad76a5ffc2455b71a8257f94de93f17f14e463fe844808d2ccc87248364a5691488a3304f1031326e62d9276e + checksum: 061c84513db62d3944c8dc8df36584dad82883ce4e49efcdbedd8703dce5b173c33fd9d2a4e1725d642a3b713c932b55418342eaa347479bc4a9cca114a04cd0 languageName: node linkType: hard @@ -9879,8 +9898,8 @@ __metadata: version: 0.0.0-use.local resolution: "react-frontend@workspace:." dependencies: - "@eslint/compat": ^1.2.2 - "@eslint/js": ^9.13.0 + "@eslint/compat": ^1.2.4 + "@eslint/js": ^9.16.0 "@mdx-js/react": ^3.1.0 "@mdx-js/rollup": ^3.1.0 "@microsoft/applicationinsights-react-js": ^17.3.4 @@ -9938,7 +9957,7 @@ __metadata: date-fns-tz: ^3.2.0 dompurify: ^3.2.2 dotenv-flow: ^4.1.0 - eslint: 9.13.0 + eslint: 9.16.0 eslint-config-prettier: ^9.1.0 eslint-import-resolver-typescript: ^3.6.3 eslint-plugin-import: ^2.31.0 @@ -9968,7 +9987,7 @@ __metadata: p-limit: ^6.1.0 patch-package: ^8.0.0 postcss: ^8.4.49 - prettier: ^3.3.3 + prettier: ^3.4.2 react: ^18.3.1 react-dom: ^18.3.1 react-error-boundary: ^4.1.2 @@ -11432,13 +11451,6 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a - languageName: node - linkType: hard - "tiny-emitter@npm:1.1.0": version: 1.1.0 resolution: "tiny-emitter@npm:1.1.0" From c1a4f42e98c74185fbcf678a3072e706bc263a73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 00:20:25 +0000 Subject: [PATCH 05/13] Bump the bundler group across 1 directory with 3 updates (#16729) * Bump the bundler group across 1 directory with 3 updates Bumps the bundler group with 3 updates in the /frontend-react directory: [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react), [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [vite-plugin-svgr](https://github.com/pd4d10/vite-plugin-svgr). Updates `@vitejs/plugin-react` from 4.3.3 to 4.3.4 - [Release notes](https://github.com/vitejs/vite-plugin-react/releases) - [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.4/packages/plugin-react) Updates `vite` from 5.4.10 to 6.0.3 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.0.3/packages/vite) Updates `vite-plugin-svgr` from 4.2.0 to 4.3.0 - [Release notes](https://github.com/pd4d10/vite-plugin-svgr/releases) - [Commits](https://github.com/pd4d10/vite-plugin-svgr/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: "@vitejs/plugin-react" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: bundler - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-major dependency-group: bundler - dependency-name: vite-plugin-svgr dependency-type: direct:development update-type: version-update:semver-minor dependency-group: bundler ... Signed-off-by: dependabot[bot] * migrate css config for vite 6 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joseph Andersen <12385932+jpandersen87@users.noreply.github.com> --- frontend-react/package.json | 6 +- .../CodeSnippet/CodeSnippet.module.scss | 46 +- .../src/shared/LiveMap/LiveMap.module.scss | 32 +- frontend-react/vite.config.ts | 2 +- frontend-react/yarn.lock | 470 ++++++++++++++++-- 5 files changed, 476 insertions(+), 80 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index ec561e7c947..9a333440f09 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -145,7 +145,7 @@ "@types/react-router-dom": "^5.3.3", "@types/react-scroll-sync": "^0.9.0", "@types/sanitize-html": "^2.13.0", - "@vitejs/plugin-react": "^4.3.3", + "@vitejs/plugin-react": "^4.3.4", "@vitest/coverage-istanbul": "^2.1.8", "@vitest/ui": "^2.1.8", "autoprefixer": "^10.4.20", @@ -191,9 +191,9 @@ "typescript": "^5.7.2", "typescript-eslint": "^8.16.0", "undici": "~6.20.1", - "vite": "^5.4.10", + "vite": "^6.0.3", "vite-plugin-checker": "^0.8.0", - "vite-plugin-svgr": "^4.2.0", + "vite-plugin-svgr": "^4.3.0", "vitest": "^2.1.8" }, "resolutions": { diff --git a/frontend-react/src/shared/CodeSnippet/CodeSnippet.module.scss b/frontend-react/src/shared/CodeSnippet/CodeSnippet.module.scss index 17d7997ebd9..13783cb0232 100644 --- a/frontend-react/src/shared/CodeSnippet/CodeSnippet.module.scss +++ b/frontend-react/src/shared/CodeSnippet/CodeSnippet.module.scss @@ -1,32 +1,32 @@ -@use "src/global-modules" as *; +@use "../../global-modules.scss" as *; .CodeSnippet { - :global { - .code_snippet { - word-wrap: break-word; + :global { + .code_snippet { + word-wrap: break-word; - p { - @include u-margin(0px); - } - } + p { + @include u-margin(0px); + } + } - .text-highlight { - @include u-text("primary-vivid"); - background-color: transparent; - } + .text-highlight { + @include u-text("primary-vivid"); + background-color: transparent; + } - .usa-tooltip { - height: fit-content; - } + .usa-tooltip { + height: fit-content; + } - .usa-tooltip__body { - @include u-font("sans", "md"); - } + .usa-tooltip__body { + @include u-font("sans", "md"); + } - .fixed-tooltip { - color: black; - margin-right: unset; - @include u-margin-left(8px); - } + .fixed-tooltip { + color: black; + margin-right: unset; + @include u-margin-left(8px); } + } } diff --git a/frontend-react/src/shared/LiveMap/LiveMap.module.scss b/frontend-react/src/shared/LiveMap/LiveMap.module.scss index bf9109ea843..54c74fda29c 100644 --- a/frontend-react/src/shared/LiveMap/LiveMap.module.scss +++ b/frontend-react/src/shared/LiveMap/LiveMap.module.scss @@ -1,21 +1,21 @@ -@use "src/global-modules" as *; +@use "../../global-modules.scss" as *; .legend { - list-style: none; + list-style: none; - li { - @include u-float(left); - @include u-margin-right(1); - } + li { + @include u-float(left); + @include u-margin-right(1); + } - span { - @include u-border(0); - @include u-float(left); - @include u-width(2); - @include u-height(2); - @include u-margin-top(0.5); - @include u-margin-right(0.5); - @include u-margin-bottom(2px); - @include u-margin-left(2px); - } + span { + @include u-border(0); + @include u-float(left); + @include u-width(2); + @include u-height(2); + @include u-margin-top(0.5); + @include u-margin-right(0.5); + @include u-margin-bottom(2px); + @include u-margin-left(2px); + } } diff --git a/frontend-react/vite.config.ts b/frontend-react/vite.config.ts index c790d99d27e..0d73b0183bc 100644 --- a/frontend-react/vite.config.ts +++ b/frontend-react/vite.config.ts @@ -147,7 +147,7 @@ export default defineConfig(async ({ mode }) => { css: { preprocessorOptions: { scss: { - includePaths: ["node_modules/@uswds/uswds/packages"], + loadPaths: ["node_modules/@uswds/uswds/packages"], }, }, devSourcemap: true, diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index ff370bbd8a0..53e45e448d3 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -39,6 +39,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0, @babel/code-frame@npm:^7.26.2": + version: 7.26.2 + resolution: "@babel/code-frame@npm:7.26.2" + dependencies: + "@babel/helper-validator-identifier": ^7.25.9 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: db13f5c42d54b76c1480916485e6900748bbcb0014a8aca87f50a091f70ff4e0d0a6db63cade75eb41fcc3d2b6ba0a7f89e343def4f96f00269b41b8ab8dd7b8 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.25.7": version: 7.25.8 resolution: "@babel/compat-data@npm:7.25.8" @@ -46,7 +57,14 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.18.9, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.25.2": +"@babel/compat-data@npm:^7.25.9": + version: 7.26.3 + resolution: "@babel/compat-data@npm:7.26.3" + checksum: 85c5a9fb365231688c7faeb977f1d659da1c039e17b416f8ef11733f7aebe11fe330dce20c1844cacf243766c1d643d011df1d13cac9eda36c46c6c475693d21 + languageName: node + linkType: hard + +"@babel/core@npm:^7.18.9, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9": version: 7.25.8 resolution: "@babel/core@npm:7.25.8" dependencies: @@ -69,6 +87,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/core@npm:7.26.0" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.26.0 + "@babel/generator": ^7.26.0 + "@babel/helper-compilation-targets": ^7.25.9 + "@babel/helper-module-transforms": ^7.26.0 + "@babel/helpers": ^7.26.0 + "@babel/parser": ^7.26.0 + "@babel/template": ^7.25.9 + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.26.0 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: b296084cfd818bed8079526af93b5dfa0ba70282532d2132caf71d4060ab190ba26d3184832a45accd82c3c54016985a4109ab9118674347a7e5e9bc464894e6 + languageName: node + linkType: hard + "@babel/generator@npm:^7.25.7": version: 7.25.7 resolution: "@babel/generator@npm:7.25.7" @@ -81,6 +122,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.26.0, @babel/generator@npm:^7.26.3": + version: 7.26.3 + resolution: "@babel/generator@npm:7.26.3" + dependencies: + "@babel/parser": ^7.26.3 + "@babel/types": ^7.26.3 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^3.0.2 + checksum: fb09fa55c66f272badf71c20a3a2cee0fa1a447fed32d1b84f16a668a42aff3e5f5ddc6ed5d832dda1e952187c002ca1a5cdd827022efe591b6ac44cada884ea + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-compilation-targets@npm:7.25.7" @@ -94,6 +148,19 @@ __metadata: 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" + dependencies: + "@babel/compat-data": ^7.25.9 + "@babel/helper-validator-option": ^7.25.9 + browserslist: ^4.24.0 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: 3af536e2db358b38f968abdf7d512d425d1018fef2f485d6f131a57a7bcaed32c606b4e148bb230e1508fa42b5b2ac281855a68eb78270f54698c48a83201b9b + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-module-imports@npm:7.25.7" @@ -104,6 +171,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-module-imports@npm:7.25.9" + dependencies: + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: 1b411ce4ca825422ef7065dffae7d8acef52023e51ad096351e3e2c05837e9bf9fca2af9ca7f28dc26d596a588863d0fedd40711a88e350b736c619a80e704e6 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helper-module-transforms@npm:7.25.7" @@ -118,10 +195,23 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-plugin-utils@npm:7.25.7" - checksum: eef4450361e597f11247d252e69207324dfe0431df9b8bcecc8bef1204358e93fa7776a659c3c4f439e9ee71cd967aeca6c4d6034ebc17a7ae48143bbb580f2f +"@babel/helper-module-transforms@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/helper-module-transforms@npm:7.26.0" + dependencies: + "@babel/helper-module-imports": ^7.25.9 + "@babel/helper-validator-identifier": ^7.25.9 + "@babel/traverse": ^7.25.9 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 942eee3adf2b387443c247a2c190c17c4fd45ba92a23087abab4c804f40541790d51ad5277e4b5b1ed8d5ba5b62de73857446b7742f835c18ebd350384e63917 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-plugin-utils@npm:7.25.9" + checksum: e19ec8acf0b696756e6d84531f532c5fe508dce57aa68c75572a77798bd04587a844a9a6c8ea7d62d673e21fdc174d091c9097fb29aea1c1b49f9c6eaa80f022 languageName: node linkType: hard @@ -156,6 +246,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-validator-option@npm:7.25.9" + checksum: 9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d + languageName: node + linkType: hard + "@babel/helpers@npm:^7.25.7": version: 7.25.7 resolution: "@babel/helpers@npm:7.25.7" @@ -166,6 +263,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/helpers@npm:7.26.0" + dependencies: + "@babel/template": ^7.25.9 + "@babel/types": ^7.26.0 + checksum: d77fe8d45033d6007eadfa440355c1355eed57902d5a302f450827ad3d530343430a21210584d32eef2f216ae463d4591184c6fc60cf205bbf3a884561469200 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.25.7": version: 7.25.7 resolution: "@babel/highlight@npm:7.25.7" @@ -178,7 +285,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.3": version: 7.26.3 resolution: "@babel/parser@npm:7.26.3" dependencies: @@ -189,25 +296,25 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.24.7": - version: 7.25.7 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.25.7" +"@babel/plugin-transform-react-jsx-self@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/plugin-transform-react-jsx-self@npm:7.25.9" dependencies: - "@babel/helper-plugin-utils": ^7.25.7 + "@babel/helper-plugin-utils": ^7.25.9 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bce354e2871c82087e52eda7eccc5927cce3e961af275ec190ba3060b9eafad497baf8da269217a69e242464d863d95c59d346339e802616fb910862db6763b8 + checksum: 41c833cd7f91b1432710f91b1325706e57979b2e8da44e83d86312c78bbe96cd9ef778b4e79e4e17ab25fa32c72b909f2be7f28e876779ede28e27506c41f4ae languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.24.7": - version: 7.25.7 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.25.7" +"@babel/plugin-transform-react-jsx-source@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/plugin-transform-react-jsx-source@npm:7.25.9" dependencies: - "@babel/helper-plugin-utils": ^7.25.7 + "@babel/helper-plugin-utils": ^7.25.9 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1f87d8fa16ff1d8736224b8775ff5d2c65e562f29c8b272d4f36d427063fdfc83d97dd4250c2568b97f6afb45d2cc7d45f7b96ab0b91fc7c5e9f38154bd10fb7 + checksum: a3e0e5672e344e9d01fb20b504fe29a84918eaa70cec512c4d4b1b035f72803261257343d8e93673365b72c371f35cf34bb0d129720bf178a4c87812c8b9c662 languageName: node linkType: hard @@ -240,6 +347,17 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/template@npm:7.25.9" + dependencies: + "@babel/code-frame": ^7.25.9 + "@babel/parser": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: 103641fea19c7f4e82dc913aa6b6ac157112a96d7c724d513288f538b84bae04fb87b1f1e495ac1736367b1bc30e10f058b30208fb25f66038e1f1eb4e426472 + languageName: node + linkType: hard + "@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.25.7": version: 7.25.7 resolution: "@babel/traverse@npm:7.25.7" @@ -255,7 +373,22 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.26.3": +"@babel/traverse@npm:^7.25.9": + version: 7.26.4 + resolution: "@babel/traverse@npm:7.26.4" + dependencies: + "@babel/code-frame": ^7.26.2 + "@babel/generator": ^7.26.3 + "@babel/parser": ^7.26.3 + "@babel/template": ^7.25.9 + "@babel/types": ^7.26.3 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: dcdf51b27ab640291f968e4477933465c2910bfdcbcff8f5315d1f29b8ff861864f363e84a71fb489f5e9708e8b36b7540608ce019aa5e57ef7a4ba537e62700 + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.3": version: 7.26.3 resolution: "@babel/types@npm:7.26.3" dependencies: @@ -1751,7 +1884,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.0, @rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.0.5": +"@rollup/pluginutils@npm:^5.0.0, @rollup/pluginutils@npm:^5.0.2": version: 5.1.0 resolution: "@rollup/pluginutils@npm:5.1.0" dependencies: @@ -1767,6 +1900,22 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^5.1.3": + version: 5.1.3 + resolution: "@rollup/pluginutils@npm:5.1.3" + dependencies: + "@types/estree": ^1.0.0 + estree-walker: ^2.0.2 + picomatch: ^4.0.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: a6e9bac8ae94da39679dae390b53b43fe7a218f8fa2bfecf86e59be4da4ba02ac004f166daf55f03506e49108399394f13edeb62cce090f8cfc967b29f4738bf + 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" @@ -1774,6 +1923,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.28.0" + 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" @@ -1781,6 +1937,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-android-arm64@npm:4.28.0" + 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" @@ -1788,6 +1951,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-darwin-arm64@npm:4.28.0" + 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" @@ -1795,6 +1965,27 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-darwin-x64@npm:4.28.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.28.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-freebsd-x64@npm:4.28.0" + 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" @@ -1802,6 +1993,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.28.0" + 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" @@ -1809,6 +2007,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.28.0" + 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" @@ -1816,6 +2021,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.28.0" + 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" @@ -1823,6 +2035,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.28.0" + conditions: os=linux & cpu=arm64 & libc=musl + 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" @@ -1830,6 +2049,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.0" + 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" @@ -1837,6 +2063,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.28.0" + 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" @@ -1844,6 +2077,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.28.0" + 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" @@ -1851,6 +2091,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.28.0" + 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" @@ -1858,6 +2105,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.28.0" + 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" @@ -1865,6 +2119,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.28.0" + 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" @@ -1872,6 +2133,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.28.0" + 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" @@ -1879,6 +2147,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.28.0": + version: 4.28.0 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.28.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -3355,18 +3630,18 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-react@npm:^4.3.3": - version: 4.3.3 - resolution: "@vitejs/plugin-react@npm:4.3.3" +"@vitejs/plugin-react@npm:^4.3.4": + version: 4.3.4 + resolution: "@vitejs/plugin-react@npm:4.3.4" dependencies: - "@babel/core": ^7.25.2 - "@babel/plugin-transform-react-jsx-self": ^7.24.7 - "@babel/plugin-transform-react-jsx-source": ^7.24.7 + "@babel/core": ^7.26.0 + "@babel/plugin-transform-react-jsx-self": ^7.25.9 + "@babel/plugin-transform-react-jsx-source": ^7.25.9 "@types/babel__core": ^7.20.5 react-refresh: ^0.14.2 peerDependencies: - vite: ^4.2.0 || ^5.0.0 - checksum: 1ad449cb7934e14ad265a0044aa2461cdb47587c436c2a0324e2b6a73de1b63a34a84396de41b77988fac67ff43302bf0186674344e11a881ba50936cc4297d8 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + checksum: d417f40d9259a1d5193152f7d9fee081d5bf41cbeef9662ae1123ccc1e26aa4b6b04bc82ebb8c4fbfde9516a746fb3af7da19fdd449819c30f0631daaa10a44b languageName: node linkType: hard @@ -5323,7 +5598,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0": +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0, esbuild@npm:^0.24.0": version: 0.24.0 resolution: "esbuild@npm:0.24.0" dependencies: @@ -9943,7 +10218,7 @@ __metadata: "@types/react-scroll-sync": ^0.9.0 "@types/sanitize-html": ^2.13.0 "@uswds/uswds": 3.7.1 - "@vitejs/plugin-react": ^4.3.3 + "@vitejs/plugin-react": ^4.3.4 "@vitest/coverage-istanbul": ^2.1.8 "@vitest/ui": ^2.1.8 autoprefixer: ^10.4.20 @@ -10018,9 +10293,9 @@ __metadata: undici: ~6.20.1 use-deep-compare-effect: ^1.8.1 uuid: ^11.0.3 - vite: ^5.4.10 + vite: ^6.0.3 vite-plugin-checker: ^0.8.0 - vite-plugin-svgr: ^4.2.0 + vite-plugin-svgr: ^4.3.0 vitest: ^2.1.8 web-vitals: ^3.4.0 languageName: unknown @@ -10629,6 +10904,75 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.23.0": + version: 4.28.0 + resolution: "rollup@npm:4.28.0" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.28.0 + "@rollup/rollup-android-arm64": 4.28.0 + "@rollup/rollup-darwin-arm64": 4.28.0 + "@rollup/rollup-darwin-x64": 4.28.0 + "@rollup/rollup-freebsd-arm64": 4.28.0 + "@rollup/rollup-freebsd-x64": 4.28.0 + "@rollup/rollup-linux-arm-gnueabihf": 4.28.0 + "@rollup/rollup-linux-arm-musleabihf": 4.28.0 + "@rollup/rollup-linux-arm64-gnu": 4.28.0 + "@rollup/rollup-linux-arm64-musl": 4.28.0 + "@rollup/rollup-linux-powerpc64le-gnu": 4.28.0 + "@rollup/rollup-linux-riscv64-gnu": 4.28.0 + "@rollup/rollup-linux-s390x-gnu": 4.28.0 + "@rollup/rollup-linux-x64-gnu": 4.28.0 + "@rollup/rollup-linux-x64-musl": 4.28.0 + "@rollup/rollup-win32-arm64-msvc": 4.28.0 + "@rollup/rollup-win32-ia32-msvc": 4.28.0 + "@rollup/rollup-win32-x64-msvc": 4.28.0 + "@types/estree": 1.0.6 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + 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": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 77919b29dd4b54ce5e131aa61f03d8bb7955b332970941914d9c8bd7afd70f8189dc463eb8a357355abcc1bc7add809ec75280d50144817e47cd9e87005bd8ac + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.7.1": version: 0.7.1 resolution: "rrweb-cssom@npm:0.7.1" @@ -12338,20 +12682,20 @@ __metadata: languageName: node linkType: hard -"vite-plugin-svgr@npm:^4.2.0": - version: 4.2.0 - resolution: "vite-plugin-svgr@npm:4.2.0" +"vite-plugin-svgr@npm:^4.3.0": + version: 4.3.0 + resolution: "vite-plugin-svgr@npm:4.3.0" dependencies: - "@rollup/pluginutils": ^5.0.5 + "@rollup/pluginutils": ^5.1.3 "@svgr/core": ^8.1.0 "@svgr/plugin-jsx": ^8.1.0 peerDependencies: - vite: ^2.6.0 || 3 || 4 || 5 - checksum: 8202c0b25c7aa547825c2a73c7ea3702bd13dadb12634a8c2ea4e4c701164d8718632a391deff5fdc53877a09ec3668843b521a3e7ca8083e040e5e4f7e53ecb + vite: ">=2.6.0" + checksum: 9ade316f20dae881f4ee65e4f2a35be11cf75b22a411bfcdb55bd61382c0249395cb925775e06a49e0fdffe483e64d5a25068c3ddfc5823fb72013cf4d932d17 languageName: node linkType: hard -"vite@npm:^5.0.0, vite@npm:^5.4.10": +"vite@npm:^5.0.0": version: 5.4.10 resolution: "vite@npm:5.4.10" dependencies: @@ -12394,6 +12738,58 @@ __metadata: languageName: node linkType: hard +"vite@npm:^6.0.3": + version: 6.0.3 + resolution: "vite@npm:6.0.3" + dependencies: + esbuild: ^0.24.0 + fsevents: ~2.3.3 + postcss: ^8.4.49 + rollup: ^4.23.0 + peerDependencies: + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: ">=1.21.0" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: b6738c1f78dbd58bc4d56cb3aba96d4fabc095c61633bbeff8778fd5ab72c4040eda2609a10d4163553b52b5481ed2f8bb6eba862798ed8b8320d60d5d29a4e6 + languageName: node + linkType: hard + "vitest@npm:^2.1.8": version: 2.1.8 resolution: "vitest@npm:2.1.8" From 9d4321de8e5672e7e491f51d24e9243776341218 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 00:41:50 +0000 Subject: [PATCH 06/13] Bump the router group across 1 directory with 3 updates (#16731) * Bump the router group across 1 directory with 3 updates Bumps the router group with 3 updates in the /frontend-react directory: [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router), [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) and [storybook-addon-remix-react-router](https://github.com/JesusTheHun/storybook-addon-remix-react-router). Updates `react-router` from 6.27.0 to 7.0.2 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router@7.0.2/packages/react-router) Updates `react-router-dom` from 6.27.0 to 7.0.2 - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@7.0.2/packages/react-router-dom) Updates `storybook-addon-remix-react-router` from 3.0.1 to 3.0.2 - [Release notes](https://github.com/JesusTheHun/storybook-addon-remix-react-router/releases) - [Changelog](https://github.com/JesusTheHun/storybook-addon-remix-react-router/blob/main/CHANGELOG.md) - [Commits](https://github.com/JesusTheHun/storybook-addon-remix-react-router/compare/v3.0.1...v3.0.2) --- updated-dependencies: - dependency-name: react-router dependency-type: direct:production update-type: version-update:semver-major dependency-group: router - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-major dependency-group: router - dependency-name: storybook-addon-remix-react-router dependency-type: direct:development update-type: version-update:semver-patch dependency-group: router ... Signed-off-by: dependabot[bot] * pin react-router to pre-7 as it requires react 19 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Joseph Andersen <12385932+jpandersen87@users.noreply.github.com> --- frontend-react/package.json | 6 +- frontend-react/yarn.lock | 422 +++--------------------------------- 2 files changed, 36 insertions(+), 392 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index 9a333440f09..3679e9acc0b 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -32,8 +32,8 @@ "react-loader-spinner": "^6.1.6", "react-markdown": "^9.0.1", "react-query-kit": "^3.3.1", - "react-router": "^6.27.0", - "react-router-dom": "^6.27.0", + "react-router": "~6.28.0", + "react-router-dom": "~6.28.0", "react-scroll-sync": "^0.11.2", "react-toastify": "^10.0.6", "rehype-raw": "^7.0.0", @@ -185,7 +185,7 @@ "remark-mdx-toc": "^0.3.1", "sass": "^1.81.0", "storybook": "^8.4.6", - "storybook-addon-remix-react-router": "^3.0.1", + "storybook-addon-remix-react-router": "^3.0.2", "ts-node": "^10.9.2", "tslib": "^2.8.1", "typescript": "^5.7.2", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 53e45e448d3..00186946763 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -29,17 +29,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/code-frame@npm:7.25.7" - dependencies: - "@babel/highlight": ^7.25.7 - picocolors: ^1.0.0 - checksum: f235cdf9c5d6f172898a27949bd63731c5f201671f77bcf4c2ad97229bc462d89746c1a7f5671a132aecff5baf43f3d878b93a7ecc6aa71f9612d2b51270c53e - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0, @babel/code-frame@npm:^7.26.2": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0, @babel/code-frame@npm:^7.26.2": version: 7.26.2 resolution: "@babel/code-frame@npm:7.26.2" dependencies: @@ -50,13 +40,6 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.25.7": - version: 7.25.8 - resolution: "@babel/compat-data@npm:7.25.8" - checksum: 7ac648b110ec0fcd3a3d3fc62c69c0325b536b3c97bafea8a4392dfc68d9ea9ab1f36d1b2f231d404473fc81f503b4a630425677fc9a3cce2ee33d74842ea109 - languageName: node - linkType: hard - "@babel/compat-data@npm:^7.25.9": version: 7.26.3 resolution: "@babel/compat-data@npm:7.26.3" @@ -64,30 +47,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.18.9, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9": - version: 7.25.8 - resolution: "@babel/core@npm:7.25.8" - dependencies: - "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.25.7 - "@babel/generator": ^7.25.7 - "@babel/helper-compilation-targets": ^7.25.7 - "@babel/helper-module-transforms": ^7.25.7 - "@babel/helpers": ^7.25.7 - "@babel/parser": ^7.25.8 - "@babel/template": ^7.25.7 - "@babel/traverse": ^7.25.7 - "@babel/types": ^7.25.8 - convert-source-map: ^2.0.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.2 - json5: ^2.2.3 - semver: ^6.3.1 - checksum: 77ddf693faf6997915e7bbe16e9f21ca1c0e58bc60ace9eac51c373b21d1b46ce50de650195c136a594b0e5fcb901ca17bb57c2d20bf175b3c325211138bcfde - languageName: node - linkType: hard - -"@babel/core@npm:^7.26.0": +"@babel/core@npm:^7.18.9, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.26.0": version: 7.26.0 resolution: "@babel/core@npm:7.26.0" dependencies: @@ -110,18 +70,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/generator@npm:7.25.7" - dependencies: - "@babel/types": ^7.25.7 - "@jridgewell/gen-mapping": ^0.3.5 - "@jridgewell/trace-mapping": ^0.3.25 - jsesc: ^3.0.2 - checksum: f81cf9dc0191ae4411d82978114382ad6e047bfb678f9a95942bac5034a41719d88f047679f5e2f51ba7728b54ebd1cc32a10df7b556215d8a6ab9bdd4f11831 - languageName: node - linkType: hard - "@babel/generator@npm:^7.26.0, @babel/generator@npm:^7.26.3": version: 7.26.3 resolution: "@babel/generator@npm:7.26.3" @@ -135,19 +83,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-compilation-targets@npm:7.25.7" - dependencies: - "@babel/compat-data": ^7.25.7 - "@babel/helper-validator-option": ^7.25.7 - browserslist: ^4.24.0 - lru-cache: ^5.1.1 - semver: ^6.3.1 - checksum: 5b57e7d4b9302c07510ad3318763c053c3d46f2d40a45c2ea0c59160ccf9061a34975ae62f36a32f15d8d03497ecd5ca43a96417c1fd83eb8c035e77a69840ef - 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" @@ -161,16 +96,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-module-imports@npm:7.25.7" - dependencies: - "@babel/traverse": ^7.25.7 - "@babel/types": ^7.25.7 - checksum: a7255755e9799978de4bf72563b94b53cf955e5fc3d2acc67c783d3b84d5d34dd41691e473ecc124a94654483fff573deacd87eccd8bd16b47ac4455b5941b30 - languageName: node - linkType: hard - "@babel/helper-module-imports@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-module-imports@npm:7.25.9" @@ -181,20 +106,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-module-transforms@npm:7.25.7" - dependencies: - "@babel/helper-module-imports": ^7.25.7 - "@babel/helper-simple-access": ^7.25.7 - "@babel/helper-validator-identifier": ^7.25.7 - "@babel/traverse": ^7.25.7 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: b1daeded78243da969d90b105a564ed918dcded66fba5cd24fe09cb13f7ee9e84d9b9dee789d60237b9a674582d9831a35dbaf6f0a92a3af5f035234a5422814 - languageName: node - linkType: hard - "@babel/helper-module-transforms@npm:^7.26.0": version: 7.26.0 resolution: "@babel/helper-module-transforms@npm:7.26.0" @@ -215,16 +126,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-simple-access@npm:7.25.7" - dependencies: - "@babel/traverse": ^7.25.7 - "@babel/types": ^7.25.7 - checksum: 684d0b0330c42d62834355f127df3ed78f16e6f1f66213c72adb7b3b0bcd6283ea8792f5b172868b3ca6518c479b54e18adac564219519072dda9053cca210bd - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-string-parser@npm:7.25.9" @@ -232,20 +133,13 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.25.7, @babel/helper-validator-identifier@npm:^7.25.9": +"@babel/helper-validator-identifier@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-identifier@npm:7.25.9" checksum: 5b85918cb1a92a7f3f508ea02699e8d2422fe17ea8e82acd445006c0ef7520fbf48e3dbcdaf7b0a1d571fc3a2715a29719e5226636cb6042e15fe6ed2a590944 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helper-validator-option@npm:7.25.7" - checksum: 87b801fe7d8337699f2fba5323243dd974ea214d27cf51faf2f0063da6dc5bb67c9bb7867fd337573870f9ab498d2788a75bcf9685442bd9430611c62b0195d1 - languageName: node - linkType: hard - "@babel/helper-validator-option@npm:^7.25.9": version: 7.25.9 resolution: "@babel/helper-validator-option@npm:7.25.9" @@ -253,16 +147,6 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/helpers@npm:7.25.7" - dependencies: - "@babel/template": ^7.25.7 - "@babel/types": ^7.25.7 - checksum: a73242850915ef2956097431fbab3a840b7d6298555ad4c6f596db7d1b43cf769181716e7b65f8f7015fe48748b9c454d3b9c6cf4506cb840b967654463b0819 - languageName: node - linkType: hard - "@babel/helpers@npm:^7.26.0": version: 7.26.0 resolution: "@babel/helpers@npm:7.26.0" @@ -273,19 +157,7 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/highlight@npm:7.25.7" - dependencies: - "@babel/helper-validator-identifier": ^7.25.7 - chalk: ^2.4.2 - js-tokens: ^4.0.0 - picocolors: ^1.0.0 - checksum: b6aa45c5bf7ecc16b8204bbed90335706131ac6cacb0f1bfb1b862ada3741539c913b56c9d26beb56cece0c231ffab36f66aa36aac6b04b32669c314705203f2 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.3": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.3": version: 7.26.3 resolution: "@babel/parser@npm:7.26.3" dependencies: @@ -336,17 +208,6 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/template@npm:7.25.7" - dependencies: - "@babel/code-frame": ^7.25.7 - "@babel/parser": ^7.25.7 - "@babel/types": ^7.25.7 - checksum: 83f025a4a777103965ee41b7c0fa2bb1c847ea7ed2b9f2cb258998ea96dfc580206176b532edf6d723d85237bc06fca26be5c8772e2af7d9e4fe6927e3bed8a3 - languageName: node - linkType: hard - "@babel/template@npm:^7.25.9": version: 7.25.9 resolution: "@babel/template@npm:7.25.9" @@ -358,22 +219,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.25.7": - version: 7.25.7 - resolution: "@babel/traverse@npm:7.25.7" - dependencies: - "@babel/code-frame": ^7.25.7 - "@babel/generator": ^7.25.7 - "@babel/parser": ^7.25.7 - "@babel/template": ^7.25.7 - "@babel/types": ^7.25.7 - debug: ^4.3.1 - globals: ^11.1.0 - checksum: 4d329b6e7a409a63f4815bbc0a08d0b0cb566c5a2fecd1767661fe1821ced213c554d7d74e6aca048672fed2c8f76071cb0d94f4bd5f120fba8d55a38af63094 - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.25.9": +"@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.25.9": version: 7.26.4 resolution: "@babel/traverse@npm:7.26.4" dependencies: @@ -388,7 +234,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.3": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.3": version: 7.26.3 resolution: "@babel/types@npm:7.26.3" dependencies: @@ -1794,10 +1640,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.20.0": - version: 1.20.0 - resolution: "@remix-run/router@npm:1.20.0" - checksum: 6bff41117eabb867b17c89baa727580f0a431368b309cd9a1f69767aafa68ea9cac95ff0eeb86d37c2c8655f5cd7c6283d37ae5e6d93e94f648c6112ddb24ede +"@remix-run/router@npm:1.21.0": + version: 1.21.0 + resolution: "@remix-run/router@npm:1.21.0" + checksum: d9477a7772053ad0ffcf03385cfb1a54e56f8a56d1f9f5062de3b1dfcbd019dd73282a00a5a72aa55c120771110982448c165c1405d64540aaef13051a8e45cc languageName: node linkType: hard @@ -1884,23 +1730,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^5.0.0, @rollup/pluginutils@npm:^5.0.2": - version: 5.1.0 - resolution: "@rollup/pluginutils@npm:5.1.0" - dependencies: - "@types/estree": ^1.0.0 - estree-walker: ^2.0.2 - picomatch: ^2.3.1 - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - checksum: 3cc5a6d91452a6eabbfd1ae79b4dd1f1e809d2eecda6e175deb784e75b0911f47e9ecce73f8dd315d6a8b3f362582c91d3c0f66908b6ced69345b3cbe28f8ce8 - languageName: node - linkType: hard - -"@rollup/pluginutils@npm:^5.1.3": +"@rollup/pluginutils@npm:^5.0.0, @rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.1.3": version: 5.1.3 resolution: "@rollup/pluginutils@npm:5.1.3" dependencies: @@ -1916,13 +1746,6 @@ __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" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@rollup/rollup-android-arm-eabi@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.28.0" @@ -1930,13 +1753,6 @@ __metadata: 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" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-android-arm64@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-android-arm64@npm:4.28.0" @@ -1944,13 +1760,6 @@ __metadata: 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" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-darwin-arm64@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.28.0" @@ -1958,13 +1767,6 @@ __metadata: 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" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@rollup/rollup-darwin-x64@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-darwin-x64@npm:4.28.0" @@ -1986,13 +1788,6 @@ __metadata: 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" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-arm-gnueabihf@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.28.0" @@ -2000,13 +1795,6 @@ __metadata: 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" - conditions: os=linux & cpu=arm & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-arm-musleabihf@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.28.0" @@ -2014,13 +1802,6 @@ __metadata: 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" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-arm64-gnu@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.28.0" @@ -2028,13 +1809,6 @@ __metadata: 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" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-arm64-musl@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.28.0" @@ -2042,13 +1816,6 @@ __metadata: 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" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.28.0" @@ -2056,13 +1823,6 @@ __metadata: 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" - conditions: os=linux & cpu=riscv64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-riscv64-gnu@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.28.0" @@ -2070,13 +1830,6 @@ __metadata: 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" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-s390x-gnu@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.28.0" @@ -2084,13 +1837,6 @@ __metadata: 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" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - "@rollup/rollup-linux-x64-gnu@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.28.0" @@ -2098,13 +1844,6 @@ __metadata: 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" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - "@rollup/rollup-linux-x64-musl@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.28.0" @@ -2112,13 +1851,6 @@ __metadata: 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" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@rollup/rollup-win32-arm64-msvc@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.28.0" @@ -2126,13 +1858,6 @@ __metadata: 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" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@rollup/rollup-win32-ia32-msvc@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.28.0" @@ -2140,13 +1865,6 @@ __metadata: 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" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@rollup/rollup-win32-x64-msvc@npm:4.28.0": version: 4.28.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.28.0" @@ -4475,7 +4193,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.1, chalk@npm:^2.4.2": +"chalk@npm:^2.4.1": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -4893,18 +4611,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" - dependencies: - path-key: ^3.1.0 - shebang-command: ^2.0.0 - which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.5": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -10271,8 +9978,8 @@ __metadata: react-loader-spinner: ^6.1.6 react-markdown: ^9.0.1 react-query-kit: ^3.3.1 - react-router: ^6.27.0 - react-router-dom: ^6.27.0 + react-router: ~6.28.0 + react-router-dom: ~6.28.0 react-scroll-sync: ^0.11.2 react-toastify: ^10.0.6 rehype-raw: ^7.0.0 @@ -10284,7 +9991,7 @@ __metadata: sanitize-html: ^2.13.1 sass: ^1.81.0 storybook: ^8.4.6 - storybook-addon-remix-react-router: ^3.0.1 + storybook-addon-remix-react-router: ^3.0.2 ts-node: ^10.9.2 tslib: ^2.8.1 tsx: ^4.19.2 @@ -10405,27 +10112,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.27.0": - version: 6.27.0 - resolution: "react-router-dom@npm:6.27.0" +"react-router-dom@npm:~6.28.0": + version: 6.28.0 + resolution: "react-router-dom@npm:6.28.0" dependencies: - "@remix-run/router": 1.20.0 - react-router: 6.27.0 + "@remix-run/router": 1.21.0 + react-router: 6.28.0 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: de3dcc56297a2879a0e3997fa34ba0f3e1b9986a2ad3ef7991f913902ecf38da0282c98f7834f344ce2d881dbab0a382201a57e9f9ef5e9816febdb26dc038b7 + checksum: 0cf4658a92bc66f50ec9d8518c36aa5a402bcadce71fb624ed6f900d73a29ea87ff904a4f2c42279107e75e80cc08c6192563fadcc5d4e642e6d476e38e83b21 languageName: node linkType: hard -"react-router@npm:6.27.0, react-router@npm:^6.27.0": - version: 6.27.0 - resolution: "react-router@npm:6.27.0" +"react-router@npm:6.28.0, react-router@npm:~6.28.0": + version: 6.28.0 + resolution: "react-router@npm:6.28.0" dependencies: - "@remix-run/router": 1.20.0 + "@remix-run/router": 1.21.0 peerDependencies: react: ">=16.8" - checksum: d22eedc33bcb11891b431655f90eed2d52c2fb3165ad11ca625f62970caf59c4859e6b1a3f92e78902b31ff1a8b2482ebf97ddebb82e9687d1f98730c14e04e6 + checksum: 23246ca957b5c2bc8d6f9a81fee2df2ce4fc3feca3ec27c2fd85999568fc1299a4e8273e4ab70b6f3acd43a1fb45e0c93cb01ef77e68c9f9e1f7e4f42a1419ea languageName: node linkType: hard @@ -10841,70 +10548,7 @@ __metadata: 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": 4.24.0 - "@rollup/rollup-android-arm64": 4.24.0 - "@rollup/rollup-darwin-arm64": 4.24.0 - "@rollup/rollup-darwin-x64": 4.24.0 - "@rollup/rollup-linux-arm-gnueabihf": 4.24.0 - "@rollup/rollup-linux-arm-musleabihf": 4.24.0 - "@rollup/rollup-linux-arm64-gnu": 4.24.0 - "@rollup/rollup-linux-arm64-musl": 4.24.0 - "@rollup/rollup-linux-powerpc64le-gnu": 4.24.0 - "@rollup/rollup-linux-riscv64-gnu": 4.24.0 - "@rollup/rollup-linux-s390x-gnu": 4.24.0 - "@rollup/rollup-linux-x64-gnu": 4.24.0 - "@rollup/rollup-linux-x64-musl": 4.24.0 - "@rollup/rollup-win32-arm64-msvc": 4.24.0 - "@rollup/rollup-win32-ia32-msvc": 4.24.0 - "@rollup/rollup-win32-x64-msvc": 4.24.0 - "@types/estree": 1.0.6 - fsevents: ~2.3.2 - dependenciesMeta: - "@rollup/rollup-android-arm-eabi": - optional: true - "@rollup/rollup-android-arm64": - optional: true - "@rollup/rollup-darwin-arm64": - optional: true - "@rollup/rollup-darwin-x64": - optional: true - "@rollup/rollup-linux-arm-gnueabihf": - optional: true - "@rollup/rollup-linux-arm-musleabihf": - optional: true - "@rollup/rollup-linux-arm64-gnu": - optional: true - "@rollup/rollup-linux-arm64-musl": - optional: true - "@rollup/rollup-linux-powerpc64le-gnu": - optional: true - "@rollup/rollup-linux-riscv64-gnu": - optional: true - "@rollup/rollup-linux-s390x-gnu": - optional: true - "@rollup/rollup-linux-x64-gnu": - optional: true - "@rollup/rollup-linux-x64-musl": - optional: true - "@rollup/rollup-win32-arm64-msvc": - optional: true - "@rollup/rollup-win32-ia32-msvc": - optional: true - "@rollup/rollup-win32-x64-msvc": - optional: true - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: b7e915b0cc43749c2c71255ff58858496460b1a75148db2abecc8e9496af83f488517768593826715f610e20e480a5ae7f1132a1408eb1d364830d6b239325cf - languageName: node - linkType: hard - -"rollup@npm:^4.23.0": +"rollup@npm:^4.20.0, rollup@npm:^4.23.0": version: 4.28.0 resolution: "rollup@npm:4.28.0" dependencies: @@ -11428,9 +11072,9 @@ __metadata: languageName: node linkType: hard -"storybook-addon-remix-react-router@npm:^3.0.1": - version: 3.0.1 - resolution: "storybook-addon-remix-react-router@npm:3.0.1" +"storybook-addon-remix-react-router@npm:^3.0.2": + version: 3.0.2 + resolution: "storybook-addon-remix-react-router@npm:3.0.2" dependencies: compare-versions: ^6.0.0 react-inspector: 6.0.2 @@ -11444,13 +11088,13 @@ __metadata: "@storybook/theming": ^8.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-router-dom: ^6.4.0 + react-router-dom: ^6.4.0 || ^7.0.0 peerDependenciesMeta: react: optional: true react-dom: optional: true - checksum: 29948e53fa1eda1c0cf5aa3e679c5d135578abb468e5d3969cd6eb9a7e24546dde6720d437692c5bdbf2c2c16f5553260933e4b8945da967313b447974d093fe + checksum: 725ca79a1050a2141a0bb60e5c25f405a39f6a90be31d7ccecb08a1edda1bd9afa4f4829e71217461a0084aaab8db333ca9f4a1a1169de3ef0d161fdedc170ab languageName: node linkType: hard From fd1ce288cb0056decf21ba32ebe902cab633cf80 Mon Sep 17 00:00:00 2001 From: "Eduardo Valdes Jr." <1084551+emvaldes@users.noreply.github.com> Date: Fri, 6 Dec 2024 09:31:19 -0700 Subject: [PATCH 07/13] Integrating the checksum-validate GitHub Action into project (#16728) * Integrating the checksum-validate-action GitHub Action into project * Correcting all external references to the checksum-validate-action GitHub Action --------- Co-authored-by: Eduardo Valdes --- .github/actions/checksum-validate/README.md | 94 ++++++++++++++++ .github/actions/checksum-validate/action.yml | 111 +++++++++++++++++++ .github/actions/deploy-backend/action.yml | 5 +- .github/dependabot.yml | 5 + .github/workflows/release_to_azure.yml | 5 +- 5 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 .github/actions/checksum-validate/README.md create mode 100644 .github/actions/checksum-validate/action.yml diff --git a/.github/actions/checksum-validate/README.md b/.github/actions/checksum-validate/README.md new file mode 100644 index 00000000000..b228bfcab77 --- /dev/null +++ b/.github/actions/checksum-validate/README.md @@ -0,0 +1,94 @@ +# Checksum Validate Action + +[![Test Action](https://github.com/JosiahSiegel/checksum-validate-action/actions/workflows/test_action.yml/badge.svg)](https://github.com/JosiahSiegel/checksum-validate-action/actions/workflows/test_action.yml) + +## Synopsis + +1. Generate a checksum from either a string or shell command (use command substitution: `$()`). +2. Validate if checksum is identical to input (even across multiple jobs), using a `key` to link the validation attempt with the correct generated checksum. + * Validation is possible across jobs since the checksum is uploaded as a workflow artifact + +## Usage + +```yml +jobs: + generate-checksums: + name: Generate checksum + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + + - name: Generate checksum of string + uses: ./.github/actions/checksum-validate@ebdf8c12c00912d18de93c483b935d51582f9236 + with: + key: test string + input: hello world + + - name: Generate checksum of command output + uses: ./.github/actions/checksum-validate@ebdf8c12c00912d18de93c483b935d51582f9236 + with: + key: test command + input: $(cat action.yml) + + validate-checksums: + name: Validate checksum + needs: + - generate-checksums + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.1.1 + + - name: Validate checksum of valid string + id: valid-string + uses: ./.github/actions/checksum-validate@ebdf8c12c00912d18de93c483b935d51582f9236 + with: + key: test string + validate: true + fail-invalid: true + input: hello world + + - name: Validate checksum of valid command output + id: valid-command + uses: ./.github/actions/checksum-validate@ebdf8c12c00912d18de93c483b935d51582f9236 + with: + key: test command + validate: true + fail-invalid: true + input: $(cat action.yml) + + - name: Get outputs + run: | + echo ${{ steps.valid-string.outputs.valid }} + echo ${{ steps.valid-command.outputs.valid }} +``` + +## Workflow summary + +### ✅ test string checksum valid ✅ + +### ❌ test string checksum INVALID ❌ + +## Inputs + +```yml +inputs: + validate: + description: Check if checksums match + default: false + key: + description: String to keep unique checksums separate + required: true + fail-invalid: + description: Fail step if invalid checksum + default: false + input: + description: String or command for checksum + required: true +``` + +## Outputs +```yml +outputs: + valid: + description: True if checksums match +``` diff --git a/.github/actions/checksum-validate/action.yml b/.github/actions/checksum-validate/action.yml new file mode 100644 index 00000000000..1ad3023476e --- /dev/null +++ b/.github/actions/checksum-validate/action.yml @@ -0,0 +1,111 @@ +# action.yml +name: Checksum Validate Action +description: Generate and validate checksums +branding: + icon: 'lock' + color: 'orange' +inputs: + validate: + description: Check if checksums match + default: false + key: + description: String to keep unique checksums separate + required: true + fail-invalid: + description: Fail step if invalid checksum + default: false + input: + description: String or command for checksum + required: true +outputs: + valid: + description: True if checksums match + value: ${{ steps.validate_checksum.outputs.valid }} + +runs: + using: "composite" + steps: + + # CHECKSUM START + - name: Generate SHA + uses: nick-fields/retry@v3.0.0 + with: + max_attempts: 5 + retry_on: any + timeout_seconds: 10 + retry_wait_seconds: 15 + command: | + function fail { + printf '%s\n' "$1" >&2 + exit "${2-1}" + } + input_cmd="${{ inputs.input }}" || fail + sha="$(echo "$input_cmd" | sha256sum)" + echo "sha=$sha" >> $GITHUB_ENV + echo "success=true" >> $GITHUB_ENV + + - name: Get input SHA + if: env.success + id: input_sha + shell: bash + run: echo "sha=${{ env.sha }}" >> $GITHUB_OUTPUT + + - name: Get input SHA + if: env.success != 'true' + shell: bash + run: | + echo "failed to generate sha" + exit 1 + # CHECKSUM END + + # UPLOAD FILE START + - name: Create checksum file + if: inputs.validate != 'true' + shell: bash + run: | + echo "${{ steps.input_sha.outputs.sha }}" > "${{ github.sha }}-${{ inputs.key }}.txt" + + - name: Upload checksum file + if: inputs.validate != 'true' + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 + with: + name: "${{ github.sha }}-${{ inputs.key }}.txt" + path: "${{ github.sha }}-${{ inputs.key }}.txt" + retention-days: 5 + # UPLOAD FILE END + + # VALIDATE FILE START + - name: Download checksum file + if: inputs.validate == 'true' + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe + with: + name: "${{ github.sha }}-${{ inputs.key }}.txt" + + - name: Validate pre and post checksums + if: inputs.validate == 'true' + id: validate_checksum + shell: bash + run: | + echo "${{ steps.input_sha.outputs.sha }}" > "${{ github.sha }}-${{ inputs.key }}-2.txt" + DIFF=$(diff -q "${{ github.sha }}-${{ inputs.key }}-2.txt" "${{ github.sha }}-${{ inputs.key }}.txt") || true + codevalid=true + if [ "$DIFF" != "" ] + then + codevalid=false + fi + echo "valid=$codevalid" >> $GITHUB_OUTPUT + + - name: Create summary + if: inputs.validate == 'true' + run: | + # Use ternary operator to assign emoji based on validity + emoji=${{ steps.validate_checksum.outputs.valid == 'true' && '✅' || '❌' }} + valid=${{ steps.validate_checksum.outputs.valid == 'true' && 'valid' || 'INVALID' }} + echo "### $emoji ${{ inputs.key }} checksum $valid $emoji" >> $GITHUB_STEP_SUMMARY + shell: bash + # VALIDATE FILE END + + - name: Fail if invalid checksum + if: inputs.validate == 'true' && steps.validate_checksum.outputs.valid == 'false' && inputs.fail-invalid == 'true' + run: exit 1 + shell: bash diff --git a/.github/actions/deploy-backend/action.yml b/.github/actions/deploy-backend/action.yml index 60c558eae6d..1d9beecaa4f 100644 --- a/.github/actions/deploy-backend/action.yml +++ b/.github/actions/deploy-backend/action.yml @@ -332,10 +332,7 @@ runs: - name: Validate function app checksum if: inputs.checksum-validation == 'true' - - uses: JosiahSiegel/checksum-validate-action@ebdf8c12c00912d18de93c483b935d51582f9236 - ## DevSecOps - Aquia (Replace) uses: ./.github/actions/checksum-validate-action - + uses: ./.github/actions/checksum-validate with: key: backend validate: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 498f787b167..6365ac26954 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -125,6 +125,11 @@ updates: schedule: interval: "daily" + - package-ecosystem: "github-actions" + directory: "/.github/actions/checksum-validate" + schedule: + interval: "daily" + # Frontend - package-ecosystem: "npm" directory: "/frontend-react" diff --git a/.github/workflows/release_to_azure.yml b/.github/workflows/release_to_azure.yml index 481834e4db4..6e01c192131 100644 --- a/.github/workflows/release_to_azure.yml +++ b/.github/workflows/release_to_azure.yml @@ -147,10 +147,7 @@ jobs: env: checksum_validation: ${{ vars.CHECKSUM_VALIDATION }} if: needs.pre_job.outputs.has_router_change == 'true' && env.checksum_validation == 'true' - - uses: JosiahSiegel/checksum-validate-action@ebdf8c12c00912d18de93c483b935d51582f9236 - ## DevSecOps - Aquia (Replace) - uses: ./.github/actions/checksum-validate-action - + uses: ./.github/actions/checksum-validate with: key: backend input: $(az functionapp config appsettings list -g prime-data-hub-${{ needs.pre_job.outputs.env_name }} -n pdh${{ needs.pre_job.outputs.env_name }}-functionapp -o tsv | sort) From ae05caed7ca0d999b1f9d94b1720d54057bd332f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:02:06 -0600 Subject: [PATCH 08/13] Bump eslint-plugin-testing-library in /frontend-react (#16754) Bumps [eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library) from 6.4.0 to 7.1.1. - [Release notes](https://github.com/testing-library/eslint-plugin-testing-library/releases) - [Changelog](https://github.com/testing-library/eslint-plugin-testing-library/blob/main/.releaserc.json) - [Commits](https://github.com/testing-library/eslint-plugin-testing-library/compare/v6.4.0...v7.1.1) --- updated-dependencies: - dependency-name: eslint-plugin-testing-library dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 2 +- frontend-react/yarn.lock | 173 ++++++++++++++---------------------- 2 files changed, 67 insertions(+), 108 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index 3679e9acc0b..65a44cce86b 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -165,7 +165,7 @@ "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", "eslint-plugin-storybook": "^0.11.1", - "eslint-plugin-testing-library": "^6.4.0", + "eslint-plugin-testing-library": "^7.1.1", "eslint-plugin-vitest": "^0.5.4", "globals": "^15.13.0", "husky": "^9.1.6", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 00186946763..d10903dd89a 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -2851,7 +2851,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -3008,13 +3008,6 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12": - version: 7.5.8 - resolution: "@types/semver@npm:7.5.8" - checksum: ea6f5276f5b84c55921785a3a27a3cd37afee0111dfe2bcb3e03c31819c197c782598f17f0b150a69d453c9584cd14c4c4d7b9a55d2c5e6cacd4d66fdb3b3663 - languageName: node - linkType: hard - "@types/sizzle@npm:*": version: 2.3.3 resolution: "@types/sizzle@npm:2.3.3" @@ -3126,16 +3119,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" - dependencies: - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/visitor-keys": 5.62.0 - checksum: 6062d6b797fe1ce4d275bb0d17204c827494af59b5eaf09d8a78cdd39dadddb31074dded4297aaf5d0f839016d601032857698b0e4516c86a41207de606e9573 - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/scope-manager@npm:7.18.0" @@ -3156,6 +3139,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.17.0, @typescript-eslint/scope-manager@npm:^8.15.0": + version: 8.17.0 + resolution: "@typescript-eslint/scope-manager@npm:8.17.0" + dependencies: + "@typescript-eslint/types": 8.17.0 + "@typescript-eslint/visitor-keys": 8.17.0 + checksum: c5f628e5b4793181a219fc8be4dc2653b2a2a158c4add645b3ba063b9618f5892e5bbf6726c9e674731e698a3df4f2ddb671494482e0f59b6625c43810f78eeb + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:8.16.0": version: 8.16.0 resolution: "@typescript-eslint/type-utils@npm:8.16.0" @@ -3173,13 +3166,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 48c87117383d1864766486f24de34086155532b070f6264e09d0e6139449270f8a9559cfef3c56d16e3bcfb52d83d42105d61b36743626399c7c2b5e0ac3b670 - languageName: node - linkType: hard - "@typescript-eslint/types@npm:7.18.0": version: 7.18.0 resolution: "@typescript-eslint/types@npm:7.18.0" @@ -3194,21 +3180,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" - dependencies: - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/visitor-keys": 5.62.0 - debug: ^4.3.4 - globby: ^11.1.0 - is-glob: ^4.0.3 - semver: ^7.3.7 - tsutils: ^3.21.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 3624520abb5807ed8f57b1197e61c7b1ed770c56dfcaca66372d584ff50175225798bccb701f7ef129d62c5989070e1ee3a0aa2d84e56d9524dcf011a2bb1a52 +"@typescript-eslint/types@npm:8.17.0": + version: 8.17.0 + resolution: "@typescript-eslint/types@npm:8.17.0" + checksum: 5f6933903ce4af536f180c9e326c18da715f6f400e6bc5b89828dcb5779ae5693bf95c59d253e105c9efe6ffd2046d0db868bcfb1c5288c5e194bae4ebaa9976 languageName: node linkType: hard @@ -3250,6 +3225,25 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.17.0": + version: 8.17.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.17.0" + dependencies: + "@typescript-eslint/types": 8.17.0 + "@typescript-eslint/visitor-keys": 8.17.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 + is-glob: ^4.0.3 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^1.3.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 35d3dca3cde7a1f3a7a1e4e5a25a69b6151338cd329dceeb52880e6f05048d10c9ac472a07e558fdfb7acc10dd60cd106284e834cfe40ced3d2c4527e8727335 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:8.16.0, @typescript-eslint/utils@npm:^8.8.1": version: 8.16.0 resolution: "@typescript-eslint/utils@npm:8.16.0" @@ -3267,24 +3261,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" - dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@types/json-schema": ^7.0.9 - "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.62.0 - "@typescript-eslint/types": 5.62.0 - "@typescript-eslint/typescript-estree": 5.62.0 - eslint-scope: ^5.1.1 - semver: ^7.3.7 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: ee9398c8c5db6d1da09463ca7bf36ed134361e20131ea354b2da16a5fdb6df9ba70c62a388d19f6eebb421af1786dbbd79ba95ddd6ab287324fc171c3e28d931 - languageName: node - linkType: hard - "@typescript-eslint/utils@npm:^7.7.1": version: 7.18.0 resolution: "@typescript-eslint/utils@npm:7.18.0" @@ -3299,13 +3275,20 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" +"@typescript-eslint/utils@npm:^8.15.0": + version: 8.17.0 + resolution: "@typescript-eslint/utils@npm:8.17.0" dependencies: - "@typescript-eslint/types": 5.62.0 - eslint-visitor-keys: ^3.3.0 - checksum: 976b05d103fe8335bef5c93ad3f76d781e3ce50329c0243ee0f00c0fcfb186c81df50e64bfdd34970148113f8ade90887f53e3c4938183afba830b4ba8e30a35 + "@eslint-community/eslint-utils": ^4.4.0 + "@typescript-eslint/scope-manager": 8.17.0 + "@typescript-eslint/types": 8.17.0 + "@typescript-eslint/typescript-estree": 8.17.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 67d8e390eb661e96b7782e6a900f7eb5825baae0b09e89e67159a576b157db4fd83f78887bbbb1778cd4097e0022f3ea2a9be12aab215320d47f13c03e1558d7 languageName: node linkType: hard @@ -3329,6 +3312,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.17.0": + version: 8.17.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.17.0" + dependencies: + "@typescript-eslint/types": 8.17.0 + eslint-visitor-keys: ^4.2.0 + checksum: f92f659ec88a1ce34f5003722a133ced1ebf9b3dfc1c0ff18caa5362d4722307edb42fa606ebf80aada8525abe78b24143ef93864d38a1e359605096f1fe2f00 + languageName: node + linkType: hard + "@ungap/structured-clone@npm:^1.0.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" @@ -5778,14 +5771,15 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-testing-library@npm:^6.4.0": - version: 6.4.0 - resolution: "eslint-plugin-testing-library@npm:6.4.0" +"eslint-plugin-testing-library@npm:^7.1.1": + version: 7.1.1 + resolution: "eslint-plugin-testing-library@npm:7.1.1" dependencies: - "@typescript-eslint/utils": ^5.62.0 + "@typescript-eslint/scope-manager": ^8.15.0 + "@typescript-eslint/utils": ^8.15.0 peerDependencies: - eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 - checksum: cfaaf0582375efb15821d3bcc2d571ffcb7d23c4f66677b9fc921cf853ec0b2a38bae9e31b566db2c55952444ad8064ef2996ca82a3312bc7e2d79537be56b19 + eslint: ^8.57.0 || ^9.0.0 + checksum: d9adc8ebff79e311eda8b800336b01d95f12d185ad327add83486906b5de555b6932fef793ea8423fbb268774a43fca7876dc1308b69cd1765e6c6bcffd3351d languageName: node linkType: hard @@ -5806,16 +5800,6 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" - dependencies: - esrecurse: ^4.3.0 - estraverse: ^4.1.1 - checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb - languageName: node - linkType: hard - "eslint-scope@npm:^8.2.0": version: 8.2.0 resolution: "eslint-scope@npm:8.2.0" @@ -5928,13 +5912,6 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.1.1": - version: 4.3.0 - resolution: "estraverse@npm:4.3.0" - checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 - languageName: node - linkType: hard - "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -9950,7 +9927,7 @@ __metadata: eslint-plugin-react-hooks: ^5.0.0 eslint-plugin-react-refresh: ^0.4.14 eslint-plugin-storybook: ^0.11.1 - eslint-plugin-testing-library: ^6.4.0 + eslint-plugin-testing-library: ^7.1.1 eslint-plugin-vitest: ^0.5.4 export-to-csv-fix-source-map: ^0.2.1 focus-trap-react: ^10.3.0 @@ -10760,7 +10737,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3": +"semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3": version: 7.6.3 resolution: "semver@npm:7.6.3" bin: @@ -11690,13 +11667,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1": - version: 1.14.1 - resolution: "tslib@npm:1.14.1" - checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd - languageName: node - linkType: hard - "tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -11704,17 +11674,6 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: ^1.8.1 - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 1843f4c1b2e0f975e08c4c21caa4af4f7f65a12ac1b81b3b8489366826259323feb3fc7a243123453d2d1a02314205a7634e048d4a8009921da19f99755cdc48 - languageName: node - linkType: hard - "tsx@npm:^4.19.2": version: 4.19.2 resolution: "tsx@npm:4.19.2" From baa0958940c34a12dcfa766326cf76b1efa96268 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:14:08 +0000 Subject: [PATCH 09/13] Bump the mocking group across 1 directory with 2 updates (#16740) Bumps the mocking group with 2 updates in the /frontend-react directory: [msw](https://github.com/mswjs/msw) and [msw-storybook-addon](https://github.com/mswjs/msw-storybook-addon/tree/HEAD/packages/msw-addon). Updates `msw` from 2.4.11 to 2.6.7 - [Release notes](https://github.com/mswjs/msw/releases) - [Changelog](https://github.com/mswjs/msw/blob/main/CHANGELOG.md) - [Commits](https://github.com/mswjs/msw/compare/v2.4.11...v2.6.7) Updates `msw-storybook-addon` from 2.0.3 to 2.0.4 - [Release notes](https://github.com/mswjs/msw-storybook-addon/releases) - [Changelog](https://github.com/mswjs/msw-storybook-addon/blob/main/packages/msw-addon/CHANGELOG.md) - [Commits](https://github.com/mswjs/msw-storybook-addon/commits/v2.0.4/packages/msw-addon) --- updated-dependencies: - dependency-name: msw dependency-type: direct:development update-type: version-update:semver-minor dependency-group: mocking - dependency-name: msw-storybook-addon dependency-type: direct:development update-type: version-update:semver-patch dependency-group: mocking ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 4 +- frontend-react/yarn.lock | 169 ++++++++++++++---------------------- 2 files changed, 66 insertions(+), 107 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index 65a44cce86b..3873bd8d2f0 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -172,8 +172,8 @@ "jsdom": "^25.0.1", "lint-staged": "^15.2.10", "mockdate": "^3.0.5", - "msw": "^2.4.11", - "msw-storybook-addon": "^2.0.3", + "msw": "^2.6.7", + "msw-storybook-addon": "^2.0.4", "npm-run-all": "^4.1.5", "otpauth": "^9.3.5", "patch-package": "^8.0.0", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index d10903dd89a..54374c73b4f 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -244,12 +244,12 @@ __metadata: languageName: node linkType: hard -"@bundled-es-modules/cookie@npm:^2.0.0": - version: 2.0.0 - resolution: "@bundled-es-modules/cookie@npm:2.0.0" +"@bundled-es-modules/cookie@npm:^2.0.1": + version: 2.0.1 + resolution: "@bundled-es-modules/cookie@npm:2.0.1" dependencies: - cookie: ^0.5.0 - checksum: 53114eabbedda20ba6c63f45dcea35c568616d22adf5d1882cef9761f65ae636bf47e0c66325572cc8e3a335e0257caf5f76ff1287990d9e9265be7bc9767a87 + cookie: ^0.7.2 + checksum: 4f210f9316a612f03a46c58f0e3de14b2598f36905433b5ac91e305a4185bd3cb0b141622fa54cff2fce18adbac0b5a8df67dca1874aabd81b7a631fc826e116 languageName: node linkType: hard @@ -929,42 +929,48 @@ __metadata: languageName: node linkType: hard -"@inquirer/confirm@npm:^3.0.0": - version: 3.0.0 - resolution: "@inquirer/confirm@npm:3.0.0" +"@inquirer/confirm@npm:^5.0.0": + version: 5.0.2 + resolution: "@inquirer/confirm@npm:5.0.2" dependencies: - "@inquirer/core": ^7.0.0 - "@inquirer/type": ^1.2.0 - checksum: ed16dc0e5b22115474853ca57dbe3dacdcd15bcb37cc50020e8e76ff8d0875d62d8b63b93b3092c653faeb6c83a139eac997ff05638b0f1f78ae919f29ee29d4 + "@inquirer/core": ^10.1.0 + "@inquirer/type": ^3.0.1 + peerDependencies: + "@types/node": ">=18" + checksum: 4e775b80b689adeb0b2852ed79b368ef23a82fe3d5f580a562f4af7cdf002a19e0ec1b3b95acc6d49427a72c0fcb5b6548e0cdcafe2f0d3f3d6a923e04aabd0c languageName: node linkType: hard -"@inquirer/core@npm:^7.0.0": - version: 7.0.0 - resolution: "@inquirer/core@npm:7.0.0" +"@inquirer/core@npm:^10.1.0": + version: 10.1.0 + resolution: "@inquirer/core@npm:10.1.0" dependencies: - "@inquirer/type": ^1.2.0 - "@types/mute-stream": ^0.0.4 - "@types/node": ^20.11.16 - "@types/wrap-ansi": ^3.0.0 + "@inquirer/figures": ^1.0.8 + "@inquirer/type": ^3.0.1 ansi-escapes: ^4.3.2 - chalk: ^4.1.2 - cli-spinners: ^2.9.2 cli-width: ^4.1.0 - figures: ^3.2.0 - mute-stream: ^1.0.0 - run-async: ^3.0.0 + mute-stream: ^2.0.0 signal-exit: ^4.1.0 strip-ansi: ^6.0.1 wrap-ansi: ^6.2.0 - checksum: 9496406e24fa68f877b4715ad0c1b8465e558bf0e669dac6a2bb55e97c4d044edd99a864cb7bf1e7db8409f8057b33edd1fe154009f85aea8a7f739837d748c9 + yoctocolors-cjs: ^2.1.2 + checksum: c52be9ef04497a2b82ed6b1258ebd24ad0950b4b83a96e6fbde1a801eeced4e4b32ed5b2217eac98e504cc1d16ddc8d9d39243c96bdb5390ff13629b28c96591 languageName: node linkType: hard -"@inquirer/type@npm:^1.2.0": - version: 1.2.0 - resolution: "@inquirer/type@npm:1.2.0" - checksum: 50be288696a55cf860cee8aef7e10751b3d28694f1f6f5fc9c085bb3c45aa77f43961d40626d48f16a993f16f12a83b4282b16845a173fb1791ddb79bb1f93e8 +"@inquirer/figures@npm:^1.0.8": + version: 1.0.8 + resolution: "@inquirer/figures@npm:1.0.8" + checksum: 24c5c70f49a5f0e9d38f5552fb6936c258d2fc545f6a4944b17ba357c9ca4a729e8cffd77666971554ebc2a57948cfe5003331271a259c406b3f2de0e9c559b7 + languageName: node + linkType: hard + +"@inquirer/type@npm:^3.0.1": + version: 3.0.1 + resolution: "@inquirer/type@npm:3.0.1" + peerDependencies: + "@types/node": ">=18" + checksum: af412f1e7541d43554b02199ae71a2039a1bff5dc51ceefd87de9ece55b199682733b28810fb4b6cb3ed4a159af4cc4a26d4bb29c58dd127e7d9dbda0797d8e7 languageName: node linkType: hard @@ -1276,9 +1282,9 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.35.8": - version: 0.35.9 - resolution: "@mswjs/interceptors@npm:0.35.9" +"@mswjs/interceptors@npm:^0.37.0": + version: 0.37.3 + resolution: "@mswjs/interceptors@npm:0.37.3" dependencies: "@open-draft/deferred-promise": ^2.2.0 "@open-draft/logger": ^0.3.0 @@ -1286,7 +1292,7 @@ __metadata: is-node-process: ^1.2.0 outvariant: ^1.4.3 strict-event-emitter: ^0.5.1 - checksum: 35b9382b94b7e3af962dc901db80bde99385645fb0b1f4cbaf64d58ff7181adb962430437db5b7d6db9db2e82399a3d1f319378d3c98e72c7ada8245180f0979 + checksum: 9a5ad23f8298e81133910611480aa28470febae0ce083e0072ffff7032d55f7214c1401c21d2bc9632ec1e475ac670ea0497f9aeaacbdf0d60fb1287ab00d528 languageName: node linkType: hard @@ -2895,25 +2901,7 @@ __metadata: languageName: node linkType: hard -"@types/mute-stream@npm:^0.0.4": - version: 0.0.4 - resolution: "@types/mute-stream@npm:0.0.4" - dependencies: - "@types/node": "*" - checksum: af8d83ad7b68ea05d9357985daf81b6c9b73af4feacb2f5c2693c7fd3e13e5135ef1bd083ce8d5bdc8e97acd28563b61bb32dec4e4508a8067fcd31b8a098632 - languageName: node - linkType: hard - -"@types/node@npm:*": - version: 22.7.8 - resolution: "@types/node@npm:22.7.8" - dependencies: - undici-types: ~6.19.2 - checksum: c1dd36bd0bf82588e61f82edb29a792f21ce902f90cc5485591f9fd60cec3ea9172e044bf7b1c0849e7cf3a5a01da39516db260cb65cb0b94904010e00634a1c - languageName: node - linkType: hard - -"@types/node@npm:^20.11.16, @types/node@npm:^20.12.5": +"@types/node@npm:^20.12.5": version: 20.12.5 resolution: "@types/node@npm:20.12.5" dependencies: @@ -3071,13 +3059,6 @@ __metadata: languageName: node linkType: hard -"@types/wrap-ansi@npm:^3.0.0": - version: 3.0.0 - resolution: "@types/wrap-ansi@npm:3.0.0" - checksum: 492f0610093b5802f45ca292777679bb9b381f1f32ae939956dd9e00bf81dba7cc99979687620a2817d9a7d8b59928207698166c47a0861c6a2e5c30d4aaf1e9 - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:8.16.0": version: 8.16.0 resolution: "@typescript-eslint/eslint-plugin@npm:8.16.0" @@ -4350,13 +4331,6 @@ __metadata: languageName: node linkType: hard -"cli-spinners@npm:^2.9.2": - version: 2.9.2 - resolution: "cli-spinners@npm:2.9.2" - checksum: 1bd588289b28432e4676cb5d40505cfe3e53f2e4e10fbe05c8a710a154d6fe0ce7836844b00d6858f740f2ffe67cdc36e0fce9c7b6a8430e80e6388d5aa4956c - languageName: node - linkType: hard - "cli-truncate@npm:^4.0.0": version: 4.0.0 resolution: "cli-truncate@npm:4.0.0" @@ -6154,15 +6128,6 @@ __metadata: languageName: node linkType: hard -"figures@npm:^3.2.0": - version: 3.2.0 - resolution: "figures@npm:3.2.0" - dependencies: - escape-string-regexp: ^1.0.5 - checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b - languageName: node - linkType: hard - "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -8846,26 +8811,27 @@ __metadata: languageName: node linkType: hard -"msw-storybook-addon@npm:^2.0.3": - version: 2.0.3 - resolution: "msw-storybook-addon@npm:2.0.3" +"msw-storybook-addon@npm:^2.0.4": + version: 2.0.4 + resolution: "msw-storybook-addon@npm:2.0.4" dependencies: is-node-process: ^1.0.1 peerDependencies: msw: ^2.0.0 - checksum: 13b607849aadf1f8f67c2f7447b27acbea2582363c76a9b7fe98ecab3ee5a101a078009fb1c93ac63e5dc52a723c38a8e0761e88d0494299e69965abca12e16a + checksum: 17d40c71fbdb896e616849bcba58df24de539786f232ccb635ce478d2f17098300275f7cb02d6b3d4078f8f8b8aeb996e7642effefa486a320e261b5142e6614 languageName: node linkType: hard -"msw@npm:^2.4.11": - version: 2.4.11 - resolution: "msw@npm:2.4.11" +"msw@npm:^2.6.7": + version: 2.6.7 + resolution: "msw@npm:2.6.7" dependencies: - "@bundled-es-modules/cookie": ^2.0.0 + "@bundled-es-modules/cookie": ^2.0.1 "@bundled-es-modules/statuses": ^1.0.1 "@bundled-es-modules/tough-cookie": ^0.1.6 - "@inquirer/confirm": ^3.0.0 - "@mswjs/interceptors": ^0.35.8 + "@inquirer/confirm": ^5.0.0 + "@mswjs/interceptors": ^0.37.0 + "@open-draft/deferred-promise": ^2.2.0 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.6.0 "@types/statuses": ^2.0.4 @@ -8885,14 +8851,14 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: f58634f5b7e7c1b69fd7d4f0d6ca09169719b8829e01f6bf5c4517b9c3159738d4a0cbd1b8c8b080fced82bf692edf72a064b419feb863f2d7e82ec852cf694b + checksum: 0aca4b1cf4939d6a6dae4901ddbf535f71e6d34d4594ceaf85f09ffaca44da0cb14ce5bb18350be720444330150f14ee9deeddeffa84d6a2dde777fcda17dfb0 languageName: node linkType: hard -"mute-stream@npm:^1.0.0": - version: 1.0.0 - resolution: "mute-stream@npm:1.0.0" - checksum: 36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7 +"mute-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "mute-stream@npm:2.0.0" + checksum: d2e4fd2f5aa342b89b98134a8d899d8ef9b0a6d69274c4af9df46faa2d97aeb1f2ce83d867880d6de63643c52386579b99139801e24e7526c3b9b0a6d1e18d6c languageName: node linkType: hard @@ -9939,8 +9905,8 @@ __metadata: lint-staged: ^15.2.10 lodash: ^4.17.21 mockdate: ^3.0.5 - msw: ^2.4.11 - msw-storybook-addon: ^2.0.3 + msw: ^2.6.7 + msw-storybook-addon: ^2.0.4 npm-run-all: ^4.1.5 otpauth: ^9.3.5 p-limit: ^6.1.0 @@ -10601,13 +10567,6 @@ __metadata: languageName: node linkType: hard -"run-async@npm:^3.0.0": - version: 3.0.0 - resolution: "run-async@npm:3.0.0" - checksum: 280c03d5a88603f48103fc6fd69f07fb0c392a1e0d319c34ec96a2516030e07ba06f79231a563c78698b882649c2fc1fda601bc84705f57d50efcd1fa506cfc0 - languageName: node - linkType: hard - "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -11864,13 +11823,6 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 - languageName: node - linkType: hard - "undici@npm:~6.20.1": version: 6.20.1 resolution: "undici@npm:6.20.1" @@ -12880,6 +12832,13 @@ __metadata: languageName: node linkType: hard +"yoctocolors-cjs@npm:^2.1.2": + version: 2.1.2 + resolution: "yoctocolors-cjs@npm:2.1.2" + checksum: 1c474d4b30a8c130e679279c5c2c33a0d48eba9684ffa0252cc64846c121fb56c3f25457fef902edbe1e2d7a7872130073a9fc8e795299d75e13fa3f5f548f1b + languageName: node + linkType: hard + "zwitch@npm:^2.0.0": version: 2.0.2 resolution: "zwitch@npm:2.0.2" From 83ac5093d014c995af6ad7f0ee46c02a58b0f978 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:31:56 +0000 Subject: [PATCH 10/13] Bump husky from 9.1.6 to 9.1.7 in /frontend-react in the project group (#16632) Bumps the project group in /frontend-react with 1 update: [husky](https://github.com/typicode/husky). Updates `husky` from 9.1.6 to 9.1.7 - [Release notes](https://github.com/typicode/husky/releases) - [Commits](https://github.com/typicode/husky/compare/v9.1.6...v9.1.7) --- updated-dependencies: - dependency-name: husky dependency-type: direct:development update-type: version-update:semver-patch dependency-group: project ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 2 +- frontend-react/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index 3873bd8d2f0..8216e2d9fff 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -168,7 +168,7 @@ "eslint-plugin-testing-library": "^7.1.1", "eslint-plugin-vitest": "^0.5.4", "globals": "^15.13.0", - "husky": "^9.1.6", + "husky": "^9.1.7", "jsdom": "^25.0.1", "lint-staged": "^15.2.10", "mockdate": "^3.0.5", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 54374c73b4f..5a824c7b103 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -6982,12 +6982,12 @@ __metadata: languageName: node linkType: hard -"husky@npm:^9.1.6": - version: 9.1.6 - resolution: "husky@npm:9.1.6" +"husky@npm:^9.1.7": + version: 9.1.7 + resolution: "husky@npm:9.1.7" bin: husky: bin.js - checksum: 421ccd8850378231aaefd70dbe9e4f1549b84ffe3a6897f93a202242bbc04e48bd498169aef43849411105d9fcf7c192b757d42661e28d06b934a609a4eb8771 + checksum: c2412753f15695db369634ba70f50f5c0b7e5cb13b673d0826c411ec1bd9ddef08c1dad89ea154f57da2521d2605bd64308af748749b27d08c5f563bcd89975f languageName: node linkType: hard @@ -9900,7 +9900,7 @@ __metadata: globals: ^15.13.0 history: ^5.3.0 html-to-text: ^9.0.5 - husky: ^9.1.6 + husky: ^9.1.7 jsdom: ^25.0.1 lint-staged: ^15.2.10 lodash: ^4.17.21 From 663f8a6841ba972e72423c10df59f9467bbb5231 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:45:27 +0000 Subject: [PATCH 11/13] Bump focus-trap-react in /frontend-react in the ui group (#16557) Bumps the ui group in /frontend-react with 1 update: [focus-trap-react](https://github.com/focus-trap/focus-trap-react). Updates `focus-trap-react` from 10.3.0 to 10.3.1 - [Release notes](https://github.com/focus-trap/focus-trap-react/releases) - [Changelog](https://github.com/focus-trap/focus-trap-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/focus-trap/focus-trap-react/compare/v10.3.0...v10.3.1) --- updated-dependencies: - dependency-name: focus-trap-react dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ui ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 2 +- frontend-react/yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index 8216e2d9fff..ab499b114c8 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -20,7 +20,7 @@ "date-fns-tz": "^3.2.0", "dompurify": "^3.2.2", "export-to-csv-fix-source-map": "^0.2.1", - "focus-trap-react": "^10.3.0", + "focus-trap-react": "^10.3.1", "history": "^5.3.0", "html-to-text": "^9.0.5", "lodash": "^4.17.21", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 5a824c7b103..16e3941a182 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -6192,26 +6192,26 @@ __metadata: languageName: node linkType: hard -"focus-trap-react@npm:^10.3.0": - version: 10.3.0 - resolution: "focus-trap-react@npm:10.3.0" +"focus-trap-react@npm:^10.3.1": + version: 10.3.1 + resolution: "focus-trap-react@npm:10.3.1" dependencies: - focus-trap: ^7.6.0 + focus-trap: ^7.6.1 tabbable: ^6.2.0 peerDependencies: prop-types: ^15.8.1 react: ">=16.3.0" react-dom: ">=16.3.0" - checksum: 040fb4a2ad848dee0fce72ca957843fb57c4cc5dd84d8e96e717d6b27cdb30d726a59b5503f3a3369dec4aeab42d9efe5dec625539c99a3f104c242192ab89f7 + checksum: 7992402b86a2ebada9232f36388fe7997e395365f1ca89927114caf84c53c546940c066b0a60417b01b4b366d97d0ac313d7c65ef69b74d188fc0863f850f480 languageName: node linkType: hard -"focus-trap@npm:^7.6.0": - version: 7.6.0 - resolution: "focus-trap@npm:7.6.0" +"focus-trap@npm:^7.6.1": + version: 7.6.2 + resolution: "focus-trap@npm:7.6.2" dependencies: tabbable: ^6.2.0 - checksum: 4cb89de0bf60b687787cdeedc4a44c37f2eba57a76f522915cf0550170acd937836fc8d00d31161a3bb58df14d871ead481f1f14d2600dcdd618ac027a220246 + checksum: b5873f8e506d3f466d9823d2f144612d3938f3c74c3be3db922052e5e54fd41a3a46889f8219f16f60d1ce5aff9e0a7fef9dea03ca0da96820c2ea36243236f7 languageName: node linkType: hard @@ -9896,7 +9896,7 @@ __metadata: eslint-plugin-testing-library: ^7.1.1 eslint-plugin-vitest: ^0.5.4 export-to-csv-fix-source-map: ^0.2.1 - focus-trap-react: ^10.3.0 + focus-trap-react: ^10.3.1 globals: ^15.13.0 history: ^5.3.0 html-to-text: ^9.0.5 From 4903089c6ede0b8961f15c70ad8a13e88f68bd43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 20:54:05 +0000 Subject: [PATCH 12/13] Bump @okta/okta-signin-widget (#16739) Bumps the auth group with 1 update in the /frontend-react directory: [@okta/okta-signin-widget](https://github.com/okta/okta-signin-widget). Updates `@okta/okta-signin-widget` from 7.24.2 to 7.26.1 - [Release notes](https://github.com/okta/okta-signin-widget/releases) - [Changelog](https://github.com/okta/okta-signin-widget/blob/master/webpack.release.config.js) - [Commits](https://github.com/okta/okta-signin-widget/compare/okta-signin-widget-7.24.2...okta-signin-widget-7.26.1) --- updated-dependencies: - dependency-name: "@okta/okta-signin-widget" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: auth ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 2 +- frontend-react/yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index ab499b114c8..e7f28f06ec0 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -8,7 +8,7 @@ "@microsoft/applicationinsights-react-js": "^17.3.4", "@microsoft/applicationinsights-web": "^3.3.4", "@okta/okta-react": "^6.9.0", - "@okta/okta-signin-widget": "^7.24.2", + "@okta/okta-signin-widget": "^7.26.1", "@rest-hooks/rest": "^3.0.3", "@tanstack/react-query": "^5.62.2", "@tanstack/react-query-devtools": "^5.62.2", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 16e3941a182..8e45b934495 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -1400,11 +1400,11 @@ __metadata: languageName: node linkType: hard -"@okta/okta-signin-widget@npm:^7.24.2": - version: 7.24.2 - resolution: "@okta/okta-signin-widget@npm:7.24.2" +"@okta/okta-signin-widget@npm:^7.26.1": + version: 7.26.1 + resolution: "@okta/okta-signin-widget@npm:7.26.1" dependencies: - "@okta/okta-auth-js": ^7.8.0 + "@okta/okta-auth-js": ^7.9.0 "@sindresorhus/to-milliseconds": ^1.0.0 "@types/backbone": ^1.4.15 "@types/eslint-scope": ^3.7.3 @@ -1426,7 +1426,7 @@ __metadata: dependenciesMeta: fsevents: optional: true - checksum: 5f444bb83fefd76eb34a5f35953f3aa09323c72c07628e893cc3bddcf56c887a1ccce1ed462c7e730ee387fa0de4e15050d0dce294f8de7bc8459e54f9145288 + checksum: bac77bb6cda8c34a5155859f11e4c1a50ff62a523fe48e2bbfdb58527ffa1265e7eabbacdc67c104b43b32b3f60b0a82704f075a65f7008090dc32a80b549433 languageName: node linkType: hard @@ -9830,7 +9830,7 @@ __metadata: "@microsoft/applicationinsights-react-js": ^17.3.4 "@microsoft/applicationinsights-web": ^3.3.4 "@okta/okta-react": ^6.9.0 - "@okta/okta-signin-widget": ^7.24.2 + "@okta/okta-signin-widget": ^7.26.1 "@playwright/test": ^1.49.0 "@rest-hooks/rest": ^3.0.3 "@rest-hooks/test": ^7.3.1 From 164926ec0a20bc93094960320a9748920aec7eb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 21:07:28 +0000 Subject: [PATCH 13/13] Bump @types/github-slugger (#16457) Bumps the typescript-types group in /frontend-react with 1 update: [@types/github-slugger](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/github-slugger). Updates `@types/github-slugger` from 1.3.0 to 2.0.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/github-slugger) --- updated-dependencies: - dependency-name: "@types/github-slugger" dependency-type: direct:development update-type: version-update:semver-major dependency-group: typescript-types ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend-react/package.json | 2 +- frontend-react/yarn.lock | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/frontend-react/package.json b/frontend-react/package.json index e7f28f06ec0..f081bf7eb01 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -135,7 +135,7 @@ "@types/dompurify": "^3.2.0", "@types/dotenv-flow": "^3.3.3", "@types/eslint__js": "^8.42.3", - "@types/github-slugger": "^1.3.0", + "@types/github-slugger": "^2.0.0", "@types/html-to-text": "^9.0.4", "@types/lodash": "^4.17.13", "@types/mdx": "^2.0.13", diff --git a/frontend-react/yarn.lock b/frontend-react/yarn.lock index 8e45b934495..15f8f6d4e66 100644 --- a/frontend-react/yarn.lock +++ b/frontend-react/yarn.lock @@ -2800,10 +2800,12 @@ __metadata: languageName: node linkType: hard -"@types/github-slugger@npm:^1.3.0": - version: 1.3.0 - resolution: "@types/github-slugger@npm:1.3.0" - checksum: 6561f26814d7c6bf619b1abfba07930ddc2f71e1e1d58a03c20852fd4086ec17f8ee98a44a8ac77ba917c0ff7052cd3fe74071fba59bd526dff8a3a980e2e528 +"@types/github-slugger@npm:^2.0.0": + version: 2.0.0 + resolution: "@types/github-slugger@npm:2.0.0" + dependencies: + github-slugger: "*" + checksum: 76d5b595baa678f78846c10e47088f6734fc8e2baee2b2657bae7830363eb298db761dd6bcc5e28686dc805084c908cee11fd270d4f48c77176d4d935b37bf7f languageName: node linkType: hard @@ -6458,7 +6460,7 @@ __metadata: languageName: node linkType: hard -"github-slugger@npm:^2.0.0": +"github-slugger@npm:*, github-slugger@npm:^2.0.0": version: 2.0.0 resolution: "github-slugger@npm:2.0.0" checksum: 250375cde2058f21454872c2c79f72c4637340c30c51ff158ca4ec71cbc478f33d54477d787a662f9207aeb095a2060f155bc01f15329ba8a5fb6698e0fc81f8 @@ -9857,7 +9859,7 @@ __metadata: "@types/dompurify": ^3.2.0 "@types/dotenv-flow": ^3.3.3 "@types/eslint__js": ^8.42.3 - "@types/github-slugger": ^1.3.0 + "@types/github-slugger": ^2.0.0 "@types/html-to-text": ^9.0.4 "@types/lodash": ^4.17.13 "@types/mdx": ^2.0.13