From 37175e40dae4678ccbf0c43822948ada933d58a0 Mon Sep 17 00:00:00 2001 From: asharonbaltazar <58940073+asharonbaltazar@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:46:11 -0400 Subject: [PATCH 1/5] feat(ui): show 1915(c) Appendix K Package Details for withdrawn children (#671) * chore: move `title` into `PackageDetails` * chore: remove redundant hook cache call * feat: add `appkParent` to withdrawing Appk child * feat: add `wasAppkChild` property to withdrawn children * chore: tidy up types and braces * Revert "feat: add `wasAppkChild` property to withdrawn children" This reverts commit 7de7b5afaa70a7481d4682657af8a13ba290878c. * chore: update `appkParent` title * fix: use correct URL for parent appks in Package Activity * chore: remove unused property --- .../main/transforms/new-submission.ts | 14 ++++--- .../main/transforms/remove-appk-child.ts | 3 +- .../ui/src/features/package/index.tsx | 17 +-------- .../package/package-activity/index.tsx | 8 ++-- .../package/package-details/index.tsx | 38 +++++++++++++------ 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/packages/shared-types/opensearch/main/transforms/new-submission.ts b/src/packages/shared-types/opensearch/main/transforms/new-submission.ts index 7c85bf57ed..cfcea05744 100644 --- a/src/packages/shared-types/opensearch/main/transforms/new-submission.ts +++ b/src/packages/shared-types/opensearch/main/transforms/new-submission.ts @@ -54,9 +54,10 @@ export const transform = (id: string) => { changedDate: getDateStringOrNullFromEpoc(data.changedDate), subject: null, description: null, - makoChangedDate: !!data.timestamp - ? new Date(data.timestamp).toISOString() - : null, + makoChangedDate: + typeof data.timestamp === "number" + ? new Date(data.timestamp).toISOString() + : null, // ---------- }; } else { @@ -72,9 +73,10 @@ export const transform = (id: string) => { submitterName: data.submitterName === "-- --" ? null : data.submitterName, origin: "OneMAC", - makoChangedDate: !!data.timestamp - ? new Date(data.timestamp).toISOString() - : null, + makoChangedDate: + typeof data.timestamp === "number" + ? new Date(data.timestamp).toISOString() + : null, }; } }); diff --git a/src/packages/shared-types/opensearch/main/transforms/remove-appk-child.ts b/src/packages/shared-types/opensearch/main/transforms/remove-appk-child.ts index f71b91dcc7..6556688a92 100644 --- a/src/packages/shared-types/opensearch/main/transforms/remove-appk-child.ts +++ b/src/packages/shared-types/opensearch/main/transforms/remove-appk-child.ts @@ -5,7 +5,8 @@ export const transform = (id: string) => { return { id, appkParentId: null, - makoChangedDate: !!data.timestamp + appkParent: true, + makoChangedDate: data.timestamp ? new Date(data.timestamp).toISOString() : null, }; diff --git a/src/services/ui/src/features/package/index.tsx b/src/services/ui/src/features/package/index.tsx index b85b122777..779990fd0a 100644 --- a/src/services/ui/src/features/package/index.tsx +++ b/src/services/ui/src/features/package/index.tsx @@ -35,21 +35,6 @@ export const DetailsContent: FC<{ id: string }> = ({ id }) => { if (isLoading) return ; if (!data?._source) return ; if (error) return ; - const title = - (() => { - switch (data._source.authority) { - case Authority["1915b"]: - case Authority["1915c"]: - case undefined: // Some TEs have no authority - if (data._source.appkParent) - return "Appendix K Amendment Package Details"; - else if (data._source.actionType == "Extend") - return "Temporary Extension Request Details"; - else return undefined; - default: - return undefined; - } - })() || `${data._source.authority} Package Details`; return (
@@ -61,7 +46,7 @@ export const DetailsContent: FC<{ id: string }> = ({ id }) => {
- +
diff --git a/src/services/ui/src/features/package/package-activity/index.tsx b/src/services/ui/src/features/package/package-activity/index.tsx index a41abd42f4..c07e84ca2f 100644 --- a/src/services/ui/src/features/package/package-activity/index.tsx +++ b/src/services/ui/src/features/package/package-activity/index.tsx @@ -11,8 +11,8 @@ import { import * as Table from "@/components"; import { BLANK_VALUE } from "@/consts"; import { usePackageActivities, useAttachmentService } from "./hook"; -import { Link } from "@/components/Routing"; import { attachmentTitleMap } from "shared-types"; +import { Link } from "react-router-dom"; // id, attachments, hook const AttachmentDetails: FC<{ @@ -54,8 +54,7 @@ export const PA_AppkParentRemovedChild: FC = ( return (
{props.appkChildId} @@ -72,8 +71,7 @@ export const PA_AppkChildRemovedFromParent: FC<

Removed from:

{props.appkParentId} diff --git a/src/services/ui/src/features/package/package-details/index.tsx b/src/services/ui/src/features/package/package-details/index.tsx index 80e5ed1e19..f2d0c99797 100644 --- a/src/services/ui/src/features/package/package-details/index.tsx +++ b/src/services/ui/src/features/package/package-details/index.tsx @@ -6,13 +6,14 @@ import { submissionDetails, } from "./hooks"; -import { FC } from "react"; +import { FC, useMemo } from "react"; import { DetailSectionItem } from "./hooks"; import { useGetUser } from "@/api/useGetUser"; import { AppK } from "./appk"; import { cn } from "@/utils"; -import { usePackageDetailsCache } from ".."; +import { Authority } from "shared-types"; +import { ItemResult } from "shared-types/opensearch/main"; export const DetailItemsGrid: FC<{ displayItems: DetailSectionItem[]; @@ -41,24 +42,39 @@ export const DetailItemsGrid: FC<{ ); }; -export const PackageDetails: FC<{ - title: string; -}> = (props) => { - const { data } = usePackageDetailsCache(); +type PackageDetailsProps = { + itemResult: ItemResult; +}; + +export const PackageDetails = ({ itemResult }: PackageDetailsProps) => { + const title = useMemo(() => { + const { _source: source } = itemResult; + + switch (source.authority) { + case Authority["1915b"]: + case Authority["1915c"]: + case undefined: // Some TEs have no authority + if (source.appkParent) return "1915(c) Appendix K Package Details"; + if (source.actionType == "Extend") + return "Temporary Extension Request Details"; + } + + return `${source.authority} Package Details`; + }, [itemResult]); return ( - +

- +
From e3a68c0d94fe715b9477f1e78d1b8cd7166b4913 Mon Sep 17 00:00:00 2001 From: asharonbaltazar <58940073+asharonbaltazar@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:46:32 -0400 Subject: [PATCH 2/5] feat(ui): update Formal RAI-centric labels (#685) * chore: package details `Formal RAI received` -> `Formal RAI response` * chore: dashboard labels `Formal RAI Received` -> `Formal RAI Response` --- .../src/components/Opensearch/main/Filtering/Drawer/consts.ts | 2 +- src/services/ui/src/features/dashboard/Lists/spas/consts.tsx | 2 +- src/services/ui/src/features/dashboard/Lists/waivers/consts.tsx | 2 +- src/services/ui/src/features/package/package-details/hooks.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/ui/src/components/Opensearch/main/Filtering/Drawer/consts.ts b/src/services/ui/src/components/Opensearch/main/Filtering/Drawer/consts.ts index f6d11295fb..a8b4ae4acb 100644 --- a/src/services/ui/src/components/Opensearch/main/Filtering/Drawer/consts.ts +++ b/src/services/ui/src/components/Opensearch/main/Filtering/Drawer/consts.ts @@ -106,7 +106,7 @@ export const DATE_LATESTPACKAGEACTIVITY: DrawerFilterableGroup = { }; export const DATE_RAIRECEIVED: DrawerFilterableGroup = { - label: "Formal RAI Received", + label: "Formal RAI Response", field: "raiReceivedDate", component: "dateRange", prefix: "must", diff --git a/src/services/ui/src/features/dashboard/Lists/spas/consts.tsx b/src/services/ui/src/features/dashboard/Lists/spas/consts.tsx index 8f907e2640..5e6f2fa7b1 100644 --- a/src/services/ui/src/features/dashboard/Lists/spas/consts.tsx +++ b/src/services/ui/src/features/dashboard/Lists/spas/consts.tsx @@ -149,7 +149,7 @@ export const useSpaTableColumns = (): OsTableColumn[] => { }, { field: "raiReceivedDate", - label: "Formal RAI Received", + label: "Formal RAI Response", transform: (data) => { return data.raiReceivedDate ? formatSeatoolDate(data.raiReceivedDate) diff --git a/src/services/ui/src/features/dashboard/Lists/waivers/consts.tsx b/src/services/ui/src/features/dashboard/Lists/waivers/consts.tsx index 9bb32a2039..bca7d3042c 100644 --- a/src/services/ui/src/features/dashboard/Lists/waivers/consts.tsx +++ b/src/services/ui/src/features/dashboard/Lists/waivers/consts.tsx @@ -165,7 +165,7 @@ export const useWaiverTableColumns = (): OsTableColumn[] => { }, { field: "raiReceivedDate", - label: "Formal RAI Received", + label: "Formal RAI Response", transform: (data) => { return data.raiReceivedDate ? formatSeatoolDate(data.raiReceivedDate) diff --git a/src/services/ui/src/features/package/package-details/hooks.tsx b/src/services/ui/src/features/package/package-details/hooks.tsx index ea9d12898e..d3651570a1 100644 --- a/src/services/ui/src/features/package/package-details/hooks.tsx +++ b/src/services/ui/src/features/package/package-details/hooks.tsx @@ -126,7 +126,7 @@ export const recordDetails = ( canView: () => true, }, { - label: "Formal RAI received", + label: "Formal RAI response", value: data.raiReceivedDate ? formatSeatoolDate(data.raiReceivedDate) : BLANK_VALUE, From 589d4826de56bc0334b23f9345cb018e80c89bef Mon Sep 17 00:00:00 2001 From: "Gavin St. Ours" Date: Wed, 31 Jul 2024 10:59:56 -0400 Subject: [PATCH 3/5] feat(ABP 7): HCD feedback items --- src/services/api/webforms/ABP7/v202401.ts | 39 ++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/services/api/webforms/ABP7/v202401.ts b/src/services/api/webforms/ABP7/v202401.ts index 6383964361..9c554875ac 100644 --- a/src/services/api/webforms/ABP7/v202401.ts +++ b/src/services/api/webforms/ABP7/v202401.ts @@ -11,7 +11,7 @@ export const v202401: FormSchema = { form: [ { description: - "If the target population includes persons under 21, complete the following assurances regarding Early and Periodic Screening, Diagnostic, and Treatment (EPSDT). Otherwise, skip to the Prescription drug coverage assurances below.", + "If the target population includes persons under 21, complete the following assurances regarding Early and Periodic Screening, Diagnostic, and Treatment (EPSDT). Otherwise, skip to the prescription drug coverage assurances below.", descriptionClassName: "font-normal", slots: [ { @@ -36,6 +36,18 @@ export const v202401: FormSchema = { rhf: "Checkbox", name: "epsdt-services", rules: { required: "* Required" }, + dependency: { + conditions: [ + { + name: "abp7_epsdt-assurances_does-abp-include-beneficiaries-under-21", + type: "expectedValue", + expectedValue: "yes", + }, + ], + effect: { + type: "show", + }, + }, props: { options: [ { @@ -57,6 +69,18 @@ export const v202401: FormSchema = { labelClassName: "font-bold", name: "how-will-epsdt-be-provided", rules: { required: "* Required" }, + dependency: { + conditions: [ + { + name: "abp7_epsdt-assurances_does-abp-include-beneficiaries-under-21", + type: "expectedValue", + expectedValue: "yes", + }, + ], + effect: { + type: "show", + }, + }, props: { options: [ { @@ -150,6 +174,19 @@ export const v202401: FormSchema = { "Other information about how ESPDT benefits will be provided to participants under age 21 (optional)", labelClassName: "font-bold", name: "other-info-about-espdt-provided-to-under-21", + dependency: { + conditions: [ + { + name: "abp7_epsdt-assurances_does-abp-include-beneficiaries-under-21", + type: "expectedValue", + expectedValue: "yes", + }, + ], + effect: { + type: "show", + }, + }, + rules: { pattern: { value: /^\S(.*\S)?$/, From 99c77baefbb7e72aa5234854a48d8416b689e676 Mon Sep 17 00:00:00 2001 From: Mike Dial Date: Wed, 31 Jul 2024 12:28:06 -0400 Subject: [PATCH 4/5] security hub finding fixes, and a few typo fixes --- lib/lambda/setupIndex.ts | 2 +- .../cloudwatch-to-s3/index.ts | 27 ++++++---- lib/stacks/data.ts | 54 +++++++++++++++++-- lib/stacks/email.ts | 20 +++++++ 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/lib/lambda/setupIndex.ts b/lib/lambda/setupIndex.ts index 31b66c5a29..4c16f78082 100644 --- a/lib/lambda/setupIndex.ts +++ b/lib/lambda/setupIndex.ts @@ -42,7 +42,7 @@ export const handler: Handler = async (event, __, callback) => { }); await manageIndexResource({ osDomain: event.osDomain, - index: "legacyinsights", + index: `${event.indexNamespace}legacyinsights`, }); } catch (error: any) { response.statusCode = 500; diff --git a/lib/local-constructs/cloudwatch-to-s3/index.ts b/lib/local-constructs/cloudwatch-to-s3/index.ts index 5937df7c23..a35ffa1725 100644 --- a/lib/local-constructs/cloudwatch-to-s3/index.ts +++ b/lib/local-constructs/cloudwatch-to-s3/index.ts @@ -43,17 +43,22 @@ export class CloudWatchToS3 extends Construct { removalPolicy: cdk.RemovalPolicy.DESTROY, }); - this.logBucket.addToResourcePolicy( - new PolicyStatement({ - effect: Effect.DENY, - principals: [new AnyPrincipal()], - actions: ["s3:*"], - resources: [this.logBucket.bucketArn, `${this.logBucket.bucketArn}/*`], - conditions: { - Bool: { "aws:SecureTransport": "false" }, - }, - }), - ); + if (!bucket) { + this.logBucket.addToResourcePolicy( + new PolicyStatement({ + effect: Effect.DENY, + principals: [new AnyPrincipal()], + actions: ["s3:*"], + resources: [ + this.logBucket.bucketArn, + `${this.logBucket.bucketArn}/*`, + ], + conditions: { + Bool: { "aws:SecureTransport": "false" }, + }, + }), + ); + } // Create a Firehose role const firehoseRole = new Role(this, "FirehoseRole", { diff --git a/lib/stacks/data.ts b/lib/stacks/data.ts index 885b8fa782..411dd1f9f0 100644 --- a/lib/stacks/data.ts +++ b/lib/stacks/data.ts @@ -207,7 +207,7 @@ export class Data extends cdk.NestedStack { nodeToNodeEncryptionOptions: { enabled: true }, domainEndpointOptions: { enforceHttps: true, - tlsSecurityPolicy: "Policy-Min-TLS-1-2-2019-07", + tlsSecurityPolicy: "Policy-Min-TLS-1-2-PFS-2023-10", }, cognitoOptions: { enabled: true, @@ -237,6 +237,52 @@ export class Data extends cdk.NestedStack { .slice(0, 3) .map((subnet) => subnet.subnetId), }, + logPublishingOptions: { + AUDIT_LOGS: { + enabled: true, + cloudWatchLogsLogGroupArn: new cdk.aws_logs.LogGroup( + this, + "OpenSearchAuditLogGroup", + { + logGroupName: `/aws/opensearch/${project}-${stage}-audit-logs`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }, + ).logGroupArn, + }, + INDEX_SLOW_LOGS: { + enabled: true, + cloudWatchLogsLogGroupArn: new cdk.aws_logs.LogGroup( + this, + "OpenSearchIndexSlowLogGroup", + { + logGroupName: `/aws/opensearch/${project}-${stage}-index-slow-logs`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }, + ).logGroupArn, + }, + SEARCH_SLOW_LOGS: { + enabled: true, + cloudWatchLogsLogGroupArn: new cdk.aws_logs.LogGroup( + this, + "OpenSearchSearchSlowLogGroup", + { + logGroupName: `/aws/opensearch/${project}-${stage}-search-slow-logs`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }, + ).logGroupArn, + }, + ES_APPLICATION_LOGS: { + enabled: true, + cloudWatchLogsLogGroupArn: new cdk.aws_logs.LogGroup( + this, + "OpenSearchApplicationLogGroup", + { + logGroupName: `/aws/opensearch/${project}-${stage}-application-logs`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }, + ).logGroupArn, + }, + }, }, ); @@ -300,7 +346,7 @@ export class Data extends cdk.NestedStack { securityGroups: [lambdaSecurityGroup], environment: { brokerString, - region: this.region, + region: cdk.Stack.of(this).region, osDomain: `https://${openSearchDomain.attrDomainEndpoint}`, }, bundling: { @@ -321,7 +367,7 @@ export class Data extends cdk.NestedStack { serviceToken: customResourceProvider.serviceToken, properties: { OsDomain: `https://${openSearchDomain.attrDomainEndpoint}`, - IamRoleName: `arn:aws:iam::${this.account}:role/*`, + IamRoleName: `arn:aws:iam::${cdk.Stack.of(this).account}:role/*`, MasterRoleToAssume: openSearchMasterRole.roleArn, OsRoleName: "all_access", }, @@ -506,7 +552,7 @@ export class Data extends cdk.NestedStack { new cdk.aws_iam.PolicyStatement({ actions: ["lambda:InvokeFunction"], resources: [ - `arn:aws:lambda:${this.region}:${this.account}:function:${project}-${stage}-${stack}-*`, + `arn:aws:lambda:${cdk.Stack.of(this).region}:${cdk.Stack.of(this).account}:function:${project}-${stage}-${stack}-*`, ], }), ], diff --git a/lib/stacks/email.ts b/lib/stacks/email.ts index b6d71c3e01..458b8f2563 100644 --- a/lib/stacks/email.ts +++ b/lib/stacks/email.ts @@ -4,6 +4,7 @@ import * as path from "path"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; import { ISubnet } from "aws-cdk-lib/aws-ec2"; import { CfnEventSourceMapping } from "aws-cdk-lib/aws-lambda"; +import * as LC from "local-constructs"; interface EmailServiceStackProps extends cdk.StackProps { project: string; @@ -91,6 +92,25 @@ export class Email extends cdk.NestedStack { removalPolicy: cdk.RemovalPolicy.DESTROY, }); + emailDataBucket.addToResourcePolicy( + new cdk.aws_iam.PolicyStatement({ + effect: cdk.aws_iam.Effect.DENY, + principals: [new cdk.aws_iam.AnyPrincipal()], + actions: ["s3:*"], + resources: [ + emailDataBucket.bucketArn, + `${emailDataBucket.bucketArn}/*`, + ], + conditions: { + Bool: { "aws:SecureTransport": "false" }, + }, + }), + ); + + new LC.EmptyBuckets(this, "EmptyBuckets", { + buckets: [emailDataBucket], + }); + // SES Configuration Set const configurationSet = new cdk.aws_ses.CfnConfigurationSet( this, From 82bc5ddb14cd59f06c9d2dcfaa5a078116672bdc Mon Sep 17 00:00:00 2001 From: Mike Dial Date: Wed, 31 Jul 2024 12:40:13 -0400 Subject: [PATCH 5/5] Fix unit test that needed to be updated for the legacyInsights namespace fix --- lib/lambda/setupIndex.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lambda/setupIndex.test.ts b/lib/lambda/setupIndex.test.ts index 3cf212c889..3647658945 100644 --- a/lib/lambda/setupIndex.test.ts +++ b/lib/lambda/setupIndex.test.ts @@ -49,7 +49,7 @@ describe("handler", () => { ); expect(os.createIndex).toHaveBeenCalledWith( "test-domain", - "legacyinsights", + "test-namespace-legacyinsights", ); expect(os.updateFieldMapping).toHaveBeenCalledTimes(1);