diff --git a/dataspray-authorizer/src/main/java/io/dataspray/authorizer/Authorizer.java b/dataspray-authorizer/src/main/java/io/dataspray/authorizer/Authorizer.java index 3c0bc937..a0d6e6f5 100644 --- a/dataspray-authorizer/src/main/java/io/dataspray/authorizer/Authorizer.java +++ b/dataspray-authorizer/src/main/java/io/dataspray/authorizer/Authorizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -83,8 +83,7 @@ public Object handleRequest(APIGatewayCustomAuthorizerEvent event, Context conte String authorizationValueLower = authorizationValue.toLowerCase(); final String identifier; - final String userEmail; - final String principalId; + final String username; final ImmutableSet organizationNames; final ImmutableSet queueWhitelist; final Optional usageKey; @@ -96,12 +95,11 @@ public Object handleRequest(APIGatewayCustomAuthorizerEvent event, Context conte .orElseThrow(() -> new ApiGatewayUnauthorized("Cognito JWT verification failed")); // Extract access info - userEmail = verifiedCognitoJwt.getUserEmail(); - principalId = verifiedCognitoJwt.getUserEmail(); + username = verifiedCognitoJwt.getUsername(); organizationNames = verifiedCognitoJwt.getGroupNames(); queueWhitelist = ImmutableSet.of(); - usageKey = apiAccessStore.getUsageKey(verifiedCognitoJwt.getUsageKeyType(), Optional.of(verifiedCognitoJwt.getUserEmail()), organizationNames); - identifier = "user " + verifiedCognitoJwt.getUserEmail() + " via cognito JWT"; + usageKey = apiAccessStore.getUsageKey(verifiedCognitoJwt.getUsageKeyType(), Optional.of(verifiedCognitoJwt.getUsername()), organizationNames); + identifier = "user " + verifiedCognitoJwt.getUsername() + " via cognito JWT"; } else if (authorizationValueLower.startsWith("apikey ")) { @@ -111,17 +109,16 @@ public Object handleRequest(APIGatewayCustomAuthorizerEvent event, Context conte .orElseThrow(() -> new ApiGatewayUnauthorized("invalid apikey found")); // Extract access info - userEmail = apiAccess.getOwnerEmail(); - principalId = apiAccess.getPrincipalId(); + username = apiAccess.getOwnerUsername(); organizationNames = ImmutableSet.of(apiAccess.getOrganizationName()); queueWhitelist = apiAccess.getQueueWhitelist(); - usageKey = apiAccessStore.getUsageKey(apiAccess.getUsageKeyType(), Optional.of(apiAccess.getOwnerEmail()), ImmutableSet.of(apiAccess.getOrganizationName())); + usageKey = apiAccessStore.getUsageKey(apiAccess.getUsageKeyType(), Optional.of(apiAccess.getOwnerUsername()), ImmutableSet.of(apiAccess.getOrganizationName())); switch (apiAccess.getOwnerType()) { - case USER -> identifier = "user " + apiAccess.getOwnerEmail() + " via apikey"; + case USER -> identifier = "user " + apiAccess.getOwnerUsername() + " via apikey"; case TASK -> identifier = "task " + apiAccess.getOwnerTaskId() + " version " + apiAccess.getOwnerTaskVersion() + " via apikey"; default -> - identifier = apiAccess.getOwnerType() + " owner email " + apiAccess.getOwnerEmail() + " via apikey"; + identifier = apiAccess.getOwnerType() + " owner email " + apiAccess.getOwnerUsername() + " via apikey"; } } else { @@ -140,11 +137,11 @@ public Object handleRequest(APIGatewayCustomAuthorizerEvent event, Context conte log.info("Client authorized for {}", identifier); PolicyDocument policyDocument = generatePolicyDocument(region, awsAccountId, restApiId, stage, organizationNames, queueWhitelist); return new AuthPolicy( - principalId, + username, policyDocument, usageKey, Map.of( - AuthorizerConstants.CONTEXT_KEY_USER_EMAIL, userEmail, + AuthorizerConstants.CONTEXT_KEY_USERNAME, username, AuthorizerConstants.CONTEXT_KEY_ORGANIZATION_NAMES, String.join(",", organizationNames) )); } catch (ApiGatewayUnauthorized ex) { diff --git a/dataspray-authorizer/src/test/java/io/dataspray/authorizer/AuthorizerBase.java b/dataspray-authorizer/src/test/java/io/dataspray/authorizer/AuthorizerBase.java index dace0baf..661794d3 100644 --- a/dataspray-authorizer/src/test/java/io/dataspray/authorizer/AuthorizerBase.java +++ b/dataspray-authorizer/src/test/java/io/dataspray/authorizer/AuthorizerBase.java @@ -125,7 +125,7 @@ void test(TestType testType) throws Exception { case GLOBAL -> "dataspray-usage-key-2-GLOBAL"; case UNLIMITED -> null; })) - .body("context." + AuthorizerConstants.CONTEXT_KEY_USER_EMAIL, equalTo(apiAccess.getOwnerEmail())) + .body("context." + AuthorizerConstants.CONTEXT_KEY_USERNAME, equalTo(apiAccess.getOwnerUsername())) .body("context." + AuthorizerConstants.CONTEXT_KEY_ORGANIZATION_NAMES, equalTo(apiAccess.getOrganizationName())) .body("policyDocument", jsonStringEqualTo(ResourceUtil.getTestResource( testType == TestType.AUTHORIZED_QUEUE_WHITELIST diff --git a/dataspray-common/src/main/java/io/dataspray/common/authorizer/AuthorizerConstants.java b/dataspray-common/src/main/java/io/dataspray/common/authorizer/AuthorizerConstants.java index 6a4c2198..13fc4a1f 100644 --- a/dataspray-common/src/main/java/io/dataspray/common/authorizer/AuthorizerConstants.java +++ b/dataspray-common/src/main/java/io/dataspray/common/authorizer/AuthorizerConstants.java @@ -9,7 +9,7 @@ @ApplicationScoped public class AuthorizerConstants { - public static final String CONTEXT_KEY_USER_EMAIL = "userEmail"; + public static final String CONTEXT_KEY_USERNAME = "username"; /** Value will hold comma delimited list of organization names */ public static final String CONTEXT_KEY_ORGANIZATION_NAMES = "organizationName"; diff --git a/dataspray-lambda-web-test/src/main/java/io/dataspray/common/test/aws/AbstractLambdaTest.java b/dataspray-lambda-web-test/src/main/java/io/dataspray/common/test/aws/AbstractLambdaTest.java index 53a69601..16cc2686 100644 --- a/dataspray-lambda-web-test/src/main/java/io/dataspray/common/test/aws/AbstractLambdaTest.java +++ b/dataspray-lambda-web-test/src/main/java/io/dataspray/common/test/aws/AbstractLambdaTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -78,8 +78,8 @@ protected AwsResponse request(Class bodyClazz, Given given) { request.getRequestContext().setResourcePath(given.getPath()); request.getRequestContext().setHttpMethod(given.getMethod()); request.getRequestContext().setAuthorizer(new ApiGatewayAuthorizerContext()); - request.getRequestContext().getAuthorizer().setPrincipalId(given.getUserEmail()); - request.getRequestContext().getAuthorizer().setContextValue(AuthorizerConstants.CONTEXT_KEY_USER_EMAIL, String.join(",", given.getUserEmail())); + request.getRequestContext().getAuthorizer().setPrincipalId(given.getUsername()); + request.getRequestContext().getAuthorizer().setContextValue(AuthorizerConstants.CONTEXT_KEY_USERNAME, String.join(",", given.getUsername())); request.getRequestContext().getAuthorizer().setContextValue(AuthorizerConstants.CONTEXT_KEY_ORGANIZATION_NAMES, String.join(",", getOrganizationName())); Response response = RestAssured.given() .contentType("application/json") @@ -116,7 +116,7 @@ protected static class Given { MediaType contentType; Object body; @Builder.Default - String userEmail = "user@example.com"; + String username = "username"; } diff --git a/dataspray-lambda-web/src/main/java/io/dataspray/web/resource/AbstractResource.java b/dataspray-lambda-web/src/main/java/io/dataspray/web/resource/AbstractResource.java index 7b45f8b0..0ae77815 100644 --- a/dataspray-lambda-web/src/main/java/io/dataspray/web/resource/AbstractResource.java +++ b/dataspray-lambda-web/src/main/java/io/dataspray/web/resource/AbstractResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -54,15 +54,15 @@ public abstract class AbstractResource { protected UriInfo uriInfo; /** - * Retrieve user email as passed in via context from Cognito Authorizer function. + * Retrieve username as passed in via context from Cognito Authorizer function. *

* May be empty if authorizer did not process this request, most likely as this API endpoint is open to public. */ - protected Optional getUserEmail() { + protected Optional getUsername() { return Optional.ofNullable(Strings.emptyToNull(proxyRequest .getRequestContext() .getAuthorizer() - .getContextValue(AuthorizerConstants.CONTEXT_KEY_USER_EMAIL))); + .getContextValue(AuthorizerConstants.CONTEXT_KEY_USERNAME))); } /** diff --git a/dataspray-lambda-web/src/test/java/io/dataspray/web/ExampleLambdaTest.java b/dataspray-lambda-web/src/test/java/io/dataspray/web/ExampleLambdaTest.java index f2aa2cd1..47d31825 100644 --- a/dataspray-lambda-web/src/test/java/io/dataspray/web/ExampleLambdaTest.java +++ b/dataspray-lambda-web/src/test/java/io/dataspray/web/ExampleLambdaTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,11 +44,11 @@ public enum TestType { .path("/api/ping") .build(), "OK"), - USER_EMAIL(Given.builder() - .path("/api/user-email") - .userEmail("expected.email@example.com") + USERNAME(Given.builder() + .path("/api/username") + .username("expected.username") .build(), - "expected.email@example.com"); + "expected.username"); private final Given given; private final String expectedBody; diff --git a/dataspray-lambda-web/src/test/java/io/dataspray/web/api/ExampleApi.java b/dataspray-lambda-web/src/test/java/io/dataspray/web/api/ExampleApi.java index 10f3a9ae..99558f20 100644 --- a/dataspray-lambda-web/src/test/java/io/dataspray/web/api/ExampleApi.java +++ b/dataspray-lambda-web/src/test/java/io/dataspray/web/api/ExampleApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,6 @@ public interface ExampleApi { String ping(); @GET - @Path("/user-email") - String userEmail(); + @Path("/username") + String username(); } diff --git a/dataspray-lambda-web/src/test/java/io/dataspray/web/resource/ExampleResource.java b/dataspray-lambda-web/src/test/java/io/dataspray/web/resource/ExampleResource.java index 1674bd7d..1c2ca370 100644 --- a/dataspray-lambda-web/src/test/java/io/dataspray/web/resource/ExampleResource.java +++ b/dataspray-lambda-web/src/test/java/io/dataspray/web/resource/ExampleResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,7 @@ public String ping() { } @Override - public String userEmail() { - return getUserEmail().orElseThrow(); + public String username() { + return getUsername().orElseThrow(); } } diff --git a/dataspray-package/src/main/java/io/dataspray/cdk/store/AuthNzStack.java b/dataspray-package/src/main/java/io/dataspray/cdk/store/AuthNzStack.java index 45e08e4e..31cbdd64 100644 --- a/dataspray-package/src/main/java/io/dataspray/cdk/store/AuthNzStack.java +++ b/dataspray-package/src/main/java/io/dataspray/cdk/store/AuthNzStack.java @@ -81,6 +81,8 @@ public AuthNzStack(Construct parent, DeployEnvironment deployEnv) { .tempPasswordValidity(Duration.days(1)).build()) .signInCaseSensitive(false) .signInAliases(SignInAliases.builder() + .preferredUsername(true) + .username(true) .email(true).build()) .deviceTracking(DeviceTracking.builder() .deviceOnlyRememberedOnUserPrompt(true) diff --git a/dataspray-site/package.json b/dataspray-site/package.json index 27578f57..3f68426a 100644 --- a/dataspray-site/package.json +++ b/dataspray-site/package.json @@ -24,6 +24,10 @@ "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@fontsource/roboto": "^5.0.5", + "@mdx-js/loader": "^3.0.0", + "@mdx-js/react": "^3.0.0", + "@next/mdx": "^14.0.4", + "@types/mdx": "^2.0.10", "@types/node": "^17.0.45", "@types/node-fetch": "^2.6.9", "formik": "^2.4.5", diff --git a/dataspray-site/pnpm-lock.yaml b/dataspray-site/pnpm-lock.yaml index 00d1d9ec..16fd0805 100644 --- a/dataspray-site/pnpm-lock.yaml +++ b/dataspray-site/pnpm-lock.yaml @@ -34,6 +34,18 @@ dependencies: '@fontsource/roboto': specifier: ^5.0.5 version: 5.0.5 + '@mdx-js/loader': + specifier: ^3.0.0 + version: 3.0.0(webpack@5.88.2) + '@mdx-js/react': + specifier: ^3.0.0 + version: 3.0.0(@types/react@18.2.37)(react@18.2.0) + '@next/mdx': + specifier: ^14.0.4 + version: 14.0.4(@mdx-js/loader@3.0.0)(@mdx-js/react@3.0.0) + '@types/mdx': + specifier: ^2.0.10 + version: 2.0.10 '@types/node': specifier: ^17.0.45 version: 17.0.45 @@ -1585,7 +1597,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.19.2: @@ -1603,7 +1614,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.19.2: @@ -1621,7 +1631,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.19.2: @@ -1639,7 +1648,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.19.2: @@ -1657,7 +1665,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.19.2: @@ -1675,7 +1682,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.19.2: @@ -1693,7 +1699,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.19.2: @@ -1711,7 +1716,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.19.2: @@ -1729,7 +1733,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.19.2: @@ -1747,7 +1750,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.19.2: @@ -1765,7 +1767,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.19.2: @@ -1783,7 +1784,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.19.2: @@ -1801,7 +1801,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.19.2: @@ -1819,7 +1818,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.19.2: @@ -1837,7 +1835,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.19.2: @@ -1855,7 +1852,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.19.2: @@ -1873,7 +1869,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.19.2: @@ -1891,7 +1886,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.19.2: @@ -1909,7 +1903,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.19.2: @@ -1927,7 +1920,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.19.2: @@ -1945,7 +1937,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.19.2: @@ -1963,7 +1954,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.19.2: @@ -2077,44 +2067,90 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/source-map@0.3.5: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@juggle/resize-observer@3.4.0: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} dev: false + /@mdx-js/loader@3.0.0(webpack@5.88.2): + resolution: {integrity: sha512-9kLv83YtgxpoXVYHaf0ygx1dmhCffo0MQCv6KtNG67jy/JlBK/2Q0dSWfuuyStP3jnZKABHfbjv8zsiT1buu6A==} + peerDependencies: + webpack: '>=5' + dependencies: + '@mdx-js/mdx': 3.0.0 + source-map: 0.7.4 + webpack: 5.88.2(esbuild@0.18.17) + transitivePeerDependencies: + - supports-color + dev: false + + /@mdx-js/mdx@3.0.0: + resolution: {integrity: sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==} + dependencies: + '@types/estree': 1.0.1 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdx': 2.0.10 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-build-jsx: 3.0.1 + estree-util-is-identifier-name: 3.0.0 + estree-util-to-js: 2.0.0 + estree-walker: 3.0.3 + hast-util-to-estree: 3.1.0 + hast-util-to-jsx-runtime: 2.3.0 + markdown-extensions: 2.0.0 + periscopic: 3.1.0 + remark-mdx: 3.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.0.0 + source-map: 0.7.4 + unified: 11.0.4 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@mdx-js/react@3.0.0(@types/react@18.2.37)(react@18.2.0): + resolution: {integrity: sha512-nDctevR9KyYFyV+m+/+S4cpzCWHqj+iHDHq3QrsWezcC+B17uZdIWgCguESUkwFhM3n/56KxWVE3V6EokrmONQ==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + dependencies: + '@types/mdx': 2.0.10 + '@types/react': 18.2.37 + react: 18.2.0 + dev: false + /@next/env@14.0.3: resolution: {integrity: sha512-7xRqh9nMvP5xrW4/+L0jgRRX+HoNRGnfJpD+5Wq6/13j3dsdzxO3BCXn7D3hMqsDb+vjZnJq+vI7+EtgrYZTeA==} dev: false @@ -2125,6 +2161,22 @@ packages: glob: 7.1.7 dev: true + /@next/mdx@14.0.4(@mdx-js/loader@3.0.0)(@mdx-js/react@3.0.0): + resolution: {integrity: sha512-w0b+A2LRdlqqTIzmaeqPOaafid2cYYYjETA+G+3ZFwkNbBQjvZp57P1waOexF3MGHzcCEoXEnhYpAc+FO6S0Rg==} + peerDependencies: + '@mdx-js/loader': '>=0.15.0' + '@mdx-js/react': '>=0.15.0' + peerDependenciesMeta: + '@mdx-js/loader': + optional: true + '@mdx-js/react': + optional: true + dependencies: + '@mdx-js/loader': 3.0.0(webpack@5.88.2) + '@mdx-js/react': 3.0.0(@types/react@18.2.37)(react@18.2.0) + source-map: 0.7.4 + dev: false + /@next/swc-darwin-arm64@14.0.3: resolution: {integrity: sha512-64JbSvi3nbbcEtyitNn2LEDS/hcleAFpHdykpcnrstITFlzFgB/bW0ER5/SJJwUPj+ZPY+z3e+1jAfcczRLVGw==} engines: {node: '>= 10'} @@ -2696,23 +2748,44 @@ packages: resolution: {integrity: sha512-RbwvSJQsuN9TB04AQbGULYfOGE/RnSFk/FLQ5b0NmDf5Kx2q/lABZbHQPKCO1vZ6Fiwkplu+yb9pGdLy1iGseQ==} dev: true + /@types/acorn@4.0.6: + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + dependencies: + '@types/estree': 1.0.1 + dev: false + + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + dependencies: + '@types/ms': 0.7.34 + dev: false + /@types/eslint-scope@3.7.4: resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} dependencies: '@types/eslint': 8.44.1 '@types/estree': 1.0.1 - dev: true /@types/eslint@8.44.1: resolution: {integrity: sha512-XpNDc4Z5Tb4x+SW1MriMVeIsMoONHCkWFMkR/aPJbzEsxqHy+4Glu/BqTdPrApfDeMaXbtNh6bseNgl5KaWrSg==} dependencies: '@types/estree': 1.0.1 '@types/json-schema': 7.0.12 - dev: true + + /@types/estree-jsx@1.0.3: + resolution: {integrity: sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==} + dependencies: + '@types/estree': 1.0.1 + dev: false /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} - dev: true + + /@types/hast@3.0.3: + resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false /@types/hoist-non-react-statics@3.3.5: resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} @@ -2723,12 +2796,25 @@ packages: /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - dev: true /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/mdast@4.0.3: + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /@types/mdx@2.0.10: + resolution: {integrity: sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==} + dev: false + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: false + /@types/node-fetch@2.6.9: resolution: {integrity: sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==} dependencies: @@ -2766,6 +2852,14 @@ packages: /@types/scheduler@0.16.6: resolution: {integrity: sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==} + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: false + + /@types/unist@3.0.2: + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + dev: false + /@typescript-eslint/parser@6.11.0(eslint@8.46.0)(typescript@5.1.6): resolution: {integrity: sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2829,24 +2923,24 @@ packages: eslint-visitor-keys: 3.4.3 dev: true + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: false + /@webassemblyjs/ast@1.11.6: resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} dependencies: '@webassemblyjs/helper-numbers': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 - dev: true /@webassemblyjs/floating-point-hex-parser@1.11.6: resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} - dev: true /@webassemblyjs/helper-api-error@1.11.6: resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} - dev: true /@webassemblyjs/helper-buffer@1.11.6: resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} - dev: true /@webassemblyjs/helper-numbers@1.11.6: resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} @@ -2854,11 +2948,9 @@ packages: '@webassemblyjs/floating-point-hex-parser': 1.11.6 '@webassemblyjs/helper-api-error': 1.11.6 '@xtuc/long': 4.2.2 - dev: true /@webassemblyjs/helper-wasm-bytecode@1.11.6: resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} - dev: true /@webassemblyjs/helper-wasm-section@1.11.6: resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} @@ -2867,23 +2959,19 @@ packages: '@webassemblyjs/helper-buffer': 1.11.6 '@webassemblyjs/helper-wasm-bytecode': 1.11.6 '@webassemblyjs/wasm-gen': 1.11.6 - dev: true /@webassemblyjs/ieee754@1.11.6: resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} dependencies: '@xtuc/ieee754': 1.2.0 - dev: true /@webassemblyjs/leb128@1.11.6: resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} dependencies: '@xtuc/long': 4.2.2 - dev: true /@webassemblyjs/utf8@1.11.6: resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} - dev: true /@webassemblyjs/wasm-edit@1.11.6: resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} @@ -2896,7 +2984,6 @@ packages: '@webassemblyjs/wasm-opt': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 '@webassemblyjs/wast-printer': 1.11.6 - dev: true /@webassemblyjs/wasm-gen@1.11.6: resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} @@ -2906,7 +2993,6 @@ packages: '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - dev: true /@webassemblyjs/wasm-opt@1.11.6: resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} @@ -2915,7 +3001,6 @@ packages: '@webassemblyjs/helper-buffer': 1.11.6 '@webassemblyjs/wasm-gen': 1.11.6 '@webassemblyjs/wasm-parser': 1.11.6 - dev: true /@webassemblyjs/wasm-parser@1.11.6: resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} @@ -2926,22 +3011,18 @@ packages: '@webassemblyjs/ieee754': 1.11.6 '@webassemblyjs/leb128': 1.11.6 '@webassemblyjs/utf8': 1.11.6 - dev: true /@webassemblyjs/wast-printer@1.11.6: resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} dependencies: '@webassemblyjs/ast': 1.11.6 '@xtuc/long': 4.2.2 - dev: true /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - dev: true /@xtuc/long@4.2.2: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - dev: true /@zeit/schemas@2.29.0: resolution: {integrity: sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==} @@ -2965,7 +3046,6 @@ packages: acorn: ^8 dependencies: acorn: 8.10.0 - dev: true /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -2973,13 +3053,11 @@ packages: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: acorn: 8.10.0 - dev: true /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /ajv-keywords@3.5.2(ajv@6.12.6): resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} @@ -2987,7 +3065,6 @@ packages: ajv: ^6.9.1 dependencies: ajv: 6.12.6 - dev: true /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -2996,7 +3073,6 @@ packages: fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - dev: true /ajv@8.11.0: resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} @@ -3156,6 +3232,11 @@ packages: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} dev: true + /astring@1.8.6: + resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + hasBin: true + dev: false + /asynciterator.prototype@1.0.0: resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} dependencies: @@ -3207,6 +3288,10 @@ packages: resolve: 1.22.2 dev: false + /bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + dev: false + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -3275,7 +3360,6 @@ packages: electron-to-chromium: 1.4.476 node-releases: 2.0.13 update-browserslist-db: 1.0.11(browserslist@4.21.9) - dev: true /browserslist@4.22.1: resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} @@ -3290,7 +3374,6 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} @@ -3330,12 +3413,15 @@ packages: /caniuse-lite@1.0.30001517: resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==} - dev: true /caniuse-lite@1.0.30001563: resolution: {integrity: sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==} dev: false + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + dev: false + /chalk-template@0.4.0: resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} engines: {node: '>=12'} @@ -3370,6 +3456,22 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: true + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: false + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: false + + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: false + + /character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + dev: false + /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true @@ -3392,7 +3494,6 @@ packages: /chrome-trace-event@1.0.3: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} - dev: true /cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} @@ -3448,6 +3549,10 @@ packages: engines: {node: '>=6'} dev: false + /collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + dev: false + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -3476,9 +3581,12 @@ packages: delayed-stream: 1.0.0 dev: false + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: false + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true /compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} @@ -3637,7 +3745,12 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: false /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} @@ -3685,7 +3798,12 @@ packages: /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - dev: true + + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dependencies: + dequal: 2.0.3 + dev: false /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -3752,7 +3870,6 @@ packages: /electron-to-chromium@1.4.476: resolution: {integrity: sha512-gzWl1m8pNy+5Kj17XcziNcbOhripjTqR2wAQmtdlFUngPYuFy7zUpJScVQAvCvQSFHNk3mS5fetNKW6BSpytFg==} - dev: true /electron-to-chromium@1.4.594: resolution: {integrity: sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==} @@ -3772,7 +3889,6 @@ packages: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - dev: true /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} @@ -3851,7 +3967,6 @@ packages: /es-module-lexer@1.3.0: resolution: {integrity: sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==} - dev: true /es-set-tostringtag@2.0.2: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} @@ -3905,7 +4020,6 @@ packages: '@esbuild/win32-arm64': 0.18.17 '@esbuild/win32-ia32': 0.18.17 '@esbuild/win32-x64': 0.18.17 - dev: true /esbuild@0.19.2: resolution: {integrity: sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==} @@ -4143,7 +4257,6 @@ packages: dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 - dev: true /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} @@ -4230,17 +4343,54 @@ packages: engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 - dev: true /estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} - dev: true /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - dev: true + + /estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + dependencies: + '@types/estree': 1.0.1 + dev: false + + /estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + dependencies: + '@types/estree-jsx': 1.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + dev: false + + /estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + dev: false + + /estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + dependencies: + '@types/estree-jsx': 1.0.3 + astring: 1.8.6 + source-map: 0.7.4 + dev: false + + /estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/unist': 3.0.2 + dev: false + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.1 + dev: false /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} @@ -4250,7 +4400,6 @@ packages: /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - dev: true /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} @@ -4267,6 +4416,10 @@ packages: strip-final-newline: 2.0.0 dev: true + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: false + /external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -4278,7 +4431,6 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -4293,7 +4445,6 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -4577,7 +4728,6 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - dev: true /has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} @@ -4615,6 +4765,57 @@ packages: function-bind: 1.1.2 dev: true + /hast-util-to-estree@3.1.0: + resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} + dependencies: + '@types/estree': 1.0.1 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.4 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /hast-util-to-jsx-runtime@2.3.0: + resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} + dependencies: + '@types/estree': 1.0.1 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + style-to-object: 1.0.5 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + dependencies: + '@types/hast': 3.0.3 + dev: false + /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: @@ -4694,6 +4895,14 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true + /inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + dev: false + + /inline-style-parser@0.2.2: + resolution: {integrity: sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==} + dev: false + /inquirer@9.2.8: resolution: {integrity: sha512-SJ0fVfgIzZL1AD6WvFhivlh5/3hN6WeAvpvPrpPXH/8MOcQHeXhinmSm5CDJNRC2Q+sLh9YJ5k8F8/5APMXSfw==} engines: {node: '>=14.18.0'} @@ -4733,6 +4942,17 @@ packages: tslib: 2.6.2 dev: false + /is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + dev: false + + /is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + dev: false + /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: @@ -4796,6 +5016,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + dev: false + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -4830,6 +5054,10 @@ packages: dependencies: is-extglob: 2.1.1 + /is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + dev: false + /is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -4860,11 +5088,22 @@ packages: engines: {node: '>=8'} dev: true + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: false + /is-port-reachable@4.0.0: resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + dependencies: + '@types/estree': 1.0.1 + dev: false + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -4968,7 +5207,6 @@ packages: '@types/node': 17.0.45 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4985,7 +5223,6 @@ packages: /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -5042,7 +5279,6 @@ packages: /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} - dev: true /loader-utils@3.2.1: resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==} @@ -5079,6 +5315,10 @@ packages: is-unicode-supported: 0.1.0 dev: true + /longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + dev: false + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -5097,15 +5337,397 @@ packages: yallist: 4.0.0 dev: true + /markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + dev: false + + /mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx-expression@2.0.0: + resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx-jsx@3.0.0: + resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.3 + unist-util-remove-position: 5.0.0 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + dependencies: + mdast-util-from-markdown: 2.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-phrasing@4.0.0: + resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} + dependencies: + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 + dev: false + + /mdast-util-to-hast@13.0.2: + resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} + dependencies: + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + dev: false + + /mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.0.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + dev: false + + /mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + dependencies: + '@types/mdast': 4.0.3 + dev: false + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true + /micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdx-expression@3.0.0: + resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} + dependencies: + '@types/estree': 1.0.1 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdx-jsx@3.0.0: + resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.1 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + dependencies: + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + dependencies: + '@types/estree': 1.0.1 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + dependencies: + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + micromark-extension-mdx-expression: 3.0.0 + micromark-extension-mdx-jsx: 3.0.0 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-mdx-expression@2.0.1: + resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} + dependencies: + '@types/estree': 1.0.1 + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-character@2.0.1: + resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + dev: false + + /micromark-util-events-to-acorn@2.0.2: + resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.1 + '@types/unist': 3.0.2 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + dev: false + + /micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + dependencies: + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + dev: false + + /micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + dev: false + + /micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: false + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -5192,7 +5814,6 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -5220,7 +5841,6 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true /next@14.0.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-AbYdRNfImBr3XGtvnwOxq8ekVCwbFTv/UJoLwmaX89nk9i051AEY4/HAWzU0YpaTDw8IofUpmuIlvzWF13jxIw==} @@ -5446,6 +6066,19 @@ packages: dependencies: callsites: 3.1.0 + /parse-entities@4.0.1: + resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + dependencies: + '@types/unist': 2.0.10 + character-entities: 2.0.2 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.0.2 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + dev: false + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -5497,6 +6130,14 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + dependencies: + '@types/estree': 1.0.1 + estree-walker: 3.0.3 + is-reference: 3.0.2 + dev: false + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -5632,6 +6273,10 @@ packages: resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} dev: false + /property-information@6.4.0: + resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} + dev: false + /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: true @@ -5639,7 +6284,6 @@ packages: /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} - dev: true /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -5649,7 +6293,6 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 - dev: true /range-parser@1.2.0: resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} @@ -5780,6 +6423,36 @@ packages: rc: 1.2.8 dev: true + /remark-mdx@3.0.0: + resolution: {integrity: sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==} + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + micromark-util-types: 2.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-rehype@11.0.0: + resolution: {integrity: sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==} + dependencies: + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + mdast-util-to-hast: 13.0.2 + unified: 11.0.4 + vfile: 6.0.1 + dev: false + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -5887,7 +6560,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} @@ -5924,7 +6596,6 @@ packages: '@types/json-schema': 7.0.12 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - dev: true /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -5943,7 +6614,6 @@ packages: resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} dependencies: randombytes: 2.1.0 - dev: true /serve-handler@6.1.5: resolution: {integrity: sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==} @@ -6040,7 +6710,6 @@ packages: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true /source-map@0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} @@ -6050,7 +6719,15 @@ packages: /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: false + + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: false /spawn-command@0.0.2: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} @@ -6128,6 +6805,13 @@ packages: safe-buffer: 5.2.1 dev: true + /stringify-entities@4.0.3: + resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: false + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -6165,6 +6849,18 @@ packages: /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + /style-to-object@0.4.4: + resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} + dependencies: + inline-style-parser: 0.1.1 + dev: false + + /style-to-object@1.0.5: + resolution: {integrity: sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==} + dependencies: + inline-style-parser: 0.2.2 + dev: false + /styled-jsx@5.1.1(react@18.2.0): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -6205,7 +6901,6 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 - dev: true /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -6214,7 +6909,6 @@ packages: /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - dev: true /terser-webpack-plugin@5.3.9(esbuild@0.18.17)(webpack@5.88.2): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} @@ -6239,7 +6933,6 @@ packages: serialize-javascript: 6.0.1 terser: 5.19.2 webpack: 5.88.2(esbuild@0.18.17) - dev: true /terser@5.16.9: resolution: {integrity: sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==} @@ -6261,7 +6954,6 @@ packages: acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21 - dev: true /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -6306,6 +6998,14 @@ packages: hasBin: true dev: true + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + dev: false + + /trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + dev: false + /ts-api-utils@1.0.3(typescript@5.1.6): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} @@ -6407,6 +7107,64 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /unified@11.0.4: + resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + dependencies: + '@types/unist': 3.0.2 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 6.0.1 + dev: false + + /unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + dependencies: + '@types/unist': 3.0.2 + unist-util-visit: 5.0.0 + dev: false + + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + dev: false + + /unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: false + /update-browserslist-db@1.0.11(browserslist@4.21.9): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} hasBin: true @@ -6416,7 +7174,6 @@ packages: browserslist: 4.21.9 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /update-browserslist-db@1.0.13(browserslist@4.22.1): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} @@ -6440,7 +7197,6 @@ packages: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.0 - dev: true /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -6454,6 +7210,21 @@ packages: engines: {node: '>= 0.8'} dev: true + /vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + dev: false + + /vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + dev: false + /watchpack@2.4.0: resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} engines: {node: '>=10.13.0'} @@ -6470,7 +7241,6 @@ packages: /webpack-sources@3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - dev: true /webpack@5.88.2(esbuild@0.18.17): resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} @@ -6510,7 +7280,6 @@ packages: - '@swc/core' - esbuild - uglify-js - dev: true /weekstart@1.1.0: resolution: {integrity: sha512-ZO3I7c7J9nwGN1PZKZeBYAsuwWEsCOZi5T68cQoVNYrzrpp5Br0Bgi0OF4l8kH/Ez7nKfxa5mSsXjsgris3+qg==} @@ -6654,3 +7423,7 @@ packages: toposort: 2.0.2 type-fest: 2.19.0 dev: false + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: false diff --git a/dataspray-site/src/common/dashboard/client.ts b/dataspray-site/src/common/dashboard/client.ts index 9c1e4de1..71f3bb7e 100644 --- a/dataspray-site/src/common/dashboard/client.ts +++ b/dataspray-site/src/common/dashboard/client.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,6 +21,7 @@ */ import * as Api from "../../client"; +import {HTTPHeaders} from "../../client"; import {isCsr} from "../util/isoUtil"; // Recommended way to create a constructor type @@ -29,7 +30,7 @@ type BaseAPIConstructor = { new(conf: Api.Configuration): T }; const clientCache = new Map, Api.BaseAPI>(); var confCache: Api.Configuration; -var apiKey: string = ''; +var headers: HTTPHeaders = {}; const getClient = (ctor: BaseAPIConstructor): T => { var client: T = clientCache.get(ctor) as T; @@ -49,10 +50,12 @@ const getClientConfiguration = (): Api.Configuration => { throw new Error("SSR fetch is disabled"); } const basePath = Api.BASE_PATH; - const apiKeyGetter = (headerName: string) => "Authorization".toUpperCase() === headerName.toUpperCase() - ? apiKey : ''; - confCache = new Api.Configuration({fetchApi, basePath, apiKey: apiKeyGetter}) + confCache = new Api.Configuration({ + fetchApi, + basePath, + headers, + }) } return confCache; } @@ -66,6 +69,9 @@ export const getClientAuth = (): Api.AuthNZApiInterface => getClient(Api.AuthNZA export const getClientHealth = (): Api.HealthApiInterface => getClient(Api.HealthApi); /** * Set the API key to be used by the client. Takes effect immediately for existing clients. - * @param newApiKey */ -export const setApiKey = (newApiKey: string) => apiKey = newApiKey +export const setApiKey = (apiKey: string) => headers['Authorization'] = `apikey ${apiKey}`; +/** + * Set the Cognito access token to be used by the client. Takes effect immediately for existing clients. + */ +export const setAccessToken = (accessToken: string) => headers['Authorization'] = `cognito ${accessToken}`; diff --git a/dataspray-site/src/mdx-components.tsx b/dataspray-site/src/mdx-components.tsx new file mode 100644 index 00000000..73c18bb4 --- /dev/null +++ b/dataspray-site/src/mdx-components.tsx @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Matus Faro + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import type {MDXComponents} from 'mdx/types' + +export function useMDXComponents(components: MDXComponents): MDXComponents { + return { + ...components, + } +} \ No newline at end of file diff --git a/dataspray-site/src/pages/docs/test.mdx b/dataspray-site/src/pages/docs/test.mdx new file mode 100644 index 00000000..808ad40b --- /dev/null +++ b/dataspray-site/src/pages/docs/test.mdx @@ -0,0 +1,15 @@ +import { MyComponent } from 'my-components' + +# Welcome to my MDX page! + +This is some **bold** and _italics_ text. + +This is a list in markdown: + +- One +- Two +- Three + +Checkout my React component: + + \ No newline at end of file diff --git a/dataspray-store/src/main/java/io/dataspray/store/ApiAccessStore.java b/dataspray-store/src/main/java/io/dataspray/store/ApiAccessStore.java index c62a2d99..355b4fa5 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/ApiAccessStore.java +++ b/dataspray-store/src/main/java/io/dataspray/store/ApiAccessStore.java @@ -64,7 +64,7 @@ public interface ApiAccessStore { ApiAccess createApiAccessForUser( String organizationName, - String userEmail, + String username, UsageKeyType usageKeyType, Optional> queueWhitelistOpt, Optional expiryOpt); @@ -101,7 +101,7 @@ ApiAccess createApiAccessForTask( void getAllUsageKeys(Consumer> batchConsumer); - Optional getUsageKey(UsageKeyType type, Optional userEmailOpt, ImmutableSet organizationNames); + Optional getUsageKey(UsageKeyType type, Optional usernameOpt, ImmutableSet organizationNames); @Value @AllArgsConstructor @@ -122,9 +122,9 @@ class ApiAccess { @NonNull OwnerType ownerType; - /** For ownerType=USER shows user email. For ownerType=TASK, shows email of user that created task. */ + /** For ownerType=USER shows user's username. For ownerType=TASK, shows username of user that deployed the task. */ @NonNull - String ownerEmail; + String ownerUsername; /** For ownerType=TASK, the task ID */ String ownerTaskId; @@ -148,7 +148,7 @@ public boolean isTtlNotExpired() { public String getPrincipalId() { return switch (ownerType) { - case USER -> ownerEmail; + case USER -> ownerUsername; case TASK -> checkNotNull(ownerTaskId); }; } diff --git a/dataspray-store/src/main/java/io/dataspray/store/CognitoJwtVerifier.java b/dataspray-store/src/main/java/io/dataspray/store/CognitoJwtVerifier.java index 15a36872..c73e24fd 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/CognitoJwtVerifier.java +++ b/dataspray-store/src/main/java/io/dataspray/store/CognitoJwtVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,7 +44,7 @@ public interface CognitoJwtVerifier { class VerifiedCognitoJwt { @Nonnull - String userEmail; + String username; @Nonnull ImmutableSet groupNames; diff --git a/dataspray-store/src/main/java/io/dataspray/store/LambdaDeployer.java b/dataspray-store/src/main/java/io/dataspray/store/LambdaDeployer.java index 7c159406..4cc85816 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/LambdaDeployer.java +++ b/dataspray-store/src/main/java/io/dataspray/store/LambdaDeployer.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,7 +41,7 @@ public interface LambdaDeployer { DeployedVersion deployVersion( String organizationName, - String userEmail, + String username, Optional apiEndpointOpt, String taskId, String codeUrl, diff --git a/dataspray-store/src/main/java/io/dataspray/store/UserStore.java b/dataspray-store/src/main/java/io/dataspray/store/UserStore.java index 4585fff7..32401e29 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/UserStore.java +++ b/dataspray-store/src/main/java/io/dataspray/store/UserStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,13 +36,13 @@ public interface UserStore { - SignUpResponse signup(String email, String password); + SignUpResponse signup(String username, String email, String password, boolean tosAgreed, boolean marketingAgreed); - ConfirmSignUpResponse signupConfirmCode(String email, String code); + ConfirmSignUpResponse signupConfirmCode(String username, String code); - ResendConfirmationCodeResponse signupResendCode(String email); + ResendConfirmationCodeResponse signupResendCode(String username); - AdminInitiateAuthResponse signin(String email, String password); + AdminInitiateAuthResponse signin(String usernameOrEmail, String password); AssociateSoftwareTokenResponse associateSoftwareTokenGivenSession(String session); @@ -52,11 +52,11 @@ public interface UserStore { VerifySoftwareTokenResponse verifySoftwareTokenGivenAccessToken(String accessToken, String friendlyDeviceName, String code); - AdminRespondToAuthChallengeResponse signinChallengeNewPassword(String session, String email, String newPassword); + AdminRespondToAuthChallengeResponse signinChallengeNewPassword(String session, String username, String newPassword); - AdminRespondToAuthChallengeResponse signinChallengeTotpCode(String session, String email, String code); + AdminRespondToAuthChallengeResponse signinChallengeTotpCode(String session, String username, String code); - AdminRespondToAuthChallengeResponse signinChallengeTotpSetup(String session, String email, String verifySoftwareTokenSession); + AdminRespondToAuthChallengeResponse signinChallengeTotpSetup(String session, String username, String verifySoftwareTokenSession); void validateAccessToken(String accessToken); diff --git a/dataspray-store/src/main/java/io/dataspray/store/impl/CognitoUserStore.java b/dataspray-store/src/main/java/io/dataspray/store/impl/CognitoUserStore.java index 1c4c2294..aa3cdfe5 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/impl/CognitoUserStore.java +++ b/dataspray-store/src/main/java/io/dataspray/store/impl/CognitoUserStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,6 +23,7 @@ package io.dataspray.store.impl; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import io.dataspray.store.UserStore; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -35,6 +36,7 @@ import software.amazon.awssdk.services.cognitoidentityprovider.model.AdminRespondToAuthChallengeResponse; import software.amazon.awssdk.services.cognitoidentityprovider.model.AssociateSoftwareTokenRequest; import software.amazon.awssdk.services.cognitoidentityprovider.model.AssociateSoftwareTokenResponse; +import software.amazon.awssdk.services.cognitoidentityprovider.model.AttributeType; import software.amazon.awssdk.services.cognitoidentityprovider.model.AuthFlowType; import software.amazon.awssdk.services.cognitoidentityprovider.model.ChallengeNameType; import software.amazon.awssdk.services.cognitoidentityprovider.model.ConfirmSignUpRequest; @@ -53,6 +55,9 @@ public class CognitoUserStore implements UserStore { public static final String USER_POOL_ID_PROP_NAME = "aws.cognito.user-pool.id"; public static final String USER_POOL_APP_CLIENT_ID_PROP_NAME = "aws.cognito.user-pool.client.id"; private static final String ACCOUNT_STREAM_NAMES_ATTRIBUTE = "streams"; + private static final String USER_ATTRIBUTE_EMAIL = "email"; + private static final String USER_ATTRIBUTE_TOS_AGREED = "custom:tos-agreed"; + private static final String USER_ATTRIBUTE_MARKETING_AGREED = "custom:marketing-agreed"; @ConfigProperty(name = USER_POOL_ID_PROP_NAME) String userPoolId; @@ -69,28 +74,46 @@ public class CognitoUserStore implements UserStore { * href="https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SignUp.html">SignUp */ @Override - public SignUpResponse signup(String email, String password) { + public SignUpResponse signup(String username, String email, String password, boolean tosAgreed, boolean marketingAgreed) { + ImmutableSet.Builder attrsBuilder = ImmutableSet.builder() + .add(AttributeType.builder() + .name(USER_ATTRIBUTE_EMAIL) + .value(email) + .build()); + if (tosAgreed) { + attrsBuilder.add(AttributeType.builder() + .name(USER_ATTRIBUTE_TOS_AGREED) + .value("true") + .build()); + } + if (marketingAgreed) { + attrsBuilder.add(AttributeType.builder() + .name(USER_ATTRIBUTE_MARKETING_AGREED) + .value("true") + .build()); + } return cognitoClient.signUp(SignUpRequest.builder() .clientId(userPoolClientId) .username(email) + .userAttributes(attrsBuilder.build()) .password(password) .build()); } @Override - public ConfirmSignUpResponse signupConfirmCode(String email, String code) { + public ConfirmSignUpResponse signupConfirmCode(String username, String code) { return cognitoClient.confirmSignUp(ConfirmSignUpRequest.builder() .clientId(userPoolClientId) - .username(email) + .username(username) .confirmationCode(code) .build()); } @Override - public ResendConfirmationCodeResponse signupResendCode(String email) { + public ResendConfirmationCodeResponse signupResendCode(String username) { return cognitoClient.resendConfirmationCode(ResendConfirmationCodeRequest.builder() .clientId(userPoolClientId) - .username(email) + .username(username) .build()); } @@ -101,14 +124,19 @@ public ResendConfirmationCodeResponse signupResendCode(String email) { * href="https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html">AdminInitiateAuth */ @Override - public AdminInitiateAuthResponse signin(String email, String password) { + public AdminInitiateAuthResponse signin(String usernameOrEmail, String password) { + ImmutableMap.Builder authParametersBuilder = ImmutableMap.builder() + .put("PASSWORD", password); + if (usernameOrEmail.contains("@")) { + authParametersBuilder.put("EMAIL", usernameOrEmail); + } else { + authParametersBuilder.put("USERNAME", usernameOrEmail); + } return cognitoClient.adminInitiateAuth(AdminInitiateAuthRequest.builder() .authFlow(AuthFlowType.ADMIN_USER_PASSWORD_AUTH) .userPoolId(userPoolId) .clientId(userPoolClientId) - .authParameters(ImmutableMap.of( - "USERNAME", email, - "PASSWORD", password)) + .authParameters(authParametersBuilder.build()) .build()); } @@ -169,23 +197,23 @@ public VerifySoftwareTokenResponse verifySoftwareTokenGivenAccessToken(String ac } @Override - public AdminRespondToAuthChallengeResponse signinChallengeNewPassword(String session, String email, String newPassword) { + public AdminRespondToAuthChallengeResponse signinChallengeNewPassword(String session, String username, String newPassword) { return signinChallenge(session, ChallengeNameType.NEW_PASSWORD_REQUIRED, ImmutableMap.of( - "USERNAME", email, + "USERNAME", username, "NEW_PASSWORD", newPassword)); } @Override - public AdminRespondToAuthChallengeResponse signinChallengeTotpCode(String session, String email, String code) { + public AdminRespondToAuthChallengeResponse signinChallengeTotpCode(String session, String username, String code) { return signinChallenge(session, ChallengeNameType.SOFTWARE_TOKEN_MFA, ImmutableMap.of( - "USERNAME", email, + "USERNAME", username, "SOFTWARE_TOKEN_MFA_CODE", code)); } @Override - public AdminRespondToAuthChallengeResponse signinChallengeTotpSetup(String session, String email, String verifySoftwareTokenSession) { + public AdminRespondToAuthChallengeResponse signinChallengeTotpSetup(String session, String username, String verifySoftwareTokenSession) { return signinChallenge(session, ChallengeNameType.MFA_SETUP, ImmutableMap.of( - "USERNAME", email, + "USERNAME", username, "SESSION", verifySoftwareTokenSession)); } diff --git a/dataspray-store/src/main/java/io/dataspray/store/impl/DynamoApiGatewayApiAccessStore.java b/dataspray-store/src/main/java/io/dataspray/store/impl/DynamoApiGatewayApiAccessStore.java index 2aa153b0..4efdc608 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/impl/DynamoApiGatewayApiAccessStore.java +++ b/dataspray-store/src/main/java/io/dataspray/store/impl/DynamoApiGatewayApiAccessStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -97,12 +97,12 @@ void init() { } @Override - public ApiAccess createApiAccessForUser(String organizationName, String userEmail, UsageKeyType usageKeyType, Optional> queueWhitelistOpt, Optional expiryOpt) { + public ApiAccess createApiAccessForUser(String organizationName, String username, UsageKeyType usageKeyType, Optional> queueWhitelistOpt, Optional expiryOpt) { return createApiAccess(new ApiAccess( keygenUtil.generateSecureApiKey(API_KEY_LENGTH), organizationName, OwnerType.USER, - userEmail, + username, null, null, usageKeyType, @@ -274,17 +274,17 @@ public void getAllUsageKeys(Consumer> batchConsumer) { } @Override - public Optional getUsageKey(UsageKeyType type, Optional userEmailOpt, ImmutableSet organizationNames) { + public Optional getUsageKey(UsageKeyType type, Optional usernameOpt, ImmutableSet organizationNames) { // For organization wide usage key, find the organization name Optional organizationNameOpt = Optional.empty(); if (UsageKeyType.ORGANIZATION.equals(type)) { if (organizationNames.isEmpty()) { type = UsageKeyType.GLOBAL; - log.info("User {} is not part of any organization, falling back to dataspray-wide usage key", userEmailOpt); + log.info("User {} is not part of any organization, falling back to dataspray-wide usage key", usernameOpt); } else if (organizationNames.size() > 1) { organizationNameOpt = Optional.of(organizationNames.stream().sorted().findFirst().get()); - log.info("User {} is part of multiple organizations, using usage key for {} out of {}", userEmailOpt, organizationNameOpt, organizationNames); + log.info("User {} is part of multiple organizations, using usage key for {} out of {}", usernameOpt, organizationNameOpt, organizationNames); } else { // Only part of one organization, use it organizationNameOpt = Optional.of(organizationNames.iterator().next()); diff --git a/dataspray-store/src/main/java/io/dataspray/store/impl/LambdaDeployerImpl.java b/dataspray-store/src/main/java/io/dataspray/store/impl/LambdaDeployerImpl.java index 4468c96c..b4979d3d 100644 --- a/dataspray-store/src/main/java/io/dataspray/store/impl/LambdaDeployerImpl.java +++ b/dataspray-store/src/main/java/io/dataspray/store/impl/LambdaDeployerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -156,7 +156,7 @@ public class LambdaDeployerImpl implements LambdaDeployer { @Override public DeployedVersion deployVersion( String organizationName, - String userEmail, + String username, Optional apiEndpointOpt, String taskId, String codeUrl, @@ -321,7 +321,7 @@ public DeployedVersion deployVersion( ApiAccess apiAccess = apiAccessStore.createApiAccessForTask( apiKey, organizationName, - userEmail, + username, taskId, publishedVersion, ApiAccessStore.UsageKeyType.ORGANIZATION, diff --git a/dataspray-store/src/test/java/io/dataspray/store/ApiAccessStoreTest.java b/dataspray-store/src/test/java/io/dataspray/store/ApiAccessStoreTest.java index e96fd45b..30355d56 100644 --- a/dataspray-store/src/test/java/io/dataspray/store/ApiAccessStoreTest.java +++ b/dataspray-store/src/test/java/io/dataspray/store/ApiAccessStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -74,16 +74,16 @@ public class ApiAccessStoreTest { @Test public void testSet() throws Exception { String organizationName = UUID.randomUUID().toString(); - String userEmail = UUID.randomUUID().toString() + "@example.com"; + String username = UUID.randomUUID().toString(); ApiAccess apiAccess = apiAccessStore.createApiAccessForUser( organizationName, - userEmail, + username, UsageKeyType.UNLIMITED, Optional.empty(), Optional.empty()); assertEquals(organizationName, apiAccess.getOrganizationName()); - assertEquals(userEmail, apiAccess.getOwnerEmail()); + assertEquals(username, apiAccess.getOwnerUsername()); assertEquals(UsageKeyType.UNLIMITED, apiAccess.getUsageKeyType()); assertEquals(Set.of(), apiAccess.getQueueWhitelist()); assertTrue(apiAccess.isTtlNotExpired()); @@ -171,7 +171,7 @@ public void testGetByAccount() throws Exception { ApiAccess apiAccess2 = apiAccessStore.createApiAccessForUser( apiAccess.getOrganizationName(), - apiAccess.getOwnerEmail(), + apiAccess.getOwnerUsername(), UsageKeyType.UNLIMITED, Optional.of(ImmutableSet.of("queue1", "queue2")), Optional.of(Instant.now().plusSeconds(300))); diff --git a/dataspray-stream-client/src/main/openapi/paths-authnz.yaml b/dataspray-stream-client/src/main/openapi/paths-authnz.yaml index afe91a17..8af81843 100644 --- a/dataspray-stream-client/src/main/openapi/paths-authnz.yaml +++ b/dataspray-stream-client/src/main/openapi/paths-authnz.yaml @@ -3,11 +3,14 @@ components: SignUpRequest: type: object required: + - username - email - password - tosAgreed - marketingAgreed properties: + username: + type: string email: type: string password: @@ -28,10 +31,10 @@ components: SignUpConfirmCodeRequest: type: object required: - - email + - username - code properties: - email: + username: type: string code: type: string @@ -39,10 +42,10 @@ components: SignInRequest: type: object required: - - email + - usernameOrEmail - password properties: - email: + usernameOrEmail: type: string password: type: string @@ -80,9 +83,12 @@ components: type: object required: - session + - username properties: session: type: string + username: + type: string ChallengePasswordChange: description: The user has to set a new password type: object @@ -91,14 +97,16 @@ components: properties: session: type: string + username: + type: string SignInChallengeTotpCodeRequest: type: object required: - - email + - username - session - code properties: - email: + username: type: string session: type: string @@ -107,11 +115,11 @@ components: SignInChallengePasswordChangeRequest: type: object required: - - email + - username - session - newPassword properties: - email: + username: type: string session: type: string diff --git a/dataspray-stream-control/src/main/java/io/dataspray/stream/control/AuthNzResource.java b/dataspray-stream-control/src/main/java/io/dataspray/stream/control/AuthNzResource.java index 74275ad1..d1abbe0a 100644 --- a/dataspray-stream-control/src/main/java/io/dataspray/stream/control/AuthNzResource.java +++ b/dataspray-stream-control/src/main/java/io/dataspray/stream/control/AuthNzResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -68,8 +68,6 @@ import java.util.Optional; -import static com.google.common.base.Preconditions.checkState; - @Slf4j @ApplicationScoped public class AuthNzResource extends AbstractResource implements AuthNzApi { @@ -126,7 +124,12 @@ public SignUpResponse signUp(SignUpRequest request) { // Sign up software.amazon.awssdk.services.cognitoidentityprovider.model.SignUpResponse response; try { - response = userStore.signup(request.getEmail(), request.getPassword()); + response = userStore.signup( + request.getUsername(), + request.getEmail(), + request.getPassword(), + request.getTosAgreed(), + request.getMarketingAgreed()); } catch (TooManyRequestsException ex) { throw new ClientErrorException(429, ex); } catch (NotAuthorizedException ex) { @@ -155,7 +158,7 @@ public SignUpResponse signUp(SignUpRequest request) { .build(); } - return signUpConfirmed(request.getEmail()); + return signUpConfirmed(); } @Override @@ -195,13 +198,13 @@ public SignUpResponse signUpConfirmCode(SignUpConfirmCodeRequest request) { .build(); } - return signUpConfirmed(request.getEmail()); + return signUpConfirmed(); } /** * Once a user is confirmed, we can trigger other events here. */ - private SignUpResponse signUpConfirmed(String email) { + private SignUpResponse signUpConfirmed() { return SignUpResponse.builder() .confirmed(true) @@ -212,7 +215,7 @@ private SignUpResponse signUpConfirmed(String email) { public SignInResponse signIn(SignInRequest request) { AdminInitiateAuthResponse response; try { - response = userStore.signin(request.getEmail(), request.getPassword()); + response = userStore.signin(request.getUsernameOrEmail(), request.getPassword()); } catch (NotAuthorizedException ex) { return SignInResponse.builder() .errorMsg("You are not authorized.") @@ -235,10 +238,11 @@ public SignInResponse signIn(SignInRequest request) { } return signinResponseHandleChallengeAndResult( - request.getEmail(), Optional.ofNullable(response.challengeName()), Optional.ofNullable(response.session()), - Optional.ofNullable(response.authenticationResult())); + Optional.ofNullable(response.authenticationResult()), + Optional.ofNullable(response.challengeParameters()) + .flatMap(challengeParameters -> Optional.ofNullable(challengeParameters.get("USER_ID_FOR_SRP")))); } @@ -252,10 +256,11 @@ public SignInResponse signInChallengeTotpCode(SignInChallengeTotpCodeRequest req } return signinResponseHandleChallengeAndResult( - request.getEmail(), Optional.ofNullable(response.challengeName()), Optional.of(response.session()), - Optional.ofNullable(response.authenticationResult())); + Optional.ofNullable(response.authenticationResult()), + Optional.ofNullable(response.challengeParameters()) + .flatMap(challengeParameters -> Optional.ofNullable(challengeParameters.get("USER_ID_FOR_SRP")))); } @Override @@ -264,51 +269,54 @@ public SignInResponse signInChallengePasswordChange(SignInChallengePasswordChang try { response = userStore.signinChallengeNewPassword( request.getSession(), - request.getEmail(), + request.getUsername(), request.getNewPassword()); } catch (TooManyRequestsException ex) { throw new ClientErrorException(429, ex); } return signinResponseHandleChallengeAndResult( - request.getEmail(), Optional.ofNullable(response.challengeName()), Optional.of(response.session()), - Optional.ofNullable(response.authenticationResult())); + Optional.ofNullable(response.authenticationResult()), + Optional.ofNullable(response.challengeParameters()) + .flatMap(challengeParameters -> Optional.ofNullable(challengeParameters.get("USER_ID_FOR_SRP")))); } private SignInResponse signinResponseHandleChallengeAndResult( - String email, Optional challengeNameOpt, Optional sessionOpt, - Optional authenticationResultOpt) { + Optional authenticationResultOpt, + Optional challengeUsernameOpt) { if (challengeNameOpt.isPresent()) { ChallengeNameType challengeName = challengeNameOpt.get(); - checkState(sessionOpt.isPresent(), "Session is expected for challenge response: " + challengeName); - String session = sessionOpt.get(); + String session = sessionOpt.orElseThrow(() -> new IllegalStateException("Session is expected for challenge response: " + challengeName)); + String username = challengeUsernameOpt.orElseThrow(() -> new IllegalStateException("Username is expected for challenge response: " + challengeName)); switch (challengeName) { case SOFTWARE_TOKEN_MFA: return SignInResponse.builder() .challengeTotpCode(ChallengeTotpCode.builder() .session(session) + .username(username) .build()) .build(); case NEW_PASSWORD_REQUIRED: return SignInResponse.builder() .challengePasswordChange(ChallengePasswordChange.builder() .session(session) + .username(username) .build()) .build(); case MFA_SETUP: - log.error("MFA setup is not yet supported as part of sign-in flow. email {}", email); + log.error("MFA setup is not yet supported as part of sign-in flow. username {}", username); return SignInResponse.builder() .errorMsg("MFA setup is not yet supported as part of sign-in flow.") .build(); case SMS_MFA: case SELECT_MFA_TYPE: - log.error("SMS MFA setup is not yet supported. email {}", email); + log.error("SMS MFA setup is not yet supported. username {}", username); return SignInResponse.builder() .errorMsg("SMS MFA not supported yet.") .build(); diff --git a/dataspray-stream-control/src/main/java/io/dataspray/stream/control/ControlResource.java b/dataspray-stream-control/src/main/java/io/dataspray/stream/control/ControlResource.java index f53e2a42..4e70d715 100644 --- a/dataspray-stream-control/src/main/java/io/dataspray/stream/control/ControlResource.java +++ b/dataspray-stream-control/src/main/java/io/dataspray/stream/control/ControlResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -80,7 +80,7 @@ public TaskStatus delete(String organizationName, String taskId) { public TaskVersion deployVersion(String organizationName, String taskId, DeployRequest deployRequest) { DeployedVersion deployedVersion = deployer.deployVersion( organizationName, - getUserEmail().orElseThrow(), + getUsername().orElseThrow(), datasprayApiEndpoint, taskId, deployRequest.getCodeUrl(), diff --git a/dataspray-stream-ingest/src/main/java/io/dataspray/stream/ingest/IngestResource.java b/dataspray-stream-ingest/src/main/java/io/dataspray/stream/ingest/IngestResource.java index 73cd5c41..9582db75 100644 --- a/dataspray-stream-ingest/src/main/java/io/dataspray/stream/ingest/IngestResource.java +++ b/dataspray-stream-ingest/src/main/java/io/dataspray/stream/ingest/IngestResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Matus Faro + * Copyright 2024 Matus Faro * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -69,7 +69,7 @@ public class IngestResource extends AbstractResource implements IngestApi { public void message(String organizationName, String targetName, InputStream messageInputStream) { // Sanity check to see if we are authorized - getUserEmail().orElseThrow(ForbiddenException::new); + getUsername().orElseThrow(ForbiddenException::new); // Fetch target definition Target target = targetStore.getTarget(organizationName, targetName, true)