From 40df3bac21a947c4cdda78ed28b02fec2c5db106 Mon Sep 17 00:00:00 2001 From: rstrahan Date: Fri, 29 Mar 2024 19:03:30 +0000 Subject: [PATCH] fix minor regression in mediasearch UI --- CHANGELOG.md | 2 + patches/mediasearch/ResultFooter.tsx | 97 ++++++ patches/mediasearch/msfinder.yaml | 492 +++++++++++++++++++++++++++ publish.sh | 5 + 4 files changed, 596 insertions(+) create mode 100644 patches/mediasearch/ResultFooter.tsx create mode 100644 patches/mediasearch/msfinder.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index a6881254..61a6d67c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +## [0.7.8] - 2024-03-29 - Fix an issue with job status indicator (step function workflow) inserting duplicate entries into DynamoDB. +- Fix regression in the mediasearch finder to re-enable hyperlink to PCA call detail page ## [0.7.7] - 2024-03-06 ### Added diff --git a/patches/mediasearch/ResultFooter.tsx b/patches/mediasearch/ResultFooter.tsx new file mode 100644 index 00000000..3c683455 --- /dev/null +++ b/patches/mediasearch/ResultFooter.tsx @@ -0,0 +1,97 @@ +import React from "react"; +import * as _ from "lodash"; +import Kendra from "aws-sdk/clients/kendra"; + +import { isNullOrUndefined, truncateString } from "../../utils"; +import "../../search.scss"; + +import Feedback from "./Feedback"; +import { Relevance } from "../../constants"; + +const IgnoreFormats = ["PLAIN_TEXT"]; +const MAX_URI_LENGTH = 30; + +interface ResultFooterProps { + queryResultItem: Kendra.QueryResultItem; + attributes: any; + startTime: number; + submitFeedback: ( + relevance: Relevance, + resultItem: Kendra.QueryResultItem + ) => Promise; +} + +export default class ResultFooter extends React.Component< + ResultFooterProps, + {} +> { + private submitClickFeedback = () => { + this.props.submitFeedback(Relevance.Click, this.props.queryResultItem); + }; + + render() { + const { attributes, queryResultItem, submitFeedback, startTime } = this.props; + + const fileFormatName = attributes.FileFormat + ? attributes.FileFormat.StringValue + : undefined; + + let fileFormat; + if ( + !isNullOrUndefined(fileFormatName) && + IgnoreFormats.indexOf(fileFormatName) === -1 + ) { + fileFormat = ( +
+ {fileFormatName.toUpperCase()} +
+
+
+
+ ); + } + let sourceLink; + let isYTVideo = 'ytauthor' in attributes; + + // BobS: Modified to enable link to PCA Call Analysis, using Uri containied in document attribute + // const uri = queryResultItem.DocumentURI; + let uri; + let label; + const pcaCallAnalysisUri = _.get(attributes, "ANALYSIS_URI.StringValue"); + if (pcaCallAnalysisUri) { + uri = pcaCallAnalysisUri; + label = "Open Call Analysis"; + } else { + uri = queryResultItem.DocumentURI; + label = uri; + } + + if (uri && !_.isEmpty(uri)) { + sourceLink = ( +
+ + {truncateString(label!, MAX_URI_LENGTH)} + +
+ ); + } + + return ( +
+
+ {fileFormat} + {sourceLink} +
+ +
+ ); + } +} diff --git a/patches/mediasearch/msfinder.yaml b/patches/mediasearch/msfinder.yaml new file mode 100644 index 00000000..e9987020 --- /dev/null +++ b/patches/mediasearch/msfinder.yaml @@ -0,0 +1,492 @@ +Description: > + MediaSearch Solution - Finder stack (v0.3.4) + +Resources: + ##Create Cognito Userpool for Authentication + UserPool: + Type: 'AWS::Cognito::UserPool' + Properties: + AliasAttributes: + - email + AutoVerifiedAttributes: + - email + UsernameConfiguration: + CaseSensitive: false + AdminCreateUserConfig: + AllowAdminCreateUserOnly: true + InviteMessageTemplate: + EmailMessage: "

Hello {username},\n

Welcome to Finder App! Your temporary password is:\n

{####}
\n

When the CloudFormation stack is COMPLETE, use the MediaSearchFinderURL in the Outputs tab of the CloudFormation stack to login using {username} as username, set your permanent password, and start searching!\n

Good luck!\n" + EmailSubject: "Welcome to Finder Web App" + + Admins: + Type: 'AWS::Cognito::UserPoolGroup' + Condition: EnableAuth + Properties: + GroupName: 'Admins' + UserPoolId: !Ref UserPool + + AdminUser: + Type: 'AWS::Cognito::UserPoolUser' + Condition: EnableAuth + Properties: + DesiredDeliveryMediums: + - EMAIL + UserAttributes: + - Name: 'email' + Value: !Ref AdminEmail + Username: 'Admin' + UserPoolId: !Ref UserPool + + AdminToAdmins: + Type: 'AWS::Cognito::UserPoolUserToGroupAttachment' + Condition: EnableAuth + Properties: + GroupName: !Ref Admins + Username: !Ref AdminUser + UserPoolId: !Ref UserPool + + ##Create Cognito IdentityPool for Authorization and associate the UserPool client with it + IdentityPool: + Type: 'AWS::Cognito::IdentityPool' + Properties: + AllowClassicFlow: false + AllowUnauthenticatedIdentities: true + CognitoIdentityProviders: + - ClientId: !Ref UserPoolClient + ProviderName: !Sub + - 'cognito-idp.${region}.amazonaws.com/${client}' + - region: !Ref 'AWS::Region' + client: !Ref UserPool + + UserPoolClient: + Type: 'AWS::Cognito::UserPoolClient' + Properties: + UserPoolId: !Ref UserPool + + ##Attach Auth/UnAuth roles for to ID Pool + IdentityPoolRoleAttachment: + Type: 'AWS::Cognito::IdentityPoolRoleAttachment' + Properties: + IdentityPoolId: !Ref IdentityPool + Roles: + 'authenticated': !GetAtt IDPoolAuthRole.Arn + 'unauthenticated': !GetAtt IDPoolUnauthRole.Arn + + ##Role to be used as Media role for the Identity Pool + IDPoolAuthRole: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Federated: cognito-identity.amazonaws.com + Action: 'sts:AssumeRoleWithWebIdentity' + Condition: + StringEquals: + 'cognito-identity.amazonaws.com:aud': !Ref IdentityPool + 'ForAnyValue:StringLike': + 'cognito-identity.amazonaws.com:amr': authenticated + - Effect: Allow + Principal: + Service: amplify.amazonaws.com + Action: sts:AssumeRole + + ##Role to be used as Unauth role for the Identity Pool + IDPoolUnauthRole: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Federated: cognito-identity.amazonaws.com + Action: 'sts:AssumeRoleWithWebIdentity' + Condition: + StringEquals: + 'cognito-identity.amazonaws.com:aud': !Ref IdentityPool + 'ForAnyValue:StringLike': + 'cognito-identity.amazonaws.com:amr': unauthenticated + - Effect: Allow + Principal: + Service: amplify.amazonaws.com + Action: sts:AssumeRole + + ## Role to be used by the repository + MediaRepositoryAssumeRole: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Federated: cognito-identity.amazonaws.com + Action: 'sts:AssumeRoleWithWebIdentity' + Condition: + StringEquals: + 'cognito-identity.amazonaws.com:aud': !Ref IdentityPool + 'ForAnyValue:StringLike': + 'cognito-identity.amazonaws.com:amr': authenticated + - Effect: Allow + Principal: + Service: amplify.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: + - !GetAtt + - PCAMediaSearchFinderRepository + - Arn + Action: + - 'codecommit:GitPull' + PolicyName: MediaRepositoryExecutionPolicy + + ##The role to be assumed by the application using sts_assume_role + MediaAppCredsRole: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Sid: '' + Effect: Allow + Principal: + Federated: cognito-identity.amazonaws.com + Action: 'sts:AssumeRoleWithWebIdentity' + Condition: + StringEquals: + 'cognito-identity.amazonaws.com:aud': !Ref IdentityPool + 'ForAnyValue:StringLike': + 'cognito-identity.amazonaws.com:amr': authenticated + - Effect: Allow + Principal: + Service: amplify.amazonaws.com + Action: sts:AssumeRole + - Effect: Allow + Principal: + AWS: + - !GetAtt IDPoolAuthRole.Arn + - !Join + - '' + - - 'arn:aws:sts::' + - !Ref 'AWS::AccountId' + - ':assumed-role/' + - !Ref IDPoolAuthRole + - '/CognitoIdentityCredentials' + - !GetAtt IDPoolAuthRole.Arn + - !Join + - '' + - - 'arn:aws:sts::' + - !Ref 'AWS::AccountId' + - ':assumed-role/' + - !Ref IDPoolUnauthRole + - '/CognitoIdentityCredentials' + Action: 'sts:AssumeRole' + Policies: + - PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: !Sub + - 'arn:aws:kendra:${region}:${account}:index/${index}' + - region: !Ref 'AWS::Region' + account: !Ref 'AWS::AccountId' + index: !Ref KendraIndexId + Action: + - 'kendra:DescribeIndex' + - 'kendra:SubmitFeedback' + - 'kendra:ListDataSources' + - 'kendra:Query' + - Effect: Allow + Resource: !Split + - ',' + - !Sub + - 'arn:aws:s3:::${inner}/*' + - inner: !Join + - '/*,arn:aws:s3:::' + - !Ref MediaBucketNames + Action: + - 's3:GetObject' + PolicyName: AWSMediaAppCredsPolicy + + ##Create CodeCommit Repository for the code of the application + PCAMediaSearchFinderRepository: + Type: 'AWS::CodeCommit::Repository' + Properties: + Code: + BranchName: main + S3: + Bucket: '' + Key: !Join + - '' + - - '' + - '' + RepositoryName: !Join + - '' + - - !Ref 'AWS::StackName' + - '-PCAMediaSearchFinderRepository' + + ##Create an App for our application in the Amplify Console + AmplifyApp: + Type: 'AWS::Amplify::App' + Properties: + BuildSpec: |- + version: 1 + frontend: + phases: + preBuild: + commands: + - npm install + build: + commands: + - npm run build + - REACT_APP_INDEX_ID=$REACT_APP_INDEX_ID + - REACT_APP_REGION=$REACT_APP_REGION + - REACT_APP_PROJECT_REGION=$REACT_APP_PROJECT_REGION + - REACT_APP_IDENTITY_POOL_ID=$REACT_APP_IDENTITY_POOL_ID + - REACT_APP_COGNITO_REGION=$REACT_APP_COGNITO_REGION + - REACT_APP_USER_POOL_ID=$REACT_APP_USER_POOL_ID + - REACT_APP_WEB_CLIENT_ID=$REACT_APP_WEB_CLIENT_ID + - REACT_APP_ROLE_ARN=$REACT_APP_ROLE_ARN + artifacts: + baseDirectory: build + files: + - '**/*' + cache: + paths: + - node_modules/**/* + EnvironmentVariables: + - Name: REACT_APP_COGNITO_REGION + Value: !Ref 'AWS::Region' + - Name: REACT_APP_IDENTITY_POOL_ID + Value: !Ref IdentityPool + - Name: REACT_APP_INDEX_ID + Value: !Ref KendraIndexId + - Name: REACT_APP_PROJECT_REGION + Value: !Ref 'AWS::Region' + - Name: REACT_APP_REGION + Value: !Ref 'AWS::Region' + - Name: REACT_APP_USER_POOL_ID + Value: !Ref UserPool + - Name: REACT_APP_WEB_CLIENT_ID + Value: !Ref UserPoolClient + - Name: REACT_APP_ROLE_ARN + Value: !GetAtt MediaAppCredsRole.Arn + - Name: REACT_APP_ENABLE_AUTH + Value: !If [EnableAuth, 'true', 'false'] + - Name: REACT_APP_ENABLE_GUEST + Value: !Ref EnableGuestUser + - Name: REACT_APP_ENABLE_ACCESSTOKENS + Value: !Ref EnableAccessTokens + IAMServiceRole: !GetAtt MediaRepositoryAssumeRole.Arn + Name: !Join + - '' + - - !Ref 'AWS::StackName' + - '-App' + Repository: !GetAtt + - PCAMediaSearchFinderRepository + - CloneUrlHttp + ##Create a branch for the App to be built + AmplifyBranch: + Type: 'AWS::Amplify::Branch' + Properties: + AppId: !GetAtt + - AmplifyApp + - AppId + EnableAutoBuild: true + BranchName: main + + MediaLambdaRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + Policies: + - PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: '*' + Action: + - 'amplify:*' + PolicyName: MediaLambdaPolicy + + BuildTriggerLambda: + Type: AWS::Lambda::Function + Properties: + Handler: lambda_function.lambda_handler + Runtime: python3.8 + Role: !GetAtt 'MediaLambdaRole.Arn' + Timeout: 300 + Code: ../lambda/build-trigger + Environment: + Variables: + APP_ID: !GetAtt AmplifyApp.AppId + + BuildTrigger: + Type: Custom::BuildTrigger + DependsOn: + - AmplifyApp + - AmplifyBranch + - MediaAppCredsRole + Properties: + ServiceToken: !GetAtt BuildTriggerLambda.Arn + Param1: '' + Param2: '' + Param3: !Ref KendraIndexId + Param4: !Ref MediaBucketNames + Param5: !Ref EnableAccessTokens + Param6: !Ref EnableGuestUser + Param7: !Ref AdminEmail + + TokenEnablerLambdaRole: + Type: AWS::IAM::Role + Condition: EnableAccess + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + Policies: + - PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: !Sub + - 'arn:aws:kendra:${region}:${account}:index/${index}*' + - region: !Ref 'AWS::Region' + account: !Ref 'AWS::AccountId' + index: !Ref KendraIndexId + Action: + - 'kendra:*' + PolicyName: TokenEnablerLambdaPolicy + + TokenEnablerLambda: + Type: AWS::Lambda::Function + Condition: EnableAccess + Properties: + Handler: lambda_function.lambda_handler + Runtime: python3.8 + Role: !GetAtt 'TokenEnablerLambdaRole.Arn' + Timeout: 900 + MemorySize: 1024 + Code: ../lambda/token-enabler + Environment: + Variables: + INDEX_ID: !Ref KendraIndexId + SIGNING_KEY_URL: !Join + - '' + - - 'https://cognito-idp.' + - !Ref 'AWS::Region' + - '.amazonaws.com/' + - !Ref UserPool + - '/.well-known/jwks.json' + + TokenEnabler: + Type: Custom::TokenEnabler + Condition: EnableAccess + DependsOn: + - AmplifyApp + Properties: + ServiceToken: !GetAtt TokenEnablerLambda.Arn + Param1: '' + Param2: '' + Param3: !Ref KendraIndexId + Param4: !Join + - '' + - - 'https://cognito-idp.' + - !Ref 'AWS::Region' + - '.amazonaws.com/' + - !Ref UserPool + - '/.well-known/jwks.json' + +Parameters: + KendraIndexId: + Type: String + AllowedPattern : ".+" + ConstraintDescription: "Kendra Index id cannot be blank" + MediaBucketNames: + Type: CommaDelimitedList + Default: "" + Description: >- + (Required) A comma-delimited list of media bucket names - may include wildcards. (Fetch this value from the CFN output for the corresponding Indexer). Needed to support presigned URLs used to access media files contained in search results. + AdminEmail: + Type: String + Description: 'To enable authentication please provide a valid email address for the admin user. This email address will be used for setting the admin password. This email will receive the temporary password for the admin user.' + AllowedPattern: "(^$|^.+\\@.+\\..+)" + Default: '' + ConstraintDescription: 'Must be valid email address eg. johndoe@example.com' + EnableGuestUser: + Type: String + Default: 'false' + AllowedValues: ['true', 'false'] + Description: 'Set true to enable using the search application without logging in' + EnableAccessTokens: + Type: String + Default: 'false' + AllowedValues: ['true', 'false'] + Description: 'Set true to enable use of Cognito user pool access tokens in the Kendra index' + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Kendra search webapp parameters + Parameters: + - KendraIndexId + - MediaBucketNames + - Label: + default: Authentication and access control parameters + Parameters: + - AdminEmail + - EnableGuestUser + - EnableAccessTokens + +Conditions: + EnableAuth: !Not + - !Equals + - !Ref AdminEmail + - '' + EnableAccess: !Equals + - !Ref EnableAccessTokens + - 'true' + +Outputs: + MediaSearchFinderURL: + Value: !Join + - '' + - - 'https://main.' + - !GetAtt AmplifyApp.DefaultDomain + + CognitoUserPool: + Value: !Ref UserPool + + CognitoSigningKeyURL: + Value: !Join + - '' + - - 'https://cognito-idp.' + - !Ref 'AWS::Region' + - '.amazonaws.com/' + - !Ref UserPool + - '/.well-known/jwks.json' \ No newline at end of file diff --git a/publish.sh b/publish.sh index 53d30bf6..630ed230 100755 --- a/publish.sh +++ b/publish.sh @@ -84,6 +84,11 @@ popd echo "Initialize and update git submodules" git submodule init git submodule update +echo "Applying patch files to enable link to PCA Call Analysis" +# force new codecommit repo to be created during upgrade +cp -v ./patches/mediasearch/msfinder.yaml submodule-mediasearch/cfn-templates/msfinder.yaml +# add PCA call detail link to results page +cp -v ./patches/mediasearch/ResultFooter.tsx submodule-mediasearch/finderapp/src/search/resultsPanel/components/ResultFooter.tsx pushd submodule-mediasearch if $PUBLIC; then echo "Enabling ACLs on bucket"