├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── general_question.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── NOTICE.txt ├── README.md └── source ├── .eslintignore ├── .eslintrc.js ├── .npmcheckrc ├── .prettierrc ├── .versionrc ├── LicenseHeader.txt ├── architecture └── apo-architecture.png ├── bin └── blueprint-service-infra.ts ├── blueprint-infrastructure ├── .eslintignore ├── .eslintrc.js ├── .npmcheckrc ├── .npmignore ├── .prettierrc ├── LicenseHeader.txt ├── bin │ └── blueprint-infrastructure.ts ├── cdk.json ├── jest.config.js ├── jest.setup.js ├── lambda │ ├── codepipeline │ │ ├── blueprint │ │ │ ├── common.ts │ │ │ ├── publish.ts │ │ │ └── register.ts │ │ └── types │ │ │ └── BlueprintTypes.ts │ ├── common │ │ ├── common-types.ts │ │ ├── logger-factory.ts │ │ └── logger-type.ts │ └── github │ │ └── createWebhook.ts ├── lib │ ├── blueprint-infrastructure-stack.ts │ ├── blueprint-infrastructure-types.ts │ ├── blueprint-publication-pipeline-construct.ts │ ├── buildspecs.ts │ └── cfn-nag-suppression.ts ├── package-lock.json ├── package.json ├── test │ └── unit │ │ ├── codepipeline │ │ └── blueprint │ │ │ ├── common.test.ts │ │ │ ├── publish.test.ts │ │ │ └── register.test.ts │ │ └── github │ │ └── createWebhook.test.ts └── tsconfig.json ├── blueprint-ui ├── .eslintignore ├── .eslintrc.js ├── .prettierrc ├── LicenseHeader.txt ├── __mocks__ │ └── react-use-localstorage.ts ├── jest.config.js ├── jest │ ├── jest.setup.ts │ └── resolver.ts ├── package.json ├── public │ ├── index.html │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.tsx │ ├── AppLayout │ │ └── index.tsx │ ├── amplify-config.ts │ ├── components │ │ ├── containers │ │ │ ├── Attributes │ │ │ │ ├── DeleteConfirmationModal │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Detail │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Form │ │ │ │ │ ├── components │ │ │ │ │ │ └── Review │ │ │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── Table │ │ │ │ │ ├── MetaData │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ ├── BlueprintArtifact │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── BlueprintVersion │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ └── Patterns │ │ │ │ └── Form │ │ │ │ ├── components │ │ │ │ └── Review │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ ├── core │ │ │ ├── AppContext │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── Authenticate │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── HasPermission │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── PageError │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── PageLoading │ │ │ │ └── index.tsx │ │ │ └── QueryContainerTemplate │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ ├── pages │ │ │ ├── Artifact │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ ├── Attributes │ │ │ │ ├── Create │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Detail │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── List │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── Update │ │ │ │ │ ├── index.test.tsx │ │ │ │ │ └── index.tsx │ │ │ ├── InfrastructureStatus │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ └── Patterns │ │ │ │ ├── Create │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ │ ├── Detail │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ │ ├── List │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ │ └── Update │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ ├── queries │ │ │ ├── GetAllAttributesQuery.test.ts │ │ │ ├── GetAllAttributesQuery.ts │ │ │ ├── GetAllPatternsQuery.test.ts │ │ │ ├── GetAllPatternsQuery.ts │ │ │ ├── GetArtifactDetailsQuery.test.ts │ │ │ ├── GetArtifactDetailsQuery.ts │ │ │ ├── GetAttributeDetailsQuery.test.ts │ │ │ ├── GetAttributeDetailsQuery.ts │ │ │ ├── GetPatternDetailsQuery.test.ts │ │ │ ├── GetPatternDetailsQuery.ts │ │ │ ├── GetSubscriptionQuery.test.ts │ │ │ ├── GetSubscriptionQuery.ts │ │ │ ├── Mutation.tsx │ │ │ └── auth.tsx │ │ ├── routes.ts │ │ └── types │ │ │ └── index.ts │ ├── index.css │ ├── index.tsx │ ├── reportWebVitals.ts │ ├── services │ │ └── EnvConfig.ts │ ├── setupTests.ts │ └── utils │ │ └── helpers.ts ├── tsconfig.json └── yarn.lock ├── cdk.json ├── cypress.config.ts ├── cypress ├── README.md ├── e2e │ ├── attribute │ │ ├── attribute-create-update-delete.cy.js │ │ └── attribute-form-validation.cy.js │ ├── pattern-cdk │ │ └── pattern-cdk-create-update-publish.cy.js │ ├── pattern-cfn │ │ └── pattern-cfn-create-update-publish.cy.js │ └── pattern-form-validation │ │ └── pattern-form-validation.cy.js ├── fixtures │ ├── templaterepo │ │ ├── cdk │ │ │ └── packages │ │ │ │ ├── cdk-test-app │ │ │ │ └── bin │ │ │ │ │ └── cdk-test-app.ts │ │ │ │ ├── compliant-dynamodb-table │ │ │ │ ├── README.md │ │ │ │ ├── lib │ │ │ │ │ ├── compliant-dynamodb-table.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── package.json │ │ │ │ └── tsconfig.json │ │ │ │ └── compliant-s3-bucket │ │ │ │ ├── README.md │ │ │ │ ├── lib │ │ │ │ ├── compliant-s3-bucket.ts │ │ │ │ └── index.ts │ │ │ │ ├── package.json │ │ │ │ └── tsconfig.json │ │ └── cfn │ │ │ └── packages │ │ │ └── dynamodb │ │ │ ├── package.json │ │ │ └── template │ │ │ └── dynamodb.template │ └── testdata.json └── support │ ├── commands.js │ └── e2e.ts ├── jest.config.js ├── lambda └── blueprintgovernanceservice │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .npmcheckrc │ ├── .prettierrc │ ├── API.md │ ├── LicenseHeader.txt │ ├── __mocks__ │ └── @aws-sdk │ │ └── client-ses.ts │ ├── buildspec.yml │ ├── env.json │ ├── events │ ├── event-get-all-items.json │ ├── event-get-by-id.json │ └── event-post-item.json │ ├── initialRepoTemplates │ ├── cdk │ │ ├── .gitignore │ │ ├── images │ │ │ └── .gitkeep │ │ ├── lerna.json │ │ ├── package.json │ │ └── packages │ │ │ └── cdk-test-app │ │ │ ├── .npmignore │ │ │ ├── bin │ │ │ └── cdk-test-app.ts │ │ │ ├── cdk.json │ │ │ ├── package.json │ │ │ └── tsconfig.json │ └── cfn │ │ ├── .gitignore │ │ ├── images │ │ └── .gitkeep │ │ ├── lerna.json │ │ ├── package.json │ │ └── packages │ │ └── .gitkeep │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── App.ts │ ├── Container.ts │ ├── appregistry-updater │ │ ├── AppRegistryUpdateHandler.ts │ │ └── MainHandler.ts │ ├── codecommit │ │ └── trigger-security-scan.ts │ ├── common │ │ ├── AppRegistrySyncRequestQueue.ts │ │ ├── AsyncRequestHandler.ts │ │ ├── Attribute.ts │ │ ├── AttributeBaseHandler.ts │ │ ├── BaseContainer.ts │ │ ├── BlueprintError.ts │ │ ├── MainHandler.ts │ │ ├── ServerlessResponse.ts │ │ ├── Utils.ts │ │ ├── Xray.ts │ │ ├── common-types.ts │ │ ├── configuration │ │ │ └── AppConfiguration.ts │ │ ├── customUserAgent.ts │ │ ├── logging │ │ │ ├── context-logging-middleware.ts │ │ │ ├── index.ts │ │ │ ├── logger-factory.ts │ │ │ └── logger-type.ts │ │ ├── metrics │ │ │ └── operational-metric.ts │ │ ├── middleware-chain.ts │ │ ├── providers │ │ │ └── DependencyConfigurationProvider.ts │ │ ├── response-formatter.ts │ │ ├── router │ │ │ ├── RouteData.ts │ │ │ └── Router.ts │ │ └── validator │ │ │ ├── AttributePayloadValidator.ts │ │ │ └── ValidatorCommon.ts │ ├── email-sender │ │ └── index.ts │ ├── handlers │ │ ├── AttributeCreateHandler.ts │ │ ├── AttributeDeleteHandler.ts │ │ ├── AttributeGetDetailsHandler.ts │ │ ├── AttributeListHandler.ts │ │ ├── AttributeUpdateHandler.ts │ │ ├── CreateBlueprintRequestHandler.ts │ │ ├── GetAllBlueprintsRequestHandler.ts │ │ ├── GetBlueprintInfoHandler.ts │ │ ├── GetSubscriptionHandler.ts │ │ ├── InitialiseBlueprintPipelineHandler.ts │ │ ├── SubscribeHandler.ts │ │ ├── UpdateBlueprintInfraStatusHandler.ts │ │ └── UpdateBlueprintMetaInfoHandler.ts │ ├── metrics │ │ └── OperationalMetricHandler.ts │ ├── service │ │ ├── AppRegistryIntegrationService.ts │ │ ├── BlueprintDBService.ts │ │ ├── BlueprintPipelineBuilderService.ts │ │ ├── Id.ts │ │ └── blueprint-repo-builder │ │ │ ├── BlueprintCodeCommitRepoBuilderService.ts │ │ │ ├── BlueprintGitHubRepoBuilderService.ts │ │ │ └── IBlueprintRepoBuilderService.ts │ ├── timed-synchroniser │ │ ├── MainHandler.ts │ │ └── SyncEventHandler.ts │ └── types │ │ └── BlueprintType.ts │ ├── test │ └── unit │ │ ├── App.test.ts │ │ ├── Container.test.ts │ │ ├── appregistry-updater │ │ ├── AppRegistryUpdateHandler.test.ts │ │ └── MainHandler.test.ts │ │ ├── codecommit │ │ └── trigger-security-scan.test.ts │ │ ├── common │ │ ├── AppRegistrySyncRequestQueue.test.ts │ │ ├── Attribute.test.ts │ │ ├── ContextLoggingMiddleware.test.ts │ │ ├── LoggerFactory.test.ts │ │ ├── common-types.test.ts │ │ ├── providers │ │ │ └── DependencyConfigurationProvider.test.ts │ │ ├── response-formatter.test.ts │ │ └── winston.ts │ │ ├── configuration │ │ └── AppConfiguration.test.ts │ │ ├── email-sender │ │ └── index.test.ts │ │ ├── handlers │ │ ├── AttributeCreateHandler.test.ts │ │ ├── AttributeDeleteHandler.test.ts │ │ ├── AttributeGetDetailHandler.test.ts │ │ ├── AttributeListHandler.test.ts │ │ ├── AttributeUpdateHandler.test.ts │ │ ├── CreateBlueprintRequestHandler.test.ts │ │ ├── GetAllBlueprintsRequestHandler.test.ts │ │ ├── GetBlueprintInfoHandler.test.ts │ │ ├── GetSubscriptionHandler.test.ts │ │ ├── InitialiseBlueprintPipelineHandler.test.ts │ │ ├── SubscribeHandler.test.ts │ │ ├── UpdateBlueprintInfraStatusHandler.test.ts │ │ └── UpdateBlueprintMetaInfoHandler.test.ts │ │ ├── services │ │ ├── AppRegistryIntegrationService.test.ts │ │ ├── BlueprintDBService.test.ts │ │ ├── BlueprintPipelineBuilderService.test.ts │ │ ├── Id.test.ts │ │ └── blueprint-repo-builder │ │ │ ├── BlueprintCodeCommitRepoBuilderService.test.ts │ │ │ └── BlueprintGitHubRepoBuilderService.test.ts │ │ ├── stubs │ │ └── githubResponseStub.ts │ │ └── timed-synchroniser │ │ ├── MainHandler.test.ts │ │ └── SyncEventHandler.test.ts │ ├── tsconfig.json │ └── webpack.config.js ├── lib ├── app-registry-aspect.ts ├── blueprint-api-definition.ts ├── blueprint-artifact-api-definition.ts ├── blueprint-authentication.ts ├── blueprint-backend.ts ├── blueprint-base-infra.ts ├── blueprint-dashboard.ts ├── blueprint-environment.ts ├── blueprint-frontend-config.ts ├── blueprint-frontend.ts ├── blueprint-infrastructure-setup-construct.ts ├── blueprint-notification.ts ├── blueprint-portal-service.ts ├── blueprint-stack.ts ├── blueprint-types.ts ├── cfn-nag-suppression.ts ├── constants.ts ├── infra-utils │ ├── ags-synthetics-canary.ts │ ├── aws-lambda-function.ts │ ├── aws-rest-api.ts │ ├── aws-secure-bucket.ts │ ├── aws-service-dashboard.ts │ ├── aws-waf-web-acl.ts │ └── zip-bundle.ts └── operational-metrics-construct.ts ├── package-lock.json ├── package.json ├── run-all-tests.sh └── tsconfig.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | 11 | 12 | 13 | **To Reproduce** 14 | 15 | 16 | 17 | **Expected behavior** 18 | 19 | 20 | 21 | **Please complete the following information about the solution:** 22 | 23 | - [ ] Version: [e.g. v1.0.0] 24 | - [ ] Region: [e.g. us-east-1] 25 | - [ ] Was the solution modified from the version published on this repository? 26 | - [ ] If the answer to the previous question was yes, are the changes available on GitHub? 27 | - [ ] Have you checked your [service quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) for the sevices this solution uses? 28 | - [ ] Were there any errors in the CloudWatch Logs? 29 | 30 | **Screenshots** 31 | 32 | 33 | 34 | **Additional context** 35 | 36 | 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this solution 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | 11 | 12 | 13 | **Describe the feature you'd like** 14 | 15 | 16 | 17 | **Additional context** 18 | 19 | 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general_question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General question 3 | about: Ask a general question 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | --- 8 | 9 | **What is your question?** 10 | 11 | 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Issue #, if available:** 2 | 3 | 4 | 5 | **Description of changes:** 6 | 7 | 8 | 9 | **Checklist** 10 | 11 | - [ ] :wave: I have run the unit tests, and all unit tests have passed. 12 | - [ ] :warning: This pull request might incur a breaking change. 13 | 14 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | cdk.out 3 | /node_modules 4 | *.d.ts 5 | **/.vscode/ 6 | **/coverage-reports/* 7 | **/test_report.xml 8 | .aws-sam/ 9 | dist 10 | **/build 11 | .DS_Store -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.2.0] - 2023-08-08 4 | 5 | ### Added 6 | 7 | - Integrated CfnGuard and Checkov as additional IaC scanning tools for pattern validation. 8 | - Added user role based access to the solution UI 9 | 10 | ### Fixed 11 | 12 | - Pull request comments max size issue. 13 | 14 | ## [1.1.0] - 2023-05-03 15 | 16 | ### Added 17 | 18 | - AWS CodeCommit support for application patterns repository 19 | - Support for Node.js version 18 20 | 21 | ### Fixed 22 | 23 | - Updated the code to accommodate the new AWS S3 default security setting of disabling the ACL. 24 | 25 | ## [1.0.1] - 2023-01-19 26 | 27 | ### Fixed 28 | 29 | - Fixed OneClick deployment script and html5 vulnerability 30 | 31 | ## [1.0.0] - 2022-09-19 32 | 33 | ### Added 34 | 35 | - All files, initial version 36 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /source/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | cdk.out 4 | lambda 5 | blueprint-infrastructure 6 | blueprint-ui 7 | -------------------------------------------------------------------------------- /source/.npmcheckrc: -------------------------------------------------------------------------------- 1 | { 2 | "depcheck": { 3 | "ignoreMatches": [ 4 | "@typescript-eslint/eslint-plugin", 5 | "@types/jest", 6 | "@typescript-eslint/parser", 7 | "eslint-config-prettier", 8 | "eslint-config-typescript", 9 | "eslint-plugin-header", 10 | "eslint-plugin-prettier", 11 | "prettier", 12 | "esbuild", 13 | "webpack-cli", 14 | "encoding" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "printWidth": 90, 4 | "semi": true, 5 | "singleQuote": true, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /source/.versionrc: -------------------------------------------------------------------------------- 1 | { 2 | "bumpFiles": [ 3 | { 4 | "filename": "package.json", 5 | "type": "json" 6 | }, 7 | { 8 | "filename": "package-lock.json", 9 | "type": "json" 10 | }, 11 | { 12 | "filename": "lambda/blueprintgovernanceservice/package.json", 13 | "type": "json" 14 | }, 15 | { 16 | "filename": "lambda/blueprintgovernanceservice/package-lock.json", 17 | "type": "json" 18 | }, 19 | { 20 | "filename": "blueprint-infrastructure/package.json", 21 | "type": "json" 22 | }, 23 | { 24 | "filename": "blueprint-infrastructure/package-lock.json", 25 | "type": "json" 26 | } 27 | ], 28 | "types": [ 29 | { 30 | "type": "feat", 31 | "section": "Features" 32 | }, 33 | { 34 | "type": "fix", 35 | "section": "Bug Fixes" 36 | }, 37 | { 38 | "type": "test", 39 | "section": "Tests", 40 | "hidden": true 41 | }, 42 | { 43 | "type": "build", 44 | "section": "Build System", 45 | "hidden": true 46 | }, 47 | { 48 | "type": "ci", 49 | "hidden": true 50 | }, 51 | { 52 | "type": "chore", 53 | "hidden": true 54 | }, 55 | { 56 | "type": "doc", 57 | "hidden": true 58 | } 59 | ], 60 | "commitUrlFormat": "{{hash}}", 61 | "compareUrlFormat": "Changes between tag {{previousTag}} and tag {{currentTag}}", 62 | "infile": "../CHANGELOG.md", 63 | "header": "# AWS Blueprint Governance Solution Release Changelog", 64 | "releaseCommitMessageFormat": "Release AWS Blueprint Governance Solution {{currentTag}}" 65 | } 66 | -------------------------------------------------------------------------------- /source/LicenseHeader.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /source/architecture/apo-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-solutions/application-pattern-orchestrator-on-aws/d762bc7c24ca12630fefbc336132398bbaec1cdb/source/architecture/apo-architecture.png -------------------------------------------------------------------------------- /source/blueprint-infrastructure/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/.npmcheckrc: -------------------------------------------------------------------------------- 1 | { 2 | "depcheck": { 3 | "ignoreMatches": [ 4 | "@typescript-eslint/eslint-plugin", 5 | "@types/jest", 6 | "@typescript-eslint/parser", 7 | "eslint-config-prettier", 8 | "eslint-config-typescript", 9 | "eslint-plugin-header", 10 | "eslint-plugin-prettier", 11 | "esbuild", 12 | "prettier" 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "printWidth": 90, 4 | "semi": true, 5 | "singleQuote": true, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/LicenseHeader.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/blueprint-infrastructure.ts", 3 | "context": { 4 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false, 5 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false, 6 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false, 7 | "@aws-cdk/core:stackRelativeExports": false, 8 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | module.exports = { 17 | testEnvironment: 'node', 18 | roots: ['/test'], 19 | testMatch: ['**/*.test.ts'], 20 | transform: { 21 | '^.+\\.tsx?$': 'ts-jest', 22 | }, 23 | collectCoverage: true, 24 | collectCoverageFrom: ['lambda/**/*.ts'], 25 | verbose: true, 26 | 27 | coverageThreshold: { 28 | global: { 29 | branches: 80, 30 | functions: 80, 31 | lines: 80, 32 | statements: -10, 33 | }, 34 | }, 35 | setupFiles: ['./jest.setup.js'], 36 | reporters: [ 37 | 'default', 38 | [ 39 | 'jest-junit', 40 | { 41 | outputDirectory: './reports', 42 | outputName: 'test_report.xml', 43 | }, 44 | ], 45 | ], 46 | }; 47 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/jest.setup.js: -------------------------------------------------------------------------------- 1 | process.env.AWS_ACCOUNT = 'foo-account'; 2 | process.env.AWS_REGION = 'foo-region'; 3 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/lambda/codepipeline/blueprint/common.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb'; 17 | 18 | export async function getPatternById( 19 | ddbDocClient: DynamoDBDocumentClient, 20 | patternId: string, 21 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 22 | ): Promise | undefined> { 23 | const params = { 24 | // eslint-disable-next-line @typescript-eslint/naming-convention 25 | TableName: process.env.RAPM_METADATA_TABLE_NAME, 26 | // eslint-disable-next-line @typescript-eslint/naming-convention 27 | Key: { 28 | patternId, 29 | }, 30 | }; 31 | const response = await ddbDocClient.send(new GetCommand(params)); 32 | return response.Item; 33 | } 34 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/lambda/codepipeline/types/BlueprintTypes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /** 17 | * Blueprint version object 18 | */ 19 | export interface BlueprintVersionObject { 20 | patternId: string; 21 | commitId: string; 22 | commitMessage: string; 23 | artifacts: BlueprintArtifact[]; 24 | updatedTimestamp: string; 25 | createdTimestamp: string; 26 | changedPackages: NpmPackageDetails[]; 27 | allPackages: NpmPackageDetails[]; 28 | codeArtifactDetails?: CodeArtifactDetails; 29 | changedServiceCatalogProducts?: BlueprintServiceCatalogProduct[]; 30 | allServiceCatalogProducts?: BlueprintServiceCatalogProduct[]; 31 | } 32 | 33 | /** 34 | * CFN Blueprint service catalog product 35 | */ 36 | export interface BlueprintServiceCatalogProduct { 37 | name: string; 38 | region?: string; 39 | account?: string; 40 | productId?: string; 41 | provisioningArtifactId?: string; 42 | } 43 | 44 | /** 45 | * Blueprint artifacts 46 | */ 47 | export interface BlueprintArtifact { 48 | location: string; 49 | type: 'CONTROL' | 'IMAGE' | 'MARKDOWN'; 50 | name?: string; 51 | } 52 | 53 | export interface NpmPackageDetails { 54 | name: string; 55 | version: string; 56 | location?: string; 57 | } 58 | 59 | export interface CodeArtifactDetails { 60 | account: string; 61 | region: string; 62 | codeArtifactDomainName: string; 63 | codeArtifactRepositoryName: string; 64 | } 65 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/lambda/common/common-types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable @typescript-eslint/naming-convention */ 17 | import { UserAgent } from '@aws-sdk/types'; 18 | 19 | export const customUserAgentString = 20 | process.env['SOLUTION_USER_AGENT'] ?? 'AwsSolution/SO0178/v1.0.0'; 21 | 22 | export const customUserAgentV3: UserAgent = [ 23 | [ 24 | customUserAgentString.slice(0, customUserAgentString.lastIndexOf('/')), 25 | customUserAgentString.slice(customUserAgentString.lastIndexOf('/') + 1), 26 | ], 27 | ]; 28 | 29 | export const awsSdkConfiguration = { 30 | region: process.env.AWS_REGION, 31 | customUserAgent: customUserAgentV3, 32 | }; 33 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/lambda/common/logger-factory.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import * as winston from 'winston'; 17 | import { Logger, LogLevelType } from './logger-type'; 18 | 19 | // eslint-disable-next-line @typescript-eslint/naming-convention 20 | const DEFAULT_LOG_LEVEL = 'debug'; 21 | 22 | export interface LoggerFactory { 23 | getLogger(name: string, logLevel?: LogLevelType): Logger; 24 | } 25 | 26 | export class StaticLoggerFactory implements LoggerFactory { 27 | public getLogger(name: string, logLevel?: LogLevelType): Logger { 28 | return winston.createLogger({ 29 | transports: [new winston.transports.Console()], 30 | format: winston.format.combine( 31 | winston.format.label({ label: name }), 32 | winston.format.timestamp(), 33 | winston.format.splat(), 34 | winston.format.json(), 35 | ), 36 | level: logLevel ?? DEFAULT_LOG_LEVEL, 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/lambda/common/logger-type.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ 18 | type LoggerMethodType = (message: string, ...meta: any[]) => void; 19 | 20 | export interface Logger { 21 | error: LoggerMethodType; 22 | warn: LoggerMethodType; 23 | info: LoggerMethodType; 24 | verbose: LoggerMethodType; 25 | debug: LoggerMethodType; 26 | silly: LoggerMethodType; 27 | defaultMeta?: Record; 28 | } 29 | 30 | export type LogLevelType = 'error' | 'warn' | 'info' | 'verbose' | 'debug' | 'silly'; 31 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueprint-infrastructure", 3 | "version": "1.0.0", 4 | "description": "Reusable Application Patterns Manager pattern infrastructure", 5 | "author": { 6 | "name": "Amazon Web Services", 7 | "url": "https://aws.amazon.com/solutions" 8 | }, 9 | "license": "Apache-2.0", 10 | "bin": { 11 | "blueprint-infrastructure": "bin/blueprint-infrastructure.js" 12 | }, 13 | "scripts": { 14 | "build": "tsc", 15 | "watch": "tsc -w", 16 | "test": "jest --silent unit", 17 | "lint": "eslint --ext .ts . --fix", 18 | "cdk": "cdk" 19 | }, 20 | "devDependencies": { 21 | "@aws-sdk/types": "^3.310.0", 22 | "@octokit/types": "^11.1.0", 23 | "@types/aws-lambda": "^8.10.101", 24 | "@types/jest": "^29.1.0", 25 | "@types/js-yaml": "^4.0.5", 26 | "@types/node": "^20.4.5", 27 | "@typescript-eslint/eslint-plugin": "^6.2.0", 28 | "@typescript-eslint/parser": "^6.2.0", 29 | "aws-cdk": "^2.85.0", 30 | "aws-lambda": "^1.0.7", 31 | "aws-sdk-client-mock": "^3.0.0", 32 | "constructs": "^10.1.84", 33 | "esbuild": "^0.14.53", 34 | "eslint": "^8.20.0", 35 | "eslint-config-prettier": "^8.3.0", 36 | "eslint-config-typescript": "^3.0.0", 37 | "eslint-plugin-header": "^3.1.1", 38 | "eslint-plugin-import": "^2.27.5", 39 | "eslint-plugin-prettier": "^5.0.0", 40 | "jest": "^29.3.1", 41 | "jest-junit": "^16.0.0", 42 | "prettier": "^3.0.0", 43 | "ts-jest": "^29.0.3", 44 | "typescript": "^5.0.4" 45 | }, 46 | "dependencies": { 47 | "@aws-sdk/client-cloudformation": "^3.310.0", 48 | "@aws-sdk/client-codebuild": "^3.310.0", 49 | "@aws-sdk/client-codepipeline": "^3.310.0", 50 | "@aws-sdk/client-dynamodb": "^3.310.0", 51 | "@aws-sdk/client-s3": "^3.310.0", 52 | "@aws-sdk/client-secrets-manager": "^3.310.0", 53 | "@aws-sdk/client-service-catalog": "^3.310.0", 54 | "@aws-sdk/client-sns": "^3.310.0", 55 | "@aws-sdk/lib-dynamodb": "^3.310.0", 56 | "@octokit/rest": "^20.0.1", 57 | "aws-cdk-lib": "^2.85.0", 58 | "js-yaml": "^4.1.0", 59 | "js-yaml-cloudformation-schema": "^1.0.0", 60 | "source-map-support": "^0.5.21", 61 | "winston": "^3.8.1" 62 | }, 63 | "overrides": { 64 | "fast-xml-parser": "^4.2.5", 65 | "semver": "^7.5.3", 66 | "word-wrap": "^1.2.5" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/test/unit/codepipeline/blueprint/common.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable @typescript-eslint/naming-convention */ 17 | import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; 18 | import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb'; 19 | import { mockClient } from 'aws-sdk-client-mock'; 20 | import { getPatternById } from '../../../../lambda/codepipeline/blueprint/common'; 21 | 22 | const ddbMock = mockClient(DynamoDBDocumentClient); 23 | 24 | const fixturePatternMetaData = { 25 | updatedTimestamp: '2022-07-08T02:33:47.623Z', 26 | blueprintType: 'CFN', 27 | blueprintId: 'test-blueprint', 28 | lastCommitId: 'ef727e767659e288c070230965bce001982bdaa4', 29 | description: 'Test CFN based pattern', 30 | blueprintRepoURL: 'git://test/test-blueprint.git', 31 | createdTimestamp: '2022-07-04T08:51:49.816Z', 32 | name: 'test-blueprint', 33 | infrastructureStackStatus: 'UPDATE_COMPLETE', 34 | attributes: { 35 | DataClassification: 'Low', 36 | RiskLevel: 'High', 37 | }, 38 | }; 39 | 40 | describe('common functions test', () => { 41 | beforeEach(() => { 42 | jest.resetAllMocks(); 43 | ddbMock.reset(); 44 | }); 45 | 46 | it('should return pattern details', async () => { 47 | process.env.RAPM_METADATA_TABLE_NAME = 'test-table'; 48 | ddbMock 49 | .on(GetCommand, { 50 | TableName: 'test-table', 51 | Key: { patternId: 'test-blueprint' }, 52 | }) 53 | .resolves({ 54 | Item: fixturePatternMetaData, 55 | }); 56 | const dynamodb = new DynamoDBClient({}); 57 | const ddbDocClient = DynamoDBDocumentClient.from(dynamodb); 58 | const patternDetails = await getPatternById(ddbDocClient, 'test-blueprint'); 59 | expect(patternDetails).toEqual(fixturePatternMetaData); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /source/blueprint-infrastructure/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "outDir": "./dist", 6 | "lib": ["es2018", "dom"], 7 | "declaration": true, 8 | "skipLibCheck": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "resolveJsonModule": true, 23 | "esModuleInterop": true, 24 | "typeRoots": ["./node_modules/@types"] 25 | }, 26 | "exclude": ["node_modules", "cdk.out", "./dist/**/*"] 27 | } 28 | -------------------------------------------------------------------------------- /source/blueprint-ui/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | __mocks__/react-use-localstorage.ts 4 | jest/jest.setup.ts 5 | jest/resolver.ts -------------------------------------------------------------------------------- /source/blueprint-ui/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "printWidth": 90, 4 | "semi": true, 5 | "singleQuote": true, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /source/blueprint-ui/LicenseHeader.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /source/blueprint-ui/__mocks__/react-use-localstorage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | export default { 17 | __esModule: true, 18 | default: () => ['false', () => {}], 19 | }; 20 | -------------------------------------------------------------------------------- /source/blueprint-ui/jest/jest.setup.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import '@testing-library/jest-dom'; 18 | import '@testing-library/jest-dom/extend-expect'; 19 | 20 | const env = { 21 | region: 'ap-southeast-2', 22 | userPoolId: 'ap-southeast-2_test', 23 | appClientId: '48ebobfn46cmhieimtestgi226', 24 | identityPoolId: 'ap-southeast-2:dd2e9e28-6d55-test-9f18-5e54e2b2f2ea', 25 | contactEmail: 'support@example.com', 26 | brandName: 'Performance Dashboard', 27 | frontendDomain: '', 28 | cognitoDomain: '', 29 | backendApi: 'https://test.execute-api.ap-southeast-2.amazonaws.com/prod/', 30 | samlProvider: '', 31 | enterpriseLoginLabel: 'Enterprise Sign-In', 32 | patternType: 'All', 33 | }; 34 | 35 | window.EnvironmentConfig = env; -------------------------------------------------------------------------------- /source/blueprint-ui/jest/resolver.ts: -------------------------------------------------------------------------------- 1 | module.exports = (path, options) => { 2 | // Call the defaultResolver, so we leverage its cache, error handling, etc. 3 | return options.defaultResolver(path, { 4 | ...options, 5 | // Use packageFilter to process parsed `package.json` before the resolution (see https://www.npmjs.com/package/resolve#resolveid-opts-cb) 6 | packageFilter: pkg => { 7 | // This is a workaround for https://github.com/uuidjs/uuid/pull/616 8 | // 9 | // jest-environment-jsdom 28+ tries to use browser exports instead of default exports, 10 | // but uuid only offers an ESM browser export and not a CommonJS one. Jest does not yet 11 | // support ESM modules natively, so this causes a Jest error related to trying to parse 12 | // "export" syntax. 13 | // 14 | // This workaround prevents Jest from considering uuid's module-based exports at all; 15 | // it falls back to uuid's CommonJS+node "main" property. 16 | // 17 | // Once we're able to migrate our Jest config to ESM and a browser crypto 18 | // implementation is available for the browser+ESM version of uuid to use (eg, via 19 | // https://github.com/jsdom/jsdom/pull/3352 or a similar polyfill), this can go away. 20 | if (pkg.name === 'uuid') { 21 | delete pkg['exports']; 22 | delete pkg['module']; 23 | } 24 | return pkg; 25 | }, 26 | }); 27 | }; -------------------------------------------------------------------------------- /source/blueprint-ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 15 | 16 | 25 | 26 | Application Pattern Orchestrator on AWS 27 | 28 | 29 | 30 |
31 | 41 | 42 | -------------------------------------------------------------------------------- /source/blueprint-ui/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "APO", 3 | "name": "Application Pattern Orchestrator on AWS", 4 | "icons": [], 5 | "start_url": ".", 6 | "display": "standalone", 7 | "theme_color": "#000000", 8 | "background_color": "#ffffff" 9 | } 10 | -------------------------------------------------------------------------------- /source/blueprint-ui/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/amplify-config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import EnvConfig from './services/EnvConfig'; 17 | 18 | export const backendApiName = 'RAPM-API'; 19 | 20 | const redirectUri = 21 | window.location.hostname === 'localhost' || location.hostname === '127.0.0.1' 22 | ? 'http://localhost:3000' 23 | : EnvConfig.redirectUri; 24 | 25 | const amplifyConfig = { 26 | API: { 27 | endpoints: [ 28 | { 29 | name: backendApiName, 30 | endpoint: EnvConfig.backendApi, 31 | region: EnvConfig.region, 32 | }, 33 | ], 34 | }, 35 | Auth: { 36 | region: EnvConfig.region, 37 | userPoolId: EnvConfig.userPoolId, 38 | userPoolWebClientId: EnvConfig.appClientId, 39 | identityPoolId: EnvConfig.identityPoolId, 40 | oauth: { 41 | domain: EnvConfig.cognitoDomain, 42 | scope: [ 43 | 'phone', 44 | 'email', 45 | 'openid', 46 | 'profile', 47 | 'aws.cognito.signin.user.admin', 48 | ], 49 | redirectSignIn: redirectUri, 50 | redirectSignOut: redirectUri, 51 | clientId: EnvConfig.appClientId, 52 | responseType: 'code', 53 | }, 54 | }, 55 | }; 56 | 57 | export default amplifyConfig; 58 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/DeleteConfirmationModal/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render, fireEvent } from '@testing-library/react'; 17 | import AttributeDeleteConfirmationModal from '.'; 18 | 19 | const attributeName = 'Test Attribute'; 20 | 21 | describe('AttributeDeleteConfirmationModal', () => { 22 | test('render', async () => { 23 | const mockOnSetVisible = jest.fn(); 24 | const mockOnConfirmed = jest.fn(); 25 | const { getByText, getByPlaceholderText } = render( 26 | 32 | ); 33 | expect(getByText(`Delete ${attributeName}`)).toBeVisible(); 34 | expect( 35 | getByText(`Delete Attribute ${attributeName}? This action cannot be undone.`) 36 | ).toBeVisible(); 37 | 38 | // test confirm button 39 | fireEvent.change(getByPlaceholderText('delete'), { 40 | target: { 41 | value: 'delete', 42 | }, 43 | }); 44 | 45 | fireEvent.click(getByText('Delete')); 46 | expect(mockOnConfirmed).toBeCalledTimes(1); 47 | 48 | // test cancel button 49 | fireEvent.click(getByText('Cancel')); 50 | expect(mockOnSetVisible).toBeCalledWith(false); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/DeleteConfirmationModal/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent } from 'react'; 18 | import Alert from 'aws-northstar/components/Alert'; 19 | import DeleteConfirmationDialog from 'aws-northstar/advanced/DeleteConfirmationDialog'; 20 | 21 | export interface AttributeDeleteConfirmationModalProps { 22 | attributeName: string; 23 | visible: boolean; 24 | setVisible: (visible: boolean) => void; 25 | onConfirmed: () => void; 26 | isDeleting?: boolean; 27 | } 28 | 29 | const AttributeDeleteConfirmationModal: FunctionComponent< 30 | AttributeDeleteConfirmationModalProps 31 | > = ({ attributeName, visible, setVisible, onConfirmed, isDeleting }) => { 32 | return ( 33 | { 37 | setVisible(false); 38 | }} 39 | onDeleteClicked={onConfirmed} 40 | loading={isDeleting} 41 | > 42 | 43 | Delete Attribute {attributeName}? This action cannot be undone. 44 | 45 | 46 | ); 47 | }; 48 | 49 | export default AttributeDeleteConfirmationModal; 50 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/Detail/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | import AttributeDetail from '.'; 18 | import { formatDate } from '../../../../utils/helpers'; 19 | import { Attribute } from '../../../types/index'; 20 | 21 | const testDateStr1 = '2021-10-11T12:34:56Z'; 22 | const testDateStr2 = '2021-10-12T12:34:56Z'; 23 | 24 | const attribute1: Attribute = { 25 | name: 'hostingConstruct:lambda', 26 | key: 'hostingConstruct', 27 | value: 'lambda', 28 | description: 'hostingConstruct lambda', 29 | metadata: {}, 30 | createTime: testDateStr1, 31 | lastUpdateTime: testDateStr2, 32 | }; 33 | 34 | describe('AttributeDetail', () => { 35 | test('render attribute details', async () => { 36 | const { getByText } = render(); 37 | expect(getByText('hostingConstruct')).toBeInTheDocument(); 38 | expect(getByText('lambda')).toBeInTheDocument(); 39 | expect(getByText('hostingConstruct lambda')).toBeInTheDocument(); 40 | expect(getByText(formatDate(new Date(testDateStr1)))).toBeInTheDocument(); 41 | expect(getByText(formatDate(new Date(testDateStr2)))).toBeInTheDocument(); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/Form/components/Review/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | import AttributeReview from '.'; 18 | import { BrowserRouter } from 'react-router-dom'; 19 | import { AttributeFormData } from '../../../../../types/index'; 20 | 21 | const attrFormValues: AttributeFormData = { 22 | key: 'testkey', 23 | value: 'testval', 24 | description: 'testdesc', 25 | metadata: [], 26 | }; 27 | 28 | describe('AttributeReview', () => { 29 | test('render review', async () => { 30 | // Attribute Review page 31 | const { getByText } = render( 32 | 33 | 34 | 35 | ); 36 | 37 | // Review page 38 | expect(getByText(attrFormValues.key)).toBeInTheDocument(); 39 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 40 | expect(getByText(attrFormValues.description!)).toBeInTheDocument(); 41 | expect(getByText(attrFormValues.value)).toBeInTheDocument(); 42 | }, 20000); 43 | }); 44 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/Form/components/Review/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent } from 'react'; 18 | import Stack from 'aws-northstar/layouts/Stack'; 19 | import KeyValuePair from 'aws-northstar/components/KeyValuePair'; 20 | import ColumnLayout, { Column } from 'aws-northstar/layouts/ColumnLayout'; 21 | import Table, { Column as TableColumn } from 'aws-northstar/components/Table'; 22 | import Text from 'aws-northstar/components/Text'; 23 | import { AttributeFormData, KeyValuePairType } from '../../../../../types'; 24 | 25 | const AttributeReview: FunctionComponent<{ data: AttributeFormData }> = ({ data }) => { 26 | const columnDefinitions: TableColumn[] = [ 27 | { 28 | id: 'key', 29 | width: 300, 30 | Header: 'Key', 31 | accessor: 'key', 32 | }, 33 | { 34 | id: 'value', 35 | width: 300, 36 | Header: 'Value', 37 | accessor: 'value', 38 | }, 39 | ]; 40 | return ( 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Metadata 52 | 63 | 64 | 65 | 66 | ); 67 | }; 68 | 69 | export default AttributeReview; 70 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/Table/MetaData/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | import MetadataTable from '.'; 18 | import { BrowserRouter } from 'react-router-dom'; 19 | 20 | const metadata = { 21 | key1: 'val1', 22 | key2: 'val2', 23 | }; 24 | 25 | describe('MetadataTable', () => { 26 | test('render table', async () => { 27 | const { getByText } = render( 28 | 29 | 30 | 31 | ); 32 | 33 | expect(getByText('key1')).toBeInTheDocument(); 34 | expect(getByText('key2')).toBeInTheDocument(); 35 | expect(getByText(metadata.key1)).toBeInTheDocument(); 36 | expect(getByText(metadata.key2)).toBeInTheDocument(); 37 | }, 20000); 38 | }); 39 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Attributes/Table/MetaData/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent, useMemo } from 'react'; 18 | import Table, { Column } from 'aws-northstar/components/Table'; 19 | import { KeyValuePairType } from '../../../../types'; 20 | export interface MetadataTableProps { 21 | metadata?: Record; 22 | disableRowSelect?: boolean; 23 | disableToolbar?: boolean; 24 | disableCreate?: boolean; 25 | disableDelete?: boolean; 26 | tableName?: string; 27 | } 28 | 29 | export const getColumnDefinitions = () => { 30 | const fields: Column[] = [ 31 | { 32 | id: 'key', 33 | width: 400, 34 | Header: 'Key', 35 | accessor: 'key', 36 | }, 37 | { 38 | id: 'value', 39 | width: 500, 40 | Header: 'Value', 41 | accessor: 'value', 42 | }, 43 | ]; 44 | 45 | return fields; 46 | }; 47 | 48 | const MetadataTable: FunctionComponent = ({ 49 | metadata = {}, 50 | disableRowSelect = true, 51 | disableToolbar = true, 52 | tableName, 53 | }) => { 54 | const columnDefinitions = useMemo(() => { 55 | return getColumnDefinitions(); 56 | }, []); 57 | const keys = Object.keys(metadata); 58 | const items = keys.map((k) => { 59 | return { key: k, value: metadata[k] }; 60 | }); 61 | return ( 62 |
data.key} 68 | items={items} 69 | wrapText={false} 70 | disableSettings={disableToolbar} 71 | disableFilters={disableToolbar} 72 | disablePagination={disableToolbar} 73 | /> 74 | ); 75 | }; 76 | 77 | export default MetadataTable; 78 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/BlueprintArtifact/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render, screen, act } from '@testing-library/react'; 17 | import { BrowserRouter } from 'react-router-dom'; 18 | import BlueprintArtifactContainer from '.'; 19 | import { PatternArtifact } from '../../types'; 20 | import GetArtifactDetails from '../../queries/GetArtifactDetailsQuery'; 21 | 22 | jest.mock('../../queries/GetArtifactDetailsQuery'); 23 | const mockGetArtifactDetails = GetArtifactDetails as jest.Mock; 24 | 25 | const artifact: PatternArtifact = { 26 | location: './README.md', 27 | type: 'MARKDOWN', 28 | name: 'README', 29 | }; 30 | 31 | describe('BlueprintArtifactContainer', () => { 32 | test('render', async () => { 33 | mockGetArtifactDetails.mockResolvedValue('dGVzdCB1c2FnZSBkb2N1bWVudAo='); 34 | 35 | await act(async () => { 36 | render( 37 | 38 | 39 | 40 | ); 41 | }); 42 | 43 | expect(mockGetArtifactDetails).toBeCalled(); 44 | expect(screen.getByText('test usage document')).toBeInTheDocument(); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/BlueprintArtifact/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent, useEffect, useState } from 'react'; 18 | import BlueprintArtifactComponent from '../../pages/Artifact'; 19 | import GetArtifactDetails from '../../queries/GetArtifactDetailsQuery'; 20 | 21 | import { PatternArtifact } from '../../types'; 22 | 23 | export interface BlueprintArtifactContainerProps { 24 | artifact: PatternArtifact; 25 | } 26 | 27 | const BlueprintArtifactContainer: FunctionComponent = ({ 28 | artifact, 29 | }) => { 30 | const [artifactData, setArtifactData] = useState(''); 31 | useEffect(() => { 32 | async function fetchArtifactData(location: string) { 33 | const artifactDetails = await GetArtifactDetails(location); 34 | setArtifactData(artifactDetails); 35 | } 36 | 37 | fetchArtifactData(artifact.location); 38 | }); 39 | 40 | return ; 41 | }; 42 | 43 | export default BlueprintArtifactContainer; 44 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/containers/Patterns/Form/components/Review/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import React from 'react'; 17 | 18 | import { render, screen } from '@testing-library/react'; 19 | import PatternReview from './index'; 20 | import { PatternFormData } from '../../../../../types'; 21 | 22 | describe('Patterns Form', () => { 23 | test('render without attributes', () => { 24 | const patternFormData: PatternFormData = { 25 | name: 'Test Form', 26 | description: 'Test form description xxx', 27 | patternType: 'CDK', 28 | }; 29 | render(); 30 | 31 | expect(screen.getByText('Test Form')).toBeInTheDocument(); 32 | expect(screen.getByText('CDK')).toBeInTheDocument(); 33 | expect(screen.getByText('Test form description xxx')).toBeInTheDocument(); 34 | expect(screen.getByText('No records found')).toBeInTheDocument(); 35 | }); 36 | 37 | test('render with attributes', () => { 38 | const patternFormData: PatternFormData = { 39 | name: 'Test Form', 40 | description: 'Test form description xxx', 41 | patternType: 'CFN', 42 | attributes: [ 43 | { 44 | key: 'attribute_1', 45 | value: 'attribute_value_1', 46 | }, 47 | { 48 | key: 'attribute_2', 49 | value: 'attribute_value_2', 50 | }, 51 | ], 52 | }; 53 | render(); 54 | 55 | expect(screen.getByText('Test Form')).toBeInTheDocument(); 56 | expect(screen.getByText('CFN')).toBeInTheDocument(); 57 | expect(screen.getByText('attribute_1')).toBeInTheDocument(); 58 | expect(screen.getByText('attribute_value_1')).toBeInTheDocument(); 59 | expect(screen.getByText('attribute_2')).toBeInTheDocument(); 60 | expect(screen.getByText('attribute_value_2')).toBeInTheDocument(); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/AppContext/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | const mockCurrentAuthenticatedUser = jest.fn(); 17 | 18 | jest.mock('aws-amplify', () => { 19 | return { 20 | ...jest.requireActual('aws-amplify'), 21 | Auth: { 22 | currentAuthenticatedUser: mockCurrentAuthenticatedUser, 23 | }, 24 | }; 25 | }); 26 | 27 | import { render, screen } from '@testing-library/react'; 28 | import { AppContextProvider } from './index'; 29 | 30 | describe('AppContext tests', () => { 31 | test('can get authenticated user', async () => { 32 | // arrange 33 | mockCurrentAuthenticatedUser.mockResolvedValueOnce({ 34 | attributes: { 35 | email: 'test@amazon.com', 36 | }, 37 | signInUserSession: { 38 | accessToken: { 39 | payload: { 'cognito:groups': ['User'] }, 40 | }, 41 | }, 42 | }); 43 | 44 | // act 45 | render( 46 | 47 |

Content

48 |
49 | ); 50 | 51 | // assert 52 | expect(await screen.findByText('Content')).toBeInTheDocument(); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/AppContext/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { createContext, FunctionComponent, useContext, useState } from 'react'; 17 | import { User } from '../../types'; 18 | 19 | export interface BlueprintContext { 20 | user?: User; 21 | setUser: (user: User) => void; 22 | } 23 | 24 | const AppContext = createContext({ 25 | // eslint-disable-next-line @typescript-eslint/no-empty-function 26 | setUser: () => {}, 27 | }); 28 | 29 | export const AppContextProvider: FunctionComponent = ({ children }) => { 30 | const [authenticatedUser, setAuthenticatedUser] = useState(); 31 | 32 | return ( 33 | 39 | {children} 40 | 41 | ); 42 | }; 43 | 44 | export const useAppContext = () => useContext(AppContext); 45 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/HasPermission/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | 18 | import { UserGroup } from '../../types'; 19 | import HasPermission from '.'; 20 | 21 | jest.mock('../AppContext', () => ({ 22 | useAppContext: jest.fn().mockImplementation(() => { 23 | return { 24 | user: { 25 | email: 'test@test.com', 26 | groups: ['SYSTEM_ADMIN'], 27 | }, 28 | }; 29 | }), 30 | })); 31 | 32 | describe('Has Group', () => { 33 | test('user group match', () => { 34 | const { getByText } = render( 35 | Test Text 36 | ); 37 | expect(getByText('Test Text')).toBeInTheDocument(); 38 | }); 39 | 40 | test('user group not match', () => { 41 | const { queryByText } = render( 42 | 43 | Test Text 44 | 45 | ); 46 | expect(queryByText('Test Text')).not.toBeInTheDocument(); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/HasPermission/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { FunctionComponent } from 'react'; 17 | import { useAppContext } from '../AppContext'; 18 | import { UserGroup } from '../../types'; 19 | 20 | export interface HasPermissionProps { 21 | groups: UserGroup[]; 22 | children: unknown; 23 | } 24 | 25 | /** 26 | * Usage: 27 | * Things to Render 28 | * 29 | * @param groups list of UserGroup to check. 30 | * @param children elements to render if user is in at least one of the groups passed in. 31 | * @constructor 32 | */ 33 | export const HasPermission: FunctionComponent = ({ 34 | groups, 35 | children, 36 | }) => { 37 | const { user } = useAppContext(); 38 | return user?.groups?.some((userGroup) => groups.includes(userGroup)) ? ( 39 | <>{children} 40 | ) : null; 41 | }; 42 | 43 | export default HasPermission; 44 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/PageError/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | import PageError from './index'; 18 | 19 | describe('Page Error', () => { 20 | test('render', () => { 21 | const { getByText } = render( 22 | 27 | ); 28 | expect(getByText('Header Text')).toBeInTheDocument(); 29 | expect(getByText('Message Text')).toBeInTheDocument(); 30 | }); 31 | 32 | test('render default', () => { 33 | const { getByText } = render(); 34 | expect(getByText('Oops! Something went wrong')).toBeInTheDocument(); 35 | expect( 36 | getByText('There was an issue on your request. Please try again later.') 37 | ).toBeInTheDocument(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/PageError/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent } from 'react'; 18 | import Box from 'aws-northstar/layouts/Box'; 19 | import Alert from 'aws-northstar/components/Alert'; 20 | 21 | export interface PageErrorProps { 22 | header?: string; 23 | message?: string; 24 | retryOnClick?: () => void; 25 | } 26 | 27 | const PageError: FunctionComponent = ({ 28 | header = 'Oops! Something went wrong', 29 | message = 'There was an issue on your request. Please try again later.', 30 | retryOnClick, 31 | }) => ( 32 | 33 | 39 | {message} 40 | 41 | 42 | ); 43 | 44 | export default PageError; 45 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/PageLoading/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent } from 'react'; 18 | import Box from 'aws-northstar/layouts/Box'; 19 | import LoadingIndicator from 'aws-northstar/components/LoadingIndicator'; 20 | 21 | const PageLoading: FunctionComponent = () => ( 22 | 23 | 24 | 25 | ); 26 | 27 | export default PageLoading; 28 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/core/QueryContainerTemplate/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { ReactElement } from 'react'; 18 | import PageError from '../PageError'; 19 | import PageLoading from '../PageLoading'; 20 | 21 | export interface QueryContainerTemplateProps { 22 | loading: boolean; 23 | error?: string; 24 | data?: T; 25 | canErrorRetry?: boolean; 26 | onRetry?: () => void; 27 | children: (data: T) => ReactElement; 28 | } 29 | 30 | function QueryContainerTemplate({ 31 | loading, 32 | error, 33 | data, 34 | children, 35 | canErrorRetry = false, 36 | onRetry, 37 | }: QueryContainerTemplateProps) { 38 | if (loading) { 39 | return ; 40 | } 41 | 42 | if (error) { 43 | return ( 44 | 48 | ); 49 | } 50 | 51 | if (data) { 52 | return children(data); 53 | } 54 | 55 | return null; 56 | } 57 | 58 | export default QueryContainerTemplate; 59 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/pages/Artifact/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { FunctionComponent, ReactElement } from 'react'; 17 | import MarkdownViewer from 'aws-northstar/components/MarkdownViewer'; 18 | import { PatternArtifact } from '../../types'; 19 | import { Buffer } from 'buffer'; 20 | 21 | export interface BlueprintArtifactComponentProps { 22 | artifact: PatternArtifact; 23 | artifactData: string; 24 | } 25 | 26 | const BlueprintArtifactComponent: FunctionComponent = ({ 27 | artifact, 28 | artifactData, 29 | }) => { 30 | if (!artifactData) { 31 | return ; 32 | } 33 | 34 | let component: ReactElement; 35 | if (artifact.type === 'MARKDOWN') { 36 | component = ( 37 | // Markdown content is returned base64 encoded by the artifacts API 38 | 39 | {Buffer.from(artifactData, 'base64').toString()} 40 | 41 | ); 42 | } else if (artifact.type === 'IMAGE') { 43 | component = ( 44 | // Blueprint service only supports png files 45 | {artifact.name} 52 | ); 53 | } else { 54 | component = Cannot render artifacts of type {artifact.type}; 55 | } 56 | 57 | return component; 58 | }; 59 | 60 | export default BlueprintArtifactComponent; 61 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/pages/InfrastructureStatus/index.test.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { render } from '@testing-library/react'; 17 | 18 | import BlueprintInfrastructureStatus from '.'; 19 | 20 | describe('BlueprintInfrastructureStatus', () => { 21 | test('render to show status in progress', () => { 22 | const { getAllByText } = render( 23 | 24 | ); 25 | expect(getAllByText('Creating')).toHaveLength(2); 26 | }); 27 | 28 | test('render to show status ready', () => { 29 | const { getAllByText } = render( 30 | 31 | ); 32 | expect(getAllByText('Ready')).toHaveLength(2); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/pages/InfrastructureStatus/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { FunctionComponent } from 'react'; 18 | import StatusIndicator from 'aws-northstar/components/StatusIndicator'; 19 | 20 | export interface BlueprintInfrastructureStatusProps { 21 | status?: string; 22 | } 23 | 24 | const BlueprintInfrastructureStatus: FunctionComponent< 25 | BlueprintInfrastructureStatusProps 26 | > = ({ status }) => { 27 | let statusType: 'positive' | 'negative' | 'warning' | 'info' = 'warning'; 28 | let statusText = status; 29 | 30 | if (status === 'CREATE_IN_PROGRESS' || status === 'UPDATE_IN_PROGRESS') { 31 | statusText = 'Creating'; 32 | statusType = 'info'; 33 | } else if (status === 'CREATE_COMPLETE' || status === 'UPDATE_COMPLETE') { 34 | statusText = 'Ready'; 35 | statusType = 'positive'; 36 | } 37 | 38 | return {statusText}; 39 | }; 40 | 41 | export default BlueprintInfrastructureStatus; 42 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAllAttributesQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import GetAllAttributesQuery from './GetAllAttributesQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetAllAttributesQuery', () => { 33 | test('GetAllAttributesQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | mockAuthHeaders.mockResolvedValueOnce(headers); 39 | await GetAllAttributesQuery(); 40 | expect(API.get).toHaveBeenCalledWith(backendApiName, '/attributes', { 41 | headers, 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAllAttributesQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { GetAttributeApiResponse } from '../types'; 19 | import { authHeaders } from './auth'; 20 | 21 | async function getAllAttributesQuery(): Promise { 22 | const headers = await authHeaders(); 23 | const path = '/attributes'; 24 | const myInit = { 25 | headers, 26 | }; 27 | 28 | return API.get(backendApiName, path, myInit); 29 | } 30 | 31 | export default getAllAttributesQuery; 32 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAllPatternsQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import GetAllPatternsQuery from './GetAllPatternsQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetAllPatternsQuery', () => { 33 | test('GetAllPatternsQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | mockAuthHeaders.mockResolvedValueOnce(headers); 39 | await GetAllPatternsQuery(); 40 | expect(API.get).toHaveBeenCalledWith(backendApiName, '/patterns', { 41 | headers, 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAllPatternsQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { GetPatternsApiResponse } from '../types'; 19 | import { authHeaders } from './auth'; 20 | 21 | async function getAllPatternsQuery(): Promise { 22 | const headers = await authHeaders(); 23 | const path = '/patterns'; 24 | const myInit = { 25 | headers, 26 | }; 27 | 28 | return API.get(backendApiName, path, myInit); 29 | } 30 | 31 | export default getAllPatternsQuery; 32 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetArtifactDetailsQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import GetArtifactDetailsQuery from './GetArtifactDetailsQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetArtifactDetailsQuery', () => { 33 | test('GetArtifactDetailsQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | mockAuthHeaders.mockResolvedValueOnce(headers); 39 | const filePath = 'artifact-xyz'; 40 | await GetArtifactDetailsQuery(filePath); 41 | expect(API.get).toHaveBeenCalledWith( 42 | backendApiName, 43 | `/artifacts/${encodeURIComponent(filePath)}`, 44 | { 45 | headers, 46 | } 47 | ); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetArtifactDetailsQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { API } from 'aws-amplify'; 18 | import { backendApiName } from '../../amplify-config'; 19 | import { authHeaders } from './auth'; 20 | 21 | async function getArtifactDetailsQuery(filePath: string): Promise { 22 | const headers = await authHeaders(); 23 | const path = `/artifacts/${encodeURIComponent(filePath)}`; 24 | const myInit = { 25 | // OPTIONAL 26 | headers, 27 | }; 28 | 29 | return API.get(backendApiName, path, myInit); 30 | } 31 | 32 | export default getArtifactDetailsQuery; 33 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAttributeDetailsQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import GetAttributeDetailsQuery from './GetAttributeDetailsQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetAttributeDetailsQuery', () => { 33 | test('GetAttributeDetailsQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | const mockAttributeId = 'test-attribute-1'; 39 | mockAuthHeaders.mockResolvedValueOnce(headers); 40 | 41 | await GetAttributeDetailsQuery(mockAttributeId); 42 | expect(API.get).toHaveBeenCalledWith( 43 | backendApiName, 44 | `/attributes/${mockAttributeId}`, 45 | { 46 | headers, 47 | } 48 | ); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetAttributeDetailsQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { Attribute } from '../types'; 19 | import { authHeaders } from './auth'; 20 | 21 | async function getAttributeDetailsQuery(id: string): Promise { 22 | const headers = await authHeaders(); 23 | const path = `/attributes/${id}`; 24 | const myInit = { 25 | headers, 26 | }; 27 | 28 | return API.get(backendApiName, path, myInit); 29 | } 30 | 31 | export default getAttributeDetailsQuery; 32 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetPatternDetailsQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import GetPatternDetailsQuery from './GetPatternDetailsQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetPatternDetailsQuery', () => { 33 | test('GetPatternDetailsQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | mockAuthHeaders.mockResolvedValueOnce(headers); 39 | const mockPatternId = 'test-patter-1'; 40 | 41 | await GetPatternDetailsQuery(mockPatternId); 42 | expect(API.get).toHaveBeenCalledWith( 43 | backendApiName, 44 | `/patterns/${mockPatternId}`, 45 | { 46 | headers, 47 | } 48 | ); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetPatternDetailsQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { Pattern } from '../types'; 19 | import { authHeaders } from './auth'; 20 | 21 | async function getPatternDetailsQuery(id: string): Promise { 22 | const headers = await authHeaders(); 23 | const path = `/patterns/${id}`; 24 | const myInit = { 25 | headers, 26 | }; 27 | 28 | return API.get(backendApiName, path, myInit); 29 | } 30 | 31 | export default getPatternDetailsQuery; 32 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetSubscriptionQuery.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { API } from 'aws-amplify'; 17 | import { backendApiName } from '../../amplify-config'; 18 | import { authHeaders } from './auth'; 19 | import { getSubscriptionQuery } from './GetSubscriptionQuery'; 20 | 21 | jest.mock('aws-amplify', () => ({ 22 | // eslint-disable-next-line @typescript-eslint/naming-convention 23 | API: { 24 | get: jest.fn(), 25 | }, 26 | })); 27 | jest.mock('./auth'); 28 | 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | const mockAuthHeaders = authHeaders as jest.Mock; 31 | 32 | describe('GetSubscriptionQuery tests', () => { 33 | test('GetPatternDetailsQuery invoke', async () => { 34 | const headers = { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Authorization: 'Bearer abcd', 37 | }; 38 | mockAuthHeaders.mockResolvedValueOnce(headers); 39 | 40 | await getSubscriptionQuery('1234', 'myemail'); 41 | 42 | expect(API.get).toHaveBeenCalledWith(backendApiName, `/subscriptions`, { 43 | headers, 44 | queryStringParameters: { 45 | patternId: '1234', 46 | email: 'myemail', 47 | }, 48 | }); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/GetSubscriptionQuery.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { API } from 'aws-amplify'; 18 | import { backendApiName } from '../../amplify-config'; 19 | import { authHeaders } from './auth'; 20 | 21 | export async function getSubscriptionQuery( 22 | patternId: string, 23 | email: string 24 | ): Promise | undefined> { 25 | const headers = await authHeaders(); 26 | 27 | try { 28 | return await API.get(backendApiName, '/subscriptions', { 29 | headers, 30 | queryStringParameters: { 31 | patternId, 32 | email, 33 | }, 34 | }); 35 | } catch (error) { 36 | if (error.response.status === 404) { 37 | return undefined; 38 | } 39 | throw error; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/queries/auth.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import Auth from '@aws-amplify/auth'; 18 | 19 | export async function authHeaders() { 20 | const token = await getAuthToken(); 21 | return { 22 | Authorization: 'Bearer '.concat(token), 23 | }; 24 | } 25 | 26 | export async function getAuthToken() { 27 | const session = await Auth.currentSession(); 28 | const idToken = session.getIdToken(); 29 | return idToken.getJwtToken(); 30 | } 31 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/components/routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Blueprints 18 | export const ROUTE_BLUEPRINT_CREATE = '/patterns/create'; 19 | 20 | export const ROUTE_BLUEPRINT_DETAIL = '/patterns/:blueprintId'; 21 | 22 | export const ROUTE_BLUEPRINT_UPDATE = '/patterns/:blueprintId/update'; 23 | 24 | export const ROUTE_BLUEPRINTS_VIEW = '/patterns'; 25 | 26 | // Attribute 27 | export const ROUTE_ATTRIBUTE_CREATE = '/attributes/create'; 28 | 29 | export const ROUTE_ATTRIBUTE_DETAILS = '/attributes/:attributeId'; 30 | 31 | export const ROUTE_ATTRIBUTE_UPDATE = '/attributes/:attributeId/update'; 32 | 33 | export const ROUTE_ATTRIBUTES_VIEW = '/attributes'; 34 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import React from 'react'; 17 | import ReactDOM from 'react-dom'; 18 | import './index.css'; 19 | import App from './App'; 20 | import Amplify from '@aws-amplify/core'; 21 | import reportWebVitals from './reportWebVitals'; 22 | 23 | import amplifyConfig from './amplify-config'; 24 | 25 | Amplify.configure(amplifyConfig); 26 | 27 | ReactDOM.render( 28 | 29 | 30 | , 31 | document.getElementById('root') 32 | ); 33 | 34 | // If you want to start measuring performance in your app, pass a function 35 | // to log results (for example: reportWebVitals(console.log)) 36 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 37 | reportWebVitals(); 38 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { ReportHandler } from 'web-vitals'; 17 | 18 | const reportWebVitals = (onPerfEntry?: ReportHandler): void => { 19 | if (onPerfEntry instanceof Function) { 20 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 21 | getCLS(onPerfEntry); 22 | getFID(onPerfEntry); 23 | getFCP(onPerfEntry); 24 | getLCP(onPerfEntry); 25 | getTTFB(onPerfEntry); 26 | }); 27 | } 28 | }; 29 | 30 | export default reportWebVitals; 31 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/services/EnvConfig.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | declare global { 18 | interface Window { 19 | EnvironmentConfig: EnvConfig; 20 | } 21 | } 22 | 23 | interface EnvConfig { 24 | region: string; 25 | backendApi: string; 26 | userPoolId: string; 27 | appClientId: string; 28 | identityPoolId: string; 29 | redirectUri: string; 30 | cognitoDomain: string; 31 | patternType: 'CloudFormation' | 'CDK' | 'All'; 32 | } 33 | 34 | const config = window.EnvironmentConfig; 35 | 36 | const EnvConfigService = { 37 | // Export all values in the window object 38 | ...window.EnvironmentConfig, 39 | // Set default values for some properties. These defaults are a fallback 40 | // mechanism in case these properties are not available on the window object 41 | // for some reason. If the `public/env.js` file loads properly, then they will be 42 | // available, but just in case it doesn't, the app wont crash. 43 | cognitoDomain: config.cognitoDomain || '', 44 | redirectUri: config.redirectUri || '', 45 | } as EnvConfig; 46 | 47 | export default EnvConfigService; 48 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import '@testing-library/jest-dom'; 17 | -------------------------------------------------------------------------------- /source/blueprint-ui/src/utils/helpers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { PatternType } from '../components/types'; 17 | import EnvConfig from '../services/EnvConfig'; 18 | 19 | export function formatDate(date: Date, locales?: string): string { 20 | const formatter = new Intl.DateTimeFormat(locales, { 21 | dateStyle: 'medium', 22 | timeStyle: 'medium', 23 | }); 24 | 25 | return formatter.format(date); 26 | } 27 | 28 | export function getDefaultPatternType(): PatternType { 29 | return EnvConfig.patternType === 'CDK' ? 'CDK' : 'CFN'; 30 | } 31 | -------------------------------------------------------------------------------- /source/blueprint-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "target": "es2017", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": false, 11 | "strictNullChecks": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "module": "esnext", 15 | "moduleResolution": "node", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "jsx": "react-jsx" 20 | }, 21 | "include": ["src"] 22 | } 23 | -------------------------------------------------------------------------------- /source/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/blueprint-service-infra.ts", 3 | "context": { 4 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 5 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false, 6 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false, 7 | "@aws-cdk/core:stackRelativeExports": false, 8 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 9 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, 10 | "appRegistrySyncScheduleExpression": "cron(0 3 * * ? *)" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /source/cypress/README.md: -------------------------------------------------------------------------------- 1 | # Cypress e2e Testing 2 | 3 | ## Pre-req: 4 | - Google Chrome installed 5 | 6 | ## Environment variables 7 | The cypress tests extracts away the configuration to environment variables. It is a pre-requisite that the below environments are available to the tests before they are executed: 8 | 9 | | Environment variable | Description | Required | 10 | |----------------------| ------------|----------| 11 | |`BASE_URL`| The base url of the test environment UI| Yes | 12 | |`AWS_COGNITO_USERNAME`| AWS Cognito user name for login| Yes | 13 | |`AWS_COGNITO_DOMAIN`| AWS Cognito domain| Yes | 14 | |`AWS_COGNITO_REGION`| AWS Cognito region| Yes | 15 | |`AWS_COGNITO_USER_POOLS_ID`| AWS Cognito user pool id| Yes | 16 | |`AWS_COGNITO_USER_POOL_APP_CLIENT_ID`| AWS Cognito user pool app client id| Yes | 17 | |`GITHUB_BASE_URL`| GitHub enterprise server base url. Not required for GitHub/GitHub cloud | Optional | 18 | |`GITHUB_ORG`| GitHub organisation| Yes | 19 | |`GITHUB_TOKEN`| GitHub token. This should have delete repo access as the tests deleted the test repo at the end of the tests| Yes | 20 | 21 | ## Local testing 22 | For local testing, please create a local file `.env.local` with all the above environment variables defined under `source/` directory where cypress.config.js exists. Please don't commit this file to the source code repo. This is for your local testing only. 23 | 24 | ## Folder structure 25 | Reference: https://docs.cypress.io/guides/references/configuration#Folders-Files 26 | 27 | ``` 28 | . 29 | ├── downloads (Path to folder where files downloaded during a test are saved 30 | ) 31 | ├── fixtures (for static data in json format you want to load into tests). 32 | ├── e2e (test specs are located here) 33 | ├── screenshots (failed test screenshots) 34 | ├── support (any reusable commands should go here) 35 | ├── testing-data 36 | └── videos 37 | ``` 38 | ## How to run the tests 39 | To run headlessly use the below command: 40 | `npm run cy:run` 41 | 42 | To run in a browser use the below command: 43 | `npm run cy:open` 44 | 45 | -------------------------------------------------------------------------------- /source/cypress/e2e/attribute/attribute-form-validation.cy.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | describe('Create Attribute form validation', function () { 18 | beforeEach(function () { 19 | cy.fixture('testdata').then(function (testdata) { 20 | cy.log(testdata.testAttributeKey); 21 | this.testData = testdata; 22 | }); 23 | cy.loginByCognito(Cypress.env('cognitoUsername'), Cypress.env('cognitoPassword')); 24 | cy.homePageWithSideNavigation(); 25 | }); 26 | 27 | it('Attribute form validation', function () { 28 | // Create attriute page 29 | cy.get('a').contains('Attributes').click(); 30 | cy.contains('Required').should('not.exist'); 31 | cy.contains('Add new attribute', { matchCase: false }).click(); 32 | cy.get('Button').contains('Next').click(); 33 | cy.contains('Required').should('exist'); 34 | cy.get('#key').type(this.testData.newAttributeKey); 35 | cy.get('#value').type(this.testData.newAttributeValue); 36 | cy.get('#description').type(this.testData.newAttributeDescription); 37 | cy.contains('Required').should('not.exist'); 38 | cy.get('Button').contains('Next').click(); 39 | 40 | // Attribute Metadata page 41 | cy.get('h1').contains('Attribute Metadata').should('be.visible'); 42 | cy.get('Button') 43 | .contains('Add new item', { 44 | matchCase: false, 45 | }) 46 | .click(); 47 | cy.get('Button').contains('Next').click(); 48 | cy.contains('Required').should('exist'); 49 | cy.get('#metadata\\[0\\]\\.key').type(this.testData.newAttributeMetaKey); 50 | cy.get('#metadata\\[0\\]\\.value').type(this.testData.newAttributeMetaValue); 51 | cy.contains('Required').should('not.exist'); 52 | cy.get('Button').contains('Next').click(); 53 | 54 | // Review page 55 | cy.get('h1').contains('Review').should('be.visible'); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/cdk-test-app/bin/cdk-test-app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"). 6 | You may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | import 'source-map-support/register'; 18 | import * as cdk from 'aws-cdk-lib'; 19 | import { CompliantBucket } from '../../compliant-s3-bucket/lib/compliant-s3-bucket'; 20 | import { CompliantDynamoDbTable } from '../../compliant-dynamodb-table/lib/compliant-dynamodb-table'; 21 | 22 | const app = new cdk.App(); 23 | const stack = new cdk.Stack(app); 24 | 25 | new CompliantBucket(stack, 'DemoCompliantBucket', { 26 | bucketName: 'demobucket', 27 | }); 28 | 29 | new CompliantDynamoDbTable(stack, 'DemoCompliantDynamoDbTable'); 30 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-dynamodb-table/README.md: -------------------------------------------------------------------------------- 1 | # `compliant-dynamodb-table` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const compliantDynamodbTable = require('compliant-dynamodb-table'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-dynamodb-table/lib/compliant-dynamodb-table.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { aws_dynamodb as ddb } from 'aws-cdk-lib'; 17 | import { Construct } from 'constructs'; 18 | 19 | export interface CompliantDynamoDbTableProps { 20 | tableName: string; 21 | } 22 | 23 | export class CompliantDynamoDbTable extends Construct { 24 | public readonly table: ddb.Table; 25 | public constructor( 26 | scope: Construct, 27 | id: string, 28 | props?: CompliantDynamoDbTableProps, 29 | ) { 30 | super(scope, id); 31 | this.table = new ddb.Table(this, 'CompliantDdbTable', { 32 | tableName: props?.tableName, 33 | partitionKey: { name: 'id', type: ddb.AttributeType.STRING }, 34 | // Compliant dynamodb table props 35 | billingMode: ddb.BillingMode.PAY_PER_REQUEST, 36 | pointInTimeRecovery: true, 37 | encryption: ddb.TableEncryption.AWS_MANAGED, 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-dynamodb-table/lib/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | export * from './compliant-dynamodb-table'; 17 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-dynamodb-table/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cypress-cdk/compliant-dynamodbtable", 3 | "version": "1.0.0", 4 | "description": "Compliant DynamoDb Table ", 5 | "license": "Apache-2.0", 6 | "main": "lib/compliant-dynamodb-table.js", 7 | "directories": { 8 | "lib": "lib", 9 | "test": "__tests__" 10 | }, 11 | "files": [ 12 | "lib" 13 | ], 14 | "scripts": { 15 | "build": "tsc --project tsconfig.json", 16 | "test": "jest --silent --passWithNoTests" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-dynamodb-table/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "target": "ES2018", 5 | "module": "commonjs", 6 | "lib": ["es2018"], 7 | "declaration": true, 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "strictNullChecks": true, 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "inlineSourceMap": true, 18 | "inlineSources": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "types": ["node", "jest"] 22 | }, 23 | "exclude": ["cdk.out", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-s3-bucket/README.md: -------------------------------------------------------------------------------- 1 | # `compliant-s3-bucket` 2 | 3 | > TODO: description 4 | 5 | ## Usage 6 | 7 | ``` 8 | const compliantS3Bucket = require('compliant-s3-bucket'); 9 | 10 | // TODO: DEMONSTRATE API 11 | ``` 12 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-s3-bucket/lib/compliant-s3-bucket.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { aws_s3 as s3, RemovalPolicy } from 'aws-cdk-lib'; 17 | import { Construct } from 'constructs'; 18 | 19 | export interface CompliantBucketProps { 20 | bucketName: string; 21 | } 22 | 23 | export class CompliantBucket extends Construct { 24 | public readonly bucket: s3.Bucket; 25 | public constructor(scope: Construct, id: string, props: CompliantBucketProps) { 26 | super(scope, id); 27 | this.bucket = new s3.Bucket(this, 'CompliantBucket', { 28 | bucketName: props.bucketName, 29 | // Below props makes compliant s3 bucket 30 | blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, 31 | encryption: s3.BucketEncryption.S3_MANAGED, 32 | enforceSSL: true, 33 | versioned: true, 34 | removalPolicy: RemovalPolicy.RETAIN, 35 | serverAccessLogsPrefix: 'access-logs', 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-s3-bucket/lib/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | export * from './compliant-s3-bucket'; 17 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-s3-bucket/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cypress-cdk/compliant-s3-bucket", 3 | "version": "1.0.0", 4 | "description": "Compliant S3 bucket", 5 | "license": "Apache-2.0", 6 | "main": "lib/compliant-s3-bucket.js", 7 | "directories": { 8 | "lib": "lib" 9 | }, 10 | "files": [ 11 | "lib" 12 | ], 13 | "scripts": { 14 | "build": "tsc --project tsconfig.json", 15 | "test": "jest --silent --passWithNoTests" 16 | }, 17 | "dependencies": { 18 | "aws-cdk-lib": "^2.32.0", 19 | "constructs": "^10.1.46" 20 | } 21 | } -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cdk/packages/compliant-s3-bucket/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "target": "ES2018", 5 | "module": "commonjs", 6 | "lib": ["es2018"], 7 | "declaration": true, 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "strictNullChecks": true, 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "inlineSourceMap": true, 18 | "inlineSources": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "types": ["node", "jest"] 22 | }, 23 | "exclude": ["cdk.out", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cfn/packages/dynamodb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dynamodb", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "description": "Test package for cypress testing" 6 | } -------------------------------------------------------------------------------- /source/cypress/fixtures/templaterepo/cfn/packages/dynamodb/template/dynamodb.template: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "1AWS CloudFormation Sample Template DynamoDB_Table: This template demonstrates the creation of a DynamoDB table. **WARNING** This template creates an Amazon DynamoDB table. You will be billed for the AWS resources used if you create a stack from this template.", 4 | "Parameters": { 5 | "HashKeyElementName": { 6 | "Description": "HashType PrimaryKey Name", 7 | "Type": "String", 8 | "AllowedPattern": "[a-zA-Z0-9]*", 9 | "MinLength": "1", 10 | "MaxLength": "2048", 11 | "ConstraintDescription": "must contain only alphanumberic characters" 12 | }, 13 | "HashKeyElementType": { 14 | "Description": "HashType PrimaryKey Type", 15 | "Type": "String", 16 | "Default": "S", 17 | "AllowedPattern": "[S|N]", 18 | "MinLength": "1", 19 | "MaxLength": "1", 20 | "ConstraintDescription": "must be either S or N" 21 | }, 22 | "ReadCapacityUnits": { 23 | "Description": "Provisioned read throughput", 24 | "Type": "Number", 25 | "Default": "5", 26 | "MinValue": "5", 27 | "MaxValue": "10000", 28 | "ConstraintDescription": "must be between 5 and 10000" 29 | }, 30 | "WriteCapacityUnits": { 31 | "Description": "Provisioned write throughput", 32 | "Type": "Number", 33 | "Default": "10", 34 | "MinValue": "5", 35 | "MaxValue": "10000", 36 | "ConstraintDescription": "must be between 5 and 10000" 37 | } 38 | }, 39 | "Resources": { 40 | "myDynamoDBTable": { 41 | "Type": "AWS::DynamoDB::Table", 42 | "Properties": { 43 | "AttributeDefinitions": [ 44 | { 45 | "AttributeName": { 46 | "Ref": "HashKeyElementName" 47 | }, 48 | "AttributeType": { 49 | "Ref": "HashKeyElementType" 50 | } 51 | } 52 | ], 53 | "KeySchema": [ 54 | { 55 | "AttributeName": { 56 | "Ref": "HashKeyElementName" 57 | }, 58 | "KeyType": "HASH" 59 | } 60 | ], 61 | "ProvisionedThroughput": { 62 | "ReadCapacityUnits": { 63 | "Ref": "ReadCapacityUnits" 64 | }, 65 | "WriteCapacityUnits": { 66 | "Ref": "WriteCapacityUnits" 67 | } 68 | } 69 | } 70 | } 71 | }, 72 | "Outputs": { 73 | "TableName": { 74 | "Value": { 75 | "Ref": "myDynamoDBTable" 76 | }, 77 | "Description": "Table name of the newly created DynamoDB table" 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /source/cypress/fixtures/testdata.json: -------------------------------------------------------------------------------- 1 | { 2 | "cfnPatternName": "cypress-test-cfn", 3 | "cdkPatternName": "cypress-test-cdk", 4 | "patternDescription": "Test desription", 5 | "cfnTestAttributeKey": "CypressCfnTestSecurityLevel", 6 | "cfnTestAttributeValue": "CypressCfnTestMedium", 7 | "cdkTestAttributeKey": "CypressCdkTestSecurityLevel", 8 | "cdkTestAttributeValue": "CypressCdkTestMedium", 9 | "formValidationTestAttributeKey": "CypressFormValidationTestAttrKey", 10 | "formValidationTestAttributeValue": "CypressFormValidationTestAttrVal", 11 | "testAttributeDescription": "Cypress Attribute Description", 12 | "newAttributeKey": "CypressDummyAttributeKey", 13 | "newAttributeValue": "CypressDummyAttributeValue", 14 | "newAttributeDescription": "CypressDummyAttributeDescription", 15 | "newAttributeMetaKey": "CypressDummyAttributeMetaKey", 16 | "newAttributeMetaValue": "CypressDummyAttributeMetaValue" 17 | } -------------------------------------------------------------------------------- /source/cypress/support/e2e.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import './commands'; 18 | -------------------------------------------------------------------------------- /source/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "roots": [ 3 | "/test" 4 | ], 5 | testMatch: [ '**/*.test.ts'], 6 | "transform": { 7 | "^.+\\.tsx?$": "ts-jest" 8 | }, 9 | coverageReporters: [ 10 | "text", 11 | ["lcov", {"projectRoot": "../"}] 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/.npmcheckrc: -------------------------------------------------------------------------------- 1 | { 2 | "depcheck": { 3 | "ignoreMatches": [ 4 | "@typescript-eslint/eslint-plugin", 5 | "@types/jest", 6 | "@typescript-eslint/parser", 7 | "eslint-config-prettier", 8 | "eslint-config-typescript", 9 | "eslint-plugin-header", 10 | "eslint-plugin-prettier", 11 | "prettier", 12 | "webpack-cli", 13 | "encoding" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "printWidth": 90, 4 | "semi": true, 5 | "singleQuote": true, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/LicenseHeader.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/__mocks__/@aws-sdk/client-ses.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"). 6 | You may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | export const mockSendFn = jest.fn(); 18 | 19 | export class SESClient { 20 | send = mockSendFn; 21 | } 22 | 23 | export class ListVerifiedEmailAddressesCommand { 24 | constructor(_input: any) { 25 | jest.fn(); 26 | } 27 | } 28 | 29 | export class SendTemplatedEmailCommand { 30 | constructor(_input: any) { 31 | jest.fn(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | phases: 3 | install: 4 | commands: 5 | # Install all dependencies (including dependencies for running tests) 6 | - npm install 7 | pre_build: 8 | commands: 9 | # Discover and run unit tests in the '__tests__' directory 10 | - npm run test 11 | # Remove all unit tests to reduce the size of the package that will be ultimately uploaded to Lambda 12 | - rm -rf ./__tests__ 13 | # Remove all dependencies not needed for the Lambda deployment package (the packages from devDependencies in package.json) 14 | - npm prune --production 15 | build: 16 | commands: 17 | # Use AWS SAM to package the application by using AWS CloudFormation 18 | - aws cloudformation package --template template.yml --s3-bucket $S3_BUCKET --output-template template-export.yml 19 | artifacts: 20 | type: zip 21 | files: 22 | - template-export.yml 23 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/env.json: -------------------------------------------------------------------------------- 1 | { 2 | "getAllItemsFunction": { 3 | "SAMPLE_TABLE": "" 4 | }, 5 | "getByIdFunction": { 6 | "SAMPLE_TABLE": "" 7 | }, 8 | "putItemFunction": { 9 | "SAMPLE_TABLE": "" 10 | } 11 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/events/event-get-all-items.json: -------------------------------------------------------------------------------- 1 | { 2 | "httpMethod": "GET" 3 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/events/event-get-by-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "httpMethod": "GET", 3 | "pathParameters": { 4 | "id": "id1" 5 | } 6 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/events/event-post-item.json: -------------------------------------------------------------------------------- 1 | { 2 | "httpMethod": "POST", 3 | "body": "{\"id\": \"id1\",\"name\": \"name1\"}" 4 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lerna-debug.log 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | cdk.context.json 8 | 9 | # Ignore typescript artifacts 10 | *.js 11 | !jest.config.js 12 | *.d.ts -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-solutions/application-pattern-orchestrator-on-aws/d762bc7c24ca12630fefbc336132398bbaec1cdb/source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/images/.gitkeep -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "independent", 6 | "command": { 7 | "version": { 8 | "conventionalCommits": true, 9 | "allowBranch": [ "{{branchName}}" ], 10 | "message": "chore(release): publish" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "description": "CDK based pattern", 4 | "license": "Apache-2.0", 5 | "workspaces": [ 6 | "packages/*" 7 | ], 8 | "scripts": { 9 | "build": "yarn workspaces run build", 10 | "test": "yarn workspaces run test", 11 | "synth": "yarn workspace cdk-test-app run synth" 12 | } 13 | } -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/packages/cdk-test-app/.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/packages/cdk-test-app/bin/cdk-test-app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"). 6 | You may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */ 17 | import 'source-map-support/register'; 18 | import * as cdk from 'aws-cdk-lib'; 19 | 20 | const app = new cdk.App(); 21 | new cdk.Stack(app); 22 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/packages/cdk-test-app/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts bin/cdk-test-app.ts", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "**/*.d.ts", 11 | "**/*.js", 12 | "tsconfig.json", 13 | "package*.json", 14 | "yarn.lock", 15 | "node_modules", 16 | "test" 17 | ] 18 | }, 19 | "context": { 20 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 21 | "@aws-cdk/core:stackRelativeExports": true, 22 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 23 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 24 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, 25 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, 26 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, 27 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, 28 | "@aws-cdk/core:target-partitions": [ 29 | "aws", 30 | "aws-cn" 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/packages/cdk-test-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cdk-test-app", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": "true", 6 | "description": "CDK Test app to generate CDK templates for all constructs.", 7 | "bin": { 8 | "cdk-test-app": "bin/cdk-test-app.js" 9 | }, 10 | "scripts": { 11 | "build": "tsc", 12 | "cdk": "cdk", 13 | "synth": "cdk synth -o ../../templates -q", 14 | "test": "echo 'Tests not implemented for this package'" 15 | }, 16 | "devDependencies": { 17 | "@types/jest": "^28.1.7", 18 | "@types/node": "^18.7.11", 19 | "aws-cdk": "^2.85.0", 20 | "jest": "^26.4.2", 21 | "ts-jest": "^28.0.8", 22 | "ts-node": "^10.9.1", 23 | "typescript": "^4.8.4" 24 | }, 25 | "dependencies": { 26 | "aws-cdk-lib": "^2.85.0", 27 | "constructs": "^10.1.84", 28 | "source-map-support": "^0.5.16" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cdk/packages/cdk-test-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2018" 7 | ], 8 | "declaration": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": [ 23 | "./node_modules/@types" 24 | ] 25 | }, 26 | "exclude": [ 27 | "node_modules", 28 | "cdk.out" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lerna-debug.log -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-solutions/application-pattern-orchestrator-on-aws/d762bc7c24ca12630fefbc336132398bbaec1cdb/source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/images/.gitkeep -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "independent", 6 | "command": { 7 | "version": { 8 | "conventionalCommits": true, 9 | "allowBranch": [ "{{branchName}}" ], 10 | "message": "chore(release): publish" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "description": "Cloudformation based pattern", 4 | "license": "Apache-2.0", 5 | "workspaces": [ 6 | "packages/*" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/packages/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-solutions/application-pattern-orchestrator-on-aws/d762bc7c24ca12630fefbc336132398bbaec1cdb/source/lambda/blueprintgovernanceservice/initialRepoTemplates/cfn/packages/.gitkeep -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/jest.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = { 3 | roots: [''], 4 | modulePaths: [''], 5 | testMatch: ['**/*.test.ts'], 6 | transform: { 7 | '^.+\\.tsx?$': 'ts-jest' 8 | }, 9 | collectCoverage: true, 10 | collectCoverageFrom: [ 11 | 'src/**/*.ts', 12 | '!src/common/Xray.ts', 13 | '!src/types/BlueprintType.ts', 14 | '!src/metrics/OperationalMetricHandler.ts', 15 | '!src/common/metrics/operational-metric.ts' 16 | ], 17 | verbose: true, 18 | 19 | coverageThreshold: { 20 | global: { 21 | branches: 70, 22 | functions: 80, 23 | lines: 80, 24 | statements: -80 25 | } 26 | }, 27 | reporters: [ 28 | 'default', 29 | [ 30 | 'jest-junit', 31 | { 32 | outputDirectory: './reports', 33 | outputName: 'test_report.xml' 34 | } 35 | ] 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/appregistry-updater/AppRegistryUpdateHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; 17 | import 'reflect-metadata'; 18 | import { AsyncRequestHandler } from '../common/AsyncRequestHandler'; 19 | import { syncAttribute } from '../common/Attribute'; 20 | import { getLogger } from '../common/BaseContainer'; 21 | import { BasicHttpResponse } from '../common/common-types'; 22 | 23 | // get logger 24 | const logger = getLogger('AppRegistryUpdateHandler'); 25 | 26 | export class AppRegistryUpdateHandler 27 | implements AsyncRequestHandler 28 | { 29 | // eslint-disable-next-line @typescript-eslint/naming-convention 30 | public async handle(event: SQSEvent, _context: Context): Promise { 31 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 32 | if (event.Records) { 33 | for (const record of event.Records) { 34 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 35 | if (record) { 36 | await this.processRecord(record); 37 | } 38 | } 39 | } 40 | return BasicHttpResponse.ofString(200, 'SUCCEED'); 41 | } 42 | 43 | public async processRecord(record: SQSRecord): Promise { 44 | let message: { id: string }; 45 | try { 46 | message = JSON.parse(record.body); 47 | logger.info(`id: ${message.id}`); 48 | 49 | /* eslint-disable-next-line */ 50 | } catch (e: any) { 51 | logger.error( 52 | `Invalid message received. Error: ${e.message}, Message:${record.body}`, 53 | ); 54 | throw new Error(`Invalid message received. Error: ${e.message}`); 55 | } 56 | 57 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 58 | if (message) { 59 | await syncAttribute(message.id); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/appregistry-updater/MainHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import middy from '@middy/core'; 18 | import { Context, SQSEvent } from 'aws-lambda'; 19 | import 'reflect-metadata'; 20 | import { container } from 'tsyringe'; 21 | import { getLogger } from '../common/BaseContainer'; 22 | import { BasicHttpResponse } from '../common/common-types'; 23 | import { AppConfiguration } from '../common/configuration/AppConfiguration'; 24 | import { ContextLoggingMiddleware } from '../common/logging'; 25 | import { LambdaHandler, MiddlewareChain } from '../common/middleware-chain'; 26 | import responseFormatter from '../common/response-formatter'; 27 | import { AppRegistryUpdateHandler } from './AppRegistryUpdateHandler'; 28 | 29 | export class MainHandler { 30 | public readonly lambdaHandler: LambdaHandler; 31 | public constructor(handler: AppRegistryUpdateHandler) { 32 | // setup middlewares 33 | const appConfig = container.resolve('AppConfiguration'); 34 | const middlewares = [ 35 | ContextLoggingMiddleware( 36 | appConfig.applicationName, 37 | container, 38 | appConfig.runningLocally, 39 | appConfig.logLevel, 40 | ), 41 | responseFormatter(), 42 | errorLogger(), 43 | ]; 44 | 45 | // main lambda handler 46 | this.lambdaHandler = new MiddlewareChain( 47 | handler, 48 | middlewares, 49 | ).lambdaHandler; 50 | } 51 | } 52 | 53 | function errorLogger(): middy.MiddlewareObj { 54 | const onError: middy.MiddlewareFn = async ( 55 | request, 56 | ): Promise => { 57 | const logger = getLogger('ErrorLoggingMiddleware'); 58 | 59 | logger.error('Error received - ', request.error); 60 | }; 61 | 62 | return { 63 | onError, 64 | }; 65 | } 66 | 67 | // main lambda handler 68 | const eventHandler = new AppRegistryUpdateHandler(); 69 | export const lambdaHandler = new MainHandler(eventHandler).lambdaHandler; 70 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/codecommit/trigger-security-scan.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { StartBuildCommand, CodeBuildClient } from '@aws-sdk/client-codebuild'; 18 | import * as lambda from 'aws-lambda'; 19 | import { getLogger } from '../common/BaseContainer'; 20 | import { awsSdkV3Configuration } from '../common/customUserAgent'; 21 | 22 | const codeBuildClient = new CodeBuildClient(awsSdkV3Configuration); 23 | 24 | export async function handler( 25 | event: lambda.SNSEvent, 26 | context: lambda.Context, 27 | ): Promise { 28 | const logger = getLogger('codecommit-trigger-security-scan'); 29 | logger.debug( 30 | `Processing event ${JSON.stringify(event)} with context ${JSON.stringify( 31 | context, 32 | )}`, 33 | ); 34 | const snsMessage = JSON.parse(event.Records[0].Sns.Message); 35 | const sourceCommitId = snsMessage.detail.sourceCommit; 36 | const destinationCommitId = snsMessage.detail.destinationCommit; 37 | const repositoryName = snsMessage.detail.repositoryNames[0]; 38 | const prId = snsMessage.detail.pullRequestId; 39 | await codeBuildClient.send( 40 | new StartBuildCommand({ 41 | projectName: `BlueprintChecks_${repositoryName}`, 42 | sourceVersion: sourceCommitId, 43 | environmentVariablesOverride: [ 44 | { 45 | name: 'BEFORE_COMMIT_ID', 46 | value: destinationCommitId, 47 | }, 48 | { 49 | name: 'AFTER_COMMIT_ID', 50 | value: sourceCommitId, 51 | }, 52 | { 53 | name: 'PR_NUMBER', 54 | value: prId, 55 | }, 56 | ], 57 | }), 58 | ); 59 | } 60 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/AppRegistrySyncRequestQueue.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import * as AWS from 'aws-sdk'; 17 | import { container } from 'tsyringe'; 18 | import { LoggerFactory } from '../common/logging'; 19 | import { AppConfiguration } from './configuration/AppConfiguration'; 20 | import { getUUID } from './Utils'; 21 | import { Logger } from './logging/logger-type'; 22 | /* eslint-disable @typescript-eslint/naming-convention */ 23 | 24 | const sqs = new AWS.SQS({ apiVersion: '2012-11-05' }); 25 | 26 | // get logger 27 | function getLogger(): Logger { 28 | return container 29 | .resolve('LoggerFactory') 30 | .getLogger('AppRegistryUpdateHandler'); 31 | } 32 | 33 | export async function addSyncRequestToQueue( 34 | id: string, 35 | ): Promise { 36 | const logger = getLogger(); 37 | // use try catch to make sure this function will not throw errors 38 | // this is to make sure the update in main tables will not be disturbed 39 | try { 40 | const appConfig = container.resolve('AppConfiguration'); 41 | return await sqs 42 | .sendMessage({ 43 | QueueUrl: appConfig.appRegistryUpdaterQueueUrl, 44 | MessageBody: JSON.stringify({ id, requestId: getUUID() }), 45 | MessageGroupId: 'appregistry-sync', 46 | }) 47 | .promise(); 48 | /* eslint-disable-next-line */ 49 | } catch (e: any) { 50 | logger.error( 51 | `Failed to send update message to AppRegistry Update Queue. Error: ${JSON.stringify( 52 | e, 53 | )}, ID: ${id} `, 54 | ); 55 | return undefined; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/AsyncRequestHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { AsyncHandlerObj } from './middleware-chain'; 17 | import { ServerlessResponse } from './ServerlessResponse'; 18 | export type AsyncRequestHandler = AsyncHandlerObj; 19 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/BaseContainer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import 'reflect-metadata'; 18 | import { container } from 'tsyringe'; 19 | import { BlueprintDBService } from '../service/BlueprintDBService'; 20 | import { AppConfiguration } from './configuration/AppConfiguration'; 21 | import { LoggerFactory, StaticLoggerFactory } from './logging'; 22 | import AWS, { ConfigurationOptions, EnvironmentCredentials } from 'aws-sdk'; 23 | import { Logger } from './logging/logger-type'; 24 | import { customUserAgentString } from './customUserAgent'; 25 | 26 | // register the global object in this file 27 | const appConfiguration = new AppConfiguration('BlueprintService'); 28 | 29 | const credentialProviderChain = new AWS.CredentialProviderChain(); 30 | credentialProviderChain.providers.push(new EnvironmentCredentials('AWS')); 31 | 32 | const configuration: ConfigurationOptions = { 33 | credentialProvider: credentialProviderChain, 34 | customUserAgent: customUserAgentString, 35 | }; 36 | 37 | // register global configure 38 | container.register('AppConfiguration', { 39 | useValue: appConfiguration, 40 | }); 41 | 42 | container.register('LoggerFactory', { 43 | useClass: StaticLoggerFactory, 44 | }); 45 | 46 | container.register('DocumentClient', { 47 | useValue: new AWS.DynamoDB.DocumentClient(configuration), 48 | }); 49 | 50 | container.register('BlueprintDBService', { 51 | useClass: BlueprintDBService, 52 | }); 53 | 54 | // get logger 55 | export function getLogger(name: string): Logger { 56 | return container 57 | .resolve('LoggerFactory') 58 | .getLogger(name, appConfiguration.logLevel); 59 | } 60 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/BlueprintError.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { BasicHttpError } from './common-types'; 17 | export default class BlueprintError extends BasicHttpError { 18 | /** 19 | * Application can specify the http status code and whether the request can be 20 | * retried by using this extended Error interface. Here is an example to throw 21 | * an error which has 501 http status code and is non-retryable: 22 | * 23 | * throw new BlueprintError('some error message', 501, false) 24 | */ 25 | public constructor(message?: string, statusCode?: number, retryable?: boolean) { 26 | super(statusCode || 200, message, retryable); 27 | this.name = 'BlueprintError'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/MainHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import 'reflect-metadata'; 18 | import { container } from 'tsyringe'; 19 | import { APIGatewayProxyEvent, Context } from 'aws-lambda'; 20 | import { MiddlewareChain, LambdaHandler } from './middleware-chain'; 21 | import { Router } from './router/Router'; 22 | import { BasicHttpResponse } from '../common/common-types'; 23 | import responseFormatter from './response-formatter'; 24 | import cors from '@middy/http-cors'; 25 | import { ContextLoggingMiddleware } from './logging'; 26 | import { AppConfiguration } from './configuration/AppConfiguration'; 27 | import middy from '@middy/core'; 28 | import { getLogger } from './BaseContainer'; 29 | 30 | export class MainHandler { 31 | public readonly lambdaHandler: LambdaHandler< 32 | APIGatewayProxyEvent, 33 | BasicHttpResponse, 34 | Context 35 | >; 36 | public constructor(router: Router) { 37 | // setup middlewares 38 | const appConfig = container.resolve('AppConfiguration'); 39 | 40 | const middlewares = [ 41 | ContextLoggingMiddleware( 42 | appConfig.applicationName, 43 | container, 44 | appConfig.runningLocally, 45 | appConfig.logLevel, 46 | ), 47 | responseFormatter(), 48 | errorLogger(), 49 | cors(), 50 | ]; 51 | 52 | // main lambda handler 53 | this.lambdaHandler = new MiddlewareChain( 54 | router, 55 | middlewares, 56 | ).lambdaHandler; 57 | } 58 | } 59 | 60 | function errorLogger(): middy.MiddlewareObj { 61 | const onError: middy.MiddlewareFn = async ( 62 | request, 63 | ): Promise => { 64 | const logger = getLogger('ErrorLoggingMiddleware'); 65 | 66 | logger.error('Error received - ', request.error); 67 | }; 68 | 69 | return { 70 | onError, 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/ServerlessResponse.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | export { BasicHttpResponse as ServerlessResponse } from '../common/common-types'; 17 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/Utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { v4 as uuidv4 } from 'uuid'; 17 | 18 | export const getUUID = (): string => uuidv4(); 19 | 20 | export const isValidJSON = (json: string): boolean => { 21 | try { 22 | JSON.parse(json); 23 | return true; 24 | } catch (err) { 25 | return false; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/Xray.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import AWS from 'aws-sdk'; 17 | import https from 'https'; 18 | import AWSXRay from 'aws-xray-sdk'; 19 | import { Logger } from './logging'; 20 | import { container } from 'tsyringe'; 21 | 22 | const logger: Logger = container.resolve('Logger'); 23 | 24 | // SAM Local doesn't support XRay: https://github.com/aws/aws-sam-cli/issues/217 25 | // Only enable XRay when it is not SAM 26 | if (!process.env.AWS_SAM_LOCAL) { 27 | // Capture all downstream AWS requests 28 | AWSXRay.captureAWS(AWS); 29 | 30 | // Capture all outgoing https requests 31 | AWSXRay.captureHTTPsGlobal(https, true); 32 | 33 | // Set XRay Logger 34 | AWSXRay.setLogger(logger); 35 | } 36 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/customUserAgent.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { UserAgent } from '@aws-sdk/types'; 17 | import { environmentVariables } from './configuration/AppConfiguration'; 18 | 19 | export const customUserAgentString = 20 | process.env[environmentVariables.UserAgent] ?? 'AwsSolution/SO0178/v1.0.0'; 21 | 22 | export const customUserAgentV3: UserAgent = [ 23 | [ 24 | customUserAgentString.slice(0, customUserAgentString.lastIndexOf('/')), 25 | customUserAgentString.slice(customUserAgentString.lastIndexOf('/') + 1), 26 | ], 27 | ]; 28 | 29 | export const awsSdkV3Configuration = { 30 | region: process.env.AWS_REGION, 31 | customUserAgent: customUserAgentV3, 32 | }; 33 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/logging/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | export * from './logger-type'; 17 | 18 | export * from './logger-factory'; 19 | 20 | export * from './context-logging-middleware'; 21 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/logging/logger-type.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ 18 | type LoggerMethodType = (message: string, ...meta: any[]) => void; 19 | 20 | export interface Logger { 21 | error: LoggerMethodType; 22 | warn: LoggerMethodType; 23 | info: LoggerMethodType; 24 | verbose: LoggerMethodType; 25 | debug: LoggerMethodType; 26 | silly: LoggerMethodType; 27 | defaultMeta?: Record; 28 | } 29 | 30 | export interface LoggerOptions { 31 | logLevel: string; 32 | } 33 | 34 | export type LogLevelType = 'error' | 'warn' | 'info' | 'verbose' | 'debug' | 'silly'; 35 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/metrics/operational-metric.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable @typescript-eslint/naming-convention */ 17 | import axios, { AxiosRequestConfig } from 'axios'; 18 | import moment from 'moment'; 19 | import { getLogger } from '../BaseContainer'; 20 | 21 | const METRICS_ENDPOINT = 'https://metrics.awssolutionsbuilder.com/generic'; 22 | const logger = getLogger('OperationalMetrics'); 23 | 24 | export interface MetricsPayload { 25 | awsSolutionId: string; 26 | awsSolutionVersion: string; 27 | anonymousDataUUID: string; 28 | data: unknown; 29 | } 30 | 31 | export async function sendAnonymousMetric(payload: MetricsPayload): Promise { 32 | try { 33 | const payloadStr = JSON.stringify({ 34 | Solution: payload.awsSolutionId, 35 | Version: payload.awsSolutionVersion, 36 | UUID: payload.anonymousDataUUID, 37 | TimeStamp: moment.utc().format('YYYY-MM-DD HH:mm:ss.S'), 38 | Data: payload.data, 39 | }); 40 | 41 | const config: AxiosRequestConfig = { 42 | headers: { 43 | 'content-type': 'application/json', 44 | 'content-length': payloadStr.length, 45 | }, 46 | }; 47 | 48 | logger.info(`Sending anonymous metric ${JSON.stringify(payloadStr)}`); 49 | const response = await axios.post(METRICS_ENDPOINT, payloadStr, config); 50 | logger.info( 51 | `Anonymous metric response: ${response.statusText} (${response.status})`, 52 | ); 53 | return 'Succeeded'; 54 | } catch (err) { 55 | // Log the error 56 | logger.error(`Error sending anonymous metric: ${JSON.stringify(err)}`); 57 | return (err as Error).message; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/middleware-chain.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { Context, Callback } from 'aws-lambda'; 17 | import middy from '@middy/core'; 18 | 19 | export type LambdaHandler = ( 20 | event: T, 21 | context: C, 22 | callback: Callback, 23 | // eslint-disable-next-line @typescript-eslint/no-invalid-void-type 24 | ) => void | Promise; 25 | 26 | type AsyncHandler = (event: T, context: C) => Promise; 27 | 28 | export interface AsyncHandlerObj { 29 | handle: AsyncHandler; 30 | } 31 | 32 | export class MiddlewareChain { 33 | public readonly lambdaHandler: LambdaHandler; 34 | public constructor( 35 | asyncHandlerObj: AsyncHandlerObj, 36 | middlewares: middy.MiddlewareObj[], 37 | ) { 38 | const middyHandler = middy( 39 | asyncHandlerObj.handle.bind(asyncHandlerObj) as AsyncHandler, 40 | ); 41 | middyHandler.use(middlewares); 42 | // eslint-disable-next-line @typescript-eslint/no-invalid-void-type 43 | this.lambdaHandler = (event: T, context: C): Promise | void => 44 | middyHandler(event, context, (null) as Callback); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/response-formatter.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import middy from '@middy/core'; 17 | import { BasicHttpResponse, BasicHttpError } from './common-types'; 18 | 19 | type ConfigType = { 20 | headers: Record; 21 | }; 22 | const defaultConfig: ConfigType = { 23 | headers: {}, 24 | }; 25 | const responseFormatter = ( 26 | config: ConfigType = defaultConfig, 27 | ): middy.MiddlewareObj => { 28 | const addHeaders = ( 29 | request: middy.Request, 30 | additonalHeaders?: Record, 31 | ): void => { 32 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 33 | request.response.headers = Object.assign( 34 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 35 | // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 36 | request?.response?.headers || {}, 37 | additonalHeaders, 38 | ); 39 | }; 40 | 41 | const after: middy.MiddlewareFn = async (request): Promise => { 42 | addHeaders(request, config.headers); 43 | }; 44 | 45 | const onError: middy.MiddlewareFn = async (request): Promise => { 46 | if (request.error instanceof BasicHttpError) { 47 | request.response = BasicHttpResponse.ofError(request.error) as unknown as R; 48 | addHeaders(request, config.headers); 49 | } else { 50 | // other exceptions, respond with 500 - Internal Server Error 51 | request.response = BasicHttpResponse.ofError( 52 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion 53 | BasicHttpError.internalServerError(request.error!.message), 54 | ) as unknown as R; 55 | } 56 | }; 57 | 58 | return { 59 | after, 60 | onError, 61 | }; 62 | }; 63 | 64 | export default responseFormatter; 65 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/router/RouteData.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { BasicHttpResponse } from '../common-types'; 17 | import { AsyncHandlerObj } from '../middleware-chain'; 18 | import { APIGatewayProxyEvent } from 'aws-lambda'; 19 | import { InjectionToken } from 'tsyringe'; 20 | 21 | export interface RouteData< 22 | TResponse extends BasicHttpResponse, 23 | THandler extends AsyncHandlerObj, 24 | > { 25 | predicate: (event: APIGatewayProxyEvent) => boolean; 26 | handlerToken: InjectionToken; 27 | } 28 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/router/Router.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { BasicHttpError, BasicHttpResponse } from '../common-types'; 17 | import { AsyncHandlerObj } from '../middleware-chain'; 18 | import { APIGatewayProxyEvent, Context } from 'aws-lambda'; 19 | import { InjectionToken } from 'tsyringe'; 20 | import { RouteData } from './RouteData'; 21 | import { LoggingContext } from '../logging'; 22 | 23 | export class Router 24 | implements AsyncHandlerObj 25 | { 26 | private readonly routes: RouteData< 27 | TResponse, 28 | AsyncHandlerObj 29 | >[] = []; 30 | 31 | public addRoute>( 32 | predicate: (event: APIGatewayProxyEvent) => boolean, 33 | handlerToken: InjectionToken, 34 | ): Router { 35 | this.routes.push({ predicate, handlerToken: handlerToken }); 36 | return this; 37 | } 38 | 39 | public handle( 40 | event: APIGatewayProxyEvent, 41 | context: Context, 42 | ): Promise { 43 | const route = this.routes.find((r) => r.predicate(event)); 44 | 45 | if (route) { 46 | const iocContainer = (context as LoggingContext).loggingContextContainer; 47 | 48 | return iocContainer.resolve(route.handlerToken).handle(event, context); 49 | } 50 | 51 | return Promise.resolve( 52 | BasicHttpResponse.ofError( 53 | new BasicHttpError( 54 | 404, 55 | `Could not find a matching route for ${event.httpMethod} ${event.resource} ${event.path}`, 56 | false, 57 | ), 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/common/validator/ValidatorCommon.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import isString from 'lodash.isstring'; 17 | 18 | export const regKeyValueAllowEmptyString = /^[-\w]{0,120}$/; 19 | 20 | export const regKeyValue = /^[-\w]{1,120}$/; 21 | 22 | export const regDescription = /^.{1,1024}$/; 23 | 24 | export const regTagKey = /^(?!aws:)[a-zA-Z+\-=._:/]{1,128}$/; 25 | 26 | export const regTagValue = /^[\w.:/=+\-@]{1,256}$/; 27 | 28 | export const regTagValueAllowEmptyString = /^[\w.:/=+\-@]{0,256}$/; 29 | 30 | export function isInvalidArgument(reg: RegExp, value: string): boolean { 31 | return !isString(value) || value.trim().length === 0 || !reg.test(value); 32 | } 33 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/handlers/GetSubscriptionHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { APIGatewayProxyEvent, Context } from 'aws-lambda'; 17 | import { inject, injectable } from 'tsyringe'; 18 | import { AsyncRequestHandler } from '../common/AsyncRequestHandler'; 19 | import { ServerlessResponse } from '../common/ServerlessResponse'; 20 | import { BlueprintDBService } from '../service/BlueprintDBService'; 21 | 22 | /** 23 | * @api {get} /subscriptions Get subscription for a pattern and email id 24 | * @apiName GetSubscription 25 | * @apiGroup Subscription 26 | * @apiDescription Returns subscription data for a pattern and email id 27 | * @apiVersion 1.0.0 28 | * @apiParam (Query string) {String} patternId Pattern Id 29 | * @apiParam (Query string) {String} email Subscriber's email address 30 | * 31 | * @apiSuccessExample Success-Response: 32 | * HTTP/1.1 200 OK 33 | * { 34 | "email": "test@testdomain.com", 35 | "patternId": "test-pattern-id" 36 | } 37 | * @apiSampleRequest off 38 | */ 39 | @injectable() 40 | export class GetSubscriptionHandler 41 | implements AsyncRequestHandler 42 | { 43 | public constructor( 44 | @inject('BlueprintDBService') private readonly db: BlueprintDBService, 45 | ) {} 46 | 47 | public async handle( 48 | event: APIGatewayProxyEvent, 49 | // eslint-disable-next-line @typescript-eslint/naming-convention 50 | _context: Context, 51 | ): Promise { 52 | const patternId = event.queryStringParameters?.['patternId']; 53 | const email = event.queryStringParameters?.['email']; 54 | 55 | if (!patternId || !email) { 56 | return ServerlessResponse.ofObject( 57 | 400, 58 | 'patternId and email must not be null or empty.', 59 | ); 60 | } 61 | 62 | const subs = await this.db.getNotificationSubscription(patternId, email); 63 | 64 | return subs 65 | ? ServerlessResponse.ofObject(200, subs) 66 | : ServerlessResponse.ofObject(404, {}); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/metrics/OperationalMetricHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable @typescript-eslint/naming-convention */ 17 | import { 18 | CloudFormationCustomResourceEvent, 19 | CloudFormationCustomResourceSuccessResponse, 20 | } from 'aws-lambda'; 21 | import { sendAnonymousMetric } from '../common/metrics/operational-metric'; 22 | import { v4 as uuidv4 } from 'uuid'; 23 | 24 | export async function handler( 25 | event: CloudFormationCustomResourceEvent, 26 | ): Promise { 27 | const { 28 | awsSolutionId, 29 | awsSolutionVersion, 30 | awsRegion, 31 | sendAnonymousData, 32 | retainData, 33 | patternType, 34 | } = event.ResourceProperties; 35 | 36 | // Randomly generated, unique identifier for each Solution deployment 37 | let anonymousDataUUID = ''; 38 | 39 | switch (event.RequestType) { 40 | case 'Create': 41 | // only create anonymous uuid for create event 42 | anonymousDataUUID = uuidv4(); 43 | break; 44 | 45 | case 'Update': 46 | case 'Delete': 47 | anonymousDataUUID = event.PhysicalResourceId; 48 | break; 49 | } 50 | 51 | // send anonymous metrics data 52 | const result = await sendAnonymousMetric({ 53 | awsSolutionId, 54 | awsSolutionVersion, 55 | anonymousDataUUID, 56 | data: { 57 | region: awsRegion, 58 | requestType: event.RequestType, 59 | sendAnonymousData, 60 | retainData, 61 | patternType, 62 | }, 63 | }); 64 | 65 | return { 66 | RequestId: event.RequestId, 67 | LogicalResourceId: event.LogicalResourceId, 68 | PhysicalResourceId: anonymousDataUUID, 69 | Data: { 70 | anonymousDataUUID, 71 | sendAnonymousData, 72 | }, 73 | StackId: event.StackId, 74 | Status: 'SUCCESS', 75 | Reason: result, 76 | }; 77 | } 78 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/service/Id.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * String to slug 19 | * @param name 20 | * @returns 21 | */ 22 | export function stringToSlug(name: string): string { 23 | name = name.trim(); 24 | name = name.toLowerCase(); 25 | 26 | // remove accents, swap ñ for n, etc 27 | const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;'; 28 | const to = 'aaaaeeeeiiiioooouuuunc------'; 29 | for (let i = 0, l = from.length; i < l; i++) { 30 | name = name.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); 31 | } 32 | 33 | name = name 34 | .replace(/[^a-z0-9 -]/g, '') // remove invalid chars 35 | .replace(/\s+/g, '-') // collapse whitespace and replace by - 36 | .replace(/-+/g, '-'); // collapse dashes 37 | 38 | return name; 39 | } 40 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/service/blueprint-repo-builder/IBlueprintRepoBuilderService.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { PatternType } from '../../common/common-types'; 17 | import { BlueprintCodeRepoDetails } from '../../types/BlueprintType'; 18 | 19 | export const blueprintRepoBuilderServiceConstants = { 20 | rootInitialRepoDir: 'initialRepoTemplates', 21 | }; 22 | 23 | export interface IBlueprintRepoBuilderService { 24 | /** 25 | * Create pattern repository and initialises it with initial code structure 26 | * @param repoName 27 | * @param patternType 28 | */ 29 | createAndInitializeRepo( 30 | repoName: string, 31 | patternType: PatternType, 32 | ): Promise; 33 | 34 | /** 35 | * In case of an error in initialising the repo rollback the repo creation. 36 | */ 37 | deleteRepo(repoName: string): Promise; 38 | } 39 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/src/timed-synchroniser/MainHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import middy from '@middy/core'; 18 | import 'reflect-metadata'; 19 | import { container } from 'tsyringe'; 20 | import { getLogger } from '../common/BaseContainer'; 21 | import { BasicHttpResponse } from '../common/common-types'; 22 | import { AppConfiguration } from '../common/configuration/AppConfiguration'; 23 | import { ContextLoggingMiddleware } from '../common/logging'; 24 | import { LambdaHandler, MiddlewareChain } from '../common/middleware-chain'; 25 | import responseFormatter from '../common/response-formatter'; 26 | import { EventType, SyncEventHandler } from './SyncEventHandler'; 27 | 28 | export class MainHandler { 29 | public readonly lambdaHandler: LambdaHandler; 30 | public constructor(handler: SyncEventHandler) { 31 | const appConfig = container.resolve('AppConfiguration'); 32 | const middlewares = [ 33 | ContextLoggingMiddleware( 34 | appConfig.applicationName, 35 | container, 36 | appConfig.runningLocally, 37 | appConfig.logLevel, 38 | ), 39 | responseFormatter(), 40 | errorLogger(), 41 | ]; 42 | 43 | // main lambda handler 44 | this.lambdaHandler = new MiddlewareChain( 45 | handler, 46 | middlewares, 47 | ).lambdaHandler; 48 | } 49 | } 50 | 51 | function errorLogger(): middy.MiddlewareObj { 52 | const onError: middy.MiddlewareFn = async ( 53 | request, 54 | ): Promise => { 55 | const logger = getLogger('ErrorLoggingMiddleware'); 56 | logger.error('Error received - ', request.error); 57 | }; 58 | 59 | return { 60 | onError, 61 | }; 62 | } 63 | 64 | // main lambda handler 65 | const eventHandler = new SyncEventHandler(); 66 | export const lambdaHandler = new MainHandler(eventHandler).lambdaHandler; 67 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/appregistry-updater/AppRegistryUpdateHandler.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import '../../../src/common/BaseContainer'; 17 | import { SQSEvent, Context } from 'aws-lambda'; 18 | import { AppRegistryUpdateHandler } from '../../../src/appregistry-updater/AppRegistryUpdateHandler'; 19 | import { syncAttribute } from '../../../src/common/Attribute'; 20 | 21 | jest.mock('src/common/Attribute'); 22 | jest.mock('src/service/AppRegistryIntegrationService'); 23 | 24 | const mockedSyncAttribute = syncAttribute as jest.MockedFunction; 25 | 26 | const event = { 27 | // eslint-disable-next-line @typescript-eslint/naming-convention 28 | Records: [ 29 | { 30 | body: JSON.stringify({ id: 'TEST-ATTRIBUTE-1' }), 31 | }, 32 | { 33 | body: JSON.stringify({ id: 'TEST-ATTRIBUTE-2' }), 34 | }, 35 | ], 36 | }; 37 | 38 | describe('AppRegistryUpdateHandler test', () => { 39 | beforeEach(() => { 40 | jest.clearAllMocks(); 41 | mockedSyncAttribute.mockClear(); 42 | mockedSyncAttribute.mockReset(); 43 | }); 44 | 45 | test('test success event', async () => { 46 | const handler = new AppRegistryUpdateHandler(); 47 | 48 | mockedSyncAttribute.mockResolvedValueOnce().mockResolvedValueOnce(); 49 | 50 | const result = await handler.handle(event as SQSEvent, {} as Context); 51 | 52 | expect(result).toEqual({ 53 | body: 'SUCCEED', 54 | headers: { 55 | // eslint-disable-next-line @typescript-eslint/naming-convention 56 | 'Content-Type': 'text/plain', 57 | }, 58 | statusCode: 200, 59 | }); 60 | 61 | expect(mockedSyncAttribute).toBeCalledTimes(2); 62 | expect(mockedSyncAttribute.mock.calls[0]).toEqual(['TEST-ATTRIBUTE-1']); 63 | expect(mockedSyncAttribute.mock.calls[1]).toEqual(['TEST-ATTRIBUTE-2']); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/appregistry-updater/MainHandler.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { SQSEvent, Context, SQSRecord } from 'aws-lambda'; 17 | import '../../../src/common/BaseContainer'; 18 | import { AppRegistryUpdateHandler } from '../../../src/appregistry-updater/AppRegistryUpdateHandler'; 19 | import { MainHandler } from '../../../src/appregistry-updater/MainHandler'; 20 | 21 | class TestHandler extends AppRegistryUpdateHandler { 22 | public handle = jest.fn(); 23 | } 24 | 25 | describe('Main Handler test', () => { 26 | test('test handler invoke', async () => { 27 | const handler = new TestHandler(); 28 | const lambdaHandler = new MainHandler(handler).lambdaHandler; 29 | handler.handle.mockResolvedValueOnce({ result: 'SUCCEED' }); 30 | const event: SQSEvent = { 31 | // eslint-disable-next-line @typescript-eslint/naming-convention 32 | Records: [{} as SQSRecord], 33 | }; 34 | const result = await lambdaHandler(event, {} as Context, jest.fn()); 35 | console.log(JSON.stringify(result, null, 4)); 36 | expect(result).toEqual({ result: 'SUCCEED', headers: {} }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/codecommit/trigger-security-scan.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import { handler } from '../../../src/codecommit/trigger-security-scan'; 18 | import { mockClient } from 'aws-sdk-client-mock'; 19 | import { SNSEvent, Context } from 'aws-lambda'; 20 | import { StartBuildCommand, CodeBuildClient } from '@aws-sdk/client-codebuild'; 21 | 22 | const codeBuildClientMock = mockClient(CodeBuildClient); 23 | 24 | beforeEach(() => { 25 | codeBuildClientMock.reset(); 26 | }); 27 | 28 | describe('Trigger Security check codebuild handler tests', () => { 29 | test('Trigger Security check codebuild handler', async () => { 30 | await handler( 31 | { 32 | // eslint-disable-next-line @typescript-eslint/naming-convention 33 | Records: [ 34 | { 35 | // eslint-disable-next-line @typescript-eslint/naming-convention 36 | Sns: { 37 | // eslint-disable-next-line @typescript-eslint/naming-convention 38 | Message: JSON.stringify({ 39 | detail: { 40 | sourceCommit: '111', 41 | destinationCommit: '222', 42 | pullRequestId: '1', 43 | repositoryNames: ['testRepoName'], 44 | }, 45 | }), 46 | }, 47 | }, 48 | ], 49 | } as unknown as SNSEvent, 50 | {} as unknown as Context, 51 | ); 52 | expect(codeBuildClientMock.calls()).toHaveLength(1); 53 | expect(codeBuildClientMock.call(0).firstArg).toBeInstanceOf(StartBuildCommand); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/common/providers/DependencyConfigurationProvider.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import 'reflect-metadata'; 17 | import { instance, mock, when } from 'ts-mockito'; 18 | import { AppConfiguration } from '../../../../src/common/configuration/AppConfiguration'; 19 | import { DependencyConfigurationProvider } from '../../../../src/common/providers/DependencyConfigurationProvider'; 20 | import AWS from 'aws-sdk'; 21 | 22 | const secretsManagergetSecretValue = { 23 | getSecretValue: jest.fn().mockReturnThis(), 24 | // eslint-disable-next-line @typescript-eslint/naming-convention 25 | promise: jest.fn().mockReturnValue({ SecretString: 'testSecret' }), 26 | }; 27 | jest.mock('aws-sdk', () => { 28 | // eslint-disable-next-line @typescript-eslint/naming-convention 29 | return { SecretsManager: jest.fn(() => secretsManagergetSecretValue) }; 30 | }); 31 | 32 | describe('DependencyConfigurationProvider - getSecret and getSSM mock', () => { 33 | test('should successfully mock getAGSAttestationAuthorityId function ', async () => { 34 | // const mockGetParameter = jest.fn(); 35 | 36 | const testingAppConfiguration = mock(AppConfiguration); 37 | 38 | const dependencyConfigurationProvider: DependencyConfigurationProvider = 39 | new DependencyConfigurationProvider( 40 | instance(testingAppConfiguration), 41 | new AWS.SecretsManager(), 42 | ); 43 | when(testingAppConfiguration.getDepdencyFor('BLUEPRINTGOVERNANCE')).thenReturn({ 44 | name: 'BLUEPRINTGOVERNANCE', 45 | githubTokenSecretId: 'githubTokenSecretId', 46 | }); 47 | const value = 48 | await dependencyConfigurationProvider.getBlueprintServiceRepoCredentials( 49 | 'BLUEPRINTGOVERNANCE', 50 | ); 51 | 52 | expect(value).toEqual('testSecret'); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/common/winston.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable */ 17 | export const mockLogFunction = jest.fn(); 18 | 19 | interface LoggerType { 20 | log: (level: string, message: string, ...meta: any[]) => LoggerType; 21 | } 22 | 23 | class MockLogger implements LoggerType { 24 | log = mockLogFunction; 25 | child(): LoggerType { 26 | return new MockLogger(); 27 | } 28 | } 29 | 30 | export default { 31 | createLogger: (): LoggerType => { 32 | return new MockLogger(); 33 | }, 34 | format: { 35 | simple: jest.fn(), 36 | 37 | combine: jest.fn(), 38 | timestamp: jest.fn(), 39 | splat: jest.fn(), 40 | json: jest.fn(), 41 | }, 42 | transports: { 43 | Console: jest.fn(), 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/configuration/AppConfiguration.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { AppConfiguration } from '../../../src/common/configuration/AppConfiguration'; 17 | 18 | describe('Test AppConfiguration.test', () => { 19 | // eslint-disable-next-line @typescript-eslint/naming-convention 20 | const ORIGINAL_ENV = process.env; 21 | 22 | beforeEach(() => { 23 | jest.resetModules(); 24 | process.env = { ...ORIGINAL_ENV }; 25 | }); 26 | afterEach(() => { 27 | process.env = ORIGINAL_ENV; 28 | }); 29 | 30 | test('should retrieve depdencies configuration', () => { 31 | process.env.LOG_LEVEL = 'debug'; 32 | process.env.githubTokenSecretId = 'githubTokenSecretId'; 33 | const objectUnderTest = new AppConfiguration('test-app'); 34 | expect( 35 | objectUnderTest.getDepdencyFor('BLUEPRINTGOVERNANCE')?.githubTokenSecretId, 36 | ).toEqual('githubTokenSecretId'); 37 | }); 38 | 39 | test('no default key when configuration missing', () => { 40 | const objectUnderTest = new AppConfiguration('test-app'); 41 | expect(objectUnderTest.getDepdencyFor('BLUEPRINTGOVERNANCE')?.name).toEqual( 42 | 'BLUEPRINTGOVERNANCE', 43 | ); 44 | }); 45 | 46 | test('no default key when configuration missing endpoint key', () => { 47 | process.env.ATTESTATION_ENDPOINT_KEY = undefined; 48 | const objectUnderTest = new AppConfiguration('test-app'); 49 | expect( 50 | objectUnderTest.getDepdencyFor('BLUEPRINTGOVERNANCE')?.githubTokenSecretId, 51 | ).toBeUndefined(); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/handlers/GetSubscriptionHandler.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import 'reflect-metadata'; 17 | import { APIGatewayProxyEvent, Context } from 'aws-lambda'; 18 | import { anything, instance, mock, when } from 'ts-mockito'; 19 | import { GetSubscriptionHandler } from '../../../src/handlers/GetSubscriptionHandler'; 20 | import { BlueprintDBService } from '../../../src/service/BlueprintDBService'; 21 | 22 | const db = mock(BlueprintDBService); 23 | const handler = new GetSubscriptionHandler(instance(db)); 24 | 25 | describe('Get subscription handler tests', () => { 26 | test('returns 400 if patternid or email is missing', async () => { 27 | // act 28 | const result = await handler.handle({} as APIGatewayProxyEvent, {} as Context); 29 | 30 | // assert 31 | expect(result.statusCode).toBe(400); 32 | }); 33 | 34 | test('returns 404 if not found', async () => { 35 | // arrange 36 | when(db.getNotificationSubscription(anything(), anything())).thenResolve( 37 | undefined, 38 | ); 39 | 40 | // act 41 | const result = await handler.handle( 42 | { 43 | queryStringParameters: { patternId: '1234', email: 'test' }, 44 | } as unknown as APIGatewayProxyEvent, 45 | {} as Context, 46 | ); 47 | 48 | // assert 49 | expect(result.statusCode).toBe(404); 50 | }); 51 | 52 | test('can get notification subs', async () => { 53 | // arrange 54 | when(db.getNotificationSubscription(anything(), anything())).thenResolve({}); 55 | 56 | // act 57 | const result = await handler.handle( 58 | { 59 | queryStringParameters: { patternId: '1234', email: 'test' }, 60 | } as unknown as APIGatewayProxyEvent, 61 | {} as Context, 62 | ); 63 | 64 | // assert 65 | expect(result.statusCode).toBe(200); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/services/Id.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { stringToSlug } from '../../../src/service/Id'; 17 | 18 | describe('stringToSlug tests', () => { 19 | test('can construct object url', () => { 20 | // act 21 | const name = 'data blueprint sample'; 22 | 23 | const id = stringToSlug(name); 24 | // assert 25 | expect(id).toBe('data-blueprint-sample'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/test/unit/timed-synchroniser/MainHandler.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import { EventBridgeEvent, Context } from 'aws-lambda'; 17 | import '../../../src/common/BaseContainer'; 18 | import { MainHandler } from '../../../src/timed-synchroniser/MainHandler'; 19 | import { SyncEventHandler } from '../../../src/timed-synchroniser/SyncEventHandler'; 20 | 21 | class TestHandler extends SyncEventHandler { 22 | public handle = jest.fn(); 23 | } 24 | 25 | describe('Main Handler test', () => { 26 | test('test handler invoke', async () => { 27 | const handler = new TestHandler(); 28 | const lambdaHandler = new MainHandler(handler).lambdaHandler; 29 | handler.handle.mockResolvedValueOnce({ result: 'SUCCEED' }); 30 | const event = {} as EventBridgeEvent; 31 | const result = await lambdaHandler(event, {} as Context, jest.fn()); 32 | expect(result).toEqual({ result: 'SUCCEED', headers: {} }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /source/lambda/blueprintgovernanceservice/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // eslint-disable-next-line @typescript-eslint/naming-convention 18 | const FileManagerPlugin = require('filemanager-webpack-plugin'); 19 | const path = require('path'); 20 | 21 | const commonConfigOptions = { 22 | // Create source maps 23 | devtool: 'source-map', 24 | // Resolve .ts and .js extensions 25 | resolve: { 26 | extensions: ['.ts', '.js'], 27 | }, 28 | // Target node 29 | target: 'node', 30 | // Set the webpack mode 31 | mode: process.env.NODE_ENV || 'production', 32 | // Add the TypeScript loader 33 | module: { 34 | rules: [ 35 | { 36 | test: /\.tsx?$/, 37 | loader: 'ts-loader', 38 | }, 39 | ], 40 | }, 41 | externals: {}, 42 | output: { 43 | filename: '[name]/[name].js', 44 | libraryTarget: 'commonjs2', 45 | path: path.resolve(__dirname, 'dist'), 46 | }, 47 | }; 48 | 49 | module.exports = [ 50 | { 51 | ...commonConfigOptions, 52 | entry: { 53 | main: './src/App.ts', 54 | }, 55 | plugins: [ 56 | new FileManagerPlugin({ 57 | events: { 58 | onEnd: { 59 | copy: [ 60 | { 61 | source: 'initialRepoTemplates', 62 | destination: 63 | 'dist/blueprintgovernanceservice/initialRepoTemplates', 64 | }, 65 | ], 66 | }, 67 | }, 68 | }), 69 | ], 70 | output: { 71 | filename: 'blueprintgovernanceservice/app.js', 72 | libraryTarget: 'commonjs2', 73 | path: path.resolve(__dirname, 'dist'), 74 | }, 75 | }, 76 | 77 | { 78 | ...commonConfigOptions, 79 | entry: { 80 | appRegistryUpdater: './src/appregistry-updater/MainHandler.ts', 81 | timedSynchroniser: './src/timed-synchroniser/MainHandler.ts', 82 | }, 83 | }, 84 | ]; 85 | -------------------------------------------------------------------------------- /source/lib/blueprint-environment.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | /* eslint-disable @typescript-eslint/naming-convention */ 17 | export const environmentVariables = { 18 | PROXY_URI: 'PROXY_URI', 19 | RAPM_METADATA_TABLE_NAME: 'RAPM_METADATA_TABLE_NAME', 20 | RAPM_PUBLISH_DATA_TABLE_NAME: 'RAPM_PUBLISH_DATA_TABLE_NAME', 21 | RAPM_ATTRIBUTES_TABLE_NAME: 'RAPM_ATTRIBUTES_TABLE_NAME', 22 | APPREGISTRY_UPDATER_QUEUE_URL: 'APPREGISTRY_UPDATER_QUEUE_URL', 23 | GITHUB_TOKEN_SECRET_ID: 'githubTokenSecretId', 24 | BLUEPRINT_CODE_BUILD_JOB_PROJECT_NAME: 'BLUEPRINT_CODE_BUILD_JOB_PROJECT_NAME', 25 | BLUEPRINT_BUCKET_NAME: 'BLUEPRINT_BUCKET_NAME', 26 | S3_BUCKET_NAME: 'S3_BUCKET_NAME', 27 | GITHUB_URL: 'GITHUB_URL', 28 | CODEOWNERS: 'CODEOWNERS', 29 | GITHUB_ORGANIZATION: 'GITHUB_ORGANIZATION', 30 | ANONYMOUS_DATA_UUID: 'ANONYMOUS_DATA_UUID', 31 | SOLUTION_ID: 'SOLUTION_ID', 32 | SOLUTION_VERSION: 'SOLUTION_VERSION', 33 | SOLUTION_USER_AGENT: 'SOLUTION_USER_AGENT', 34 | PATTERN_EMAIL_MAPPING_TABLE_NAME: 'PATTERN_EMAIL_MAPPING_TABLE_NAME', 35 | LOG_LEVEL: 'LOG_LEVEL', 36 | PATTERN_REPO_TYPE: 'PATTERN_REPO_TYPE', 37 | }; 38 | -------------------------------------------------------------------------------- /source/lib/constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* eslint-disable @typescript-eslint/naming-convention */ 18 | 19 | export const RAPM_CONSTANTS = { 20 | RAPM_RETAIN_DATA: 'Yes', 21 | RAPM_CODE_ARTIFACT_DOMAIN_NAME: 'awspatterns', 22 | RAPM_CODE_ARTIFACT_REPOSITORY_NAME: 'awspatterns', 23 | }; 24 | 25 | export const passwordPolicy = { 26 | minimumLength: 14, 27 | requireLowercase: true, 28 | requireDigits: true, 29 | requireSymbols: true, 30 | requireUppercase: true, 31 | temporaryPasswordValidityDays: 7, 32 | }; 33 | -------------------------------------------------------------------------------- /source/lib/infra-utils/zip-bundle.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"). 5 | You may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import * as fs from 'fs'; 17 | import * as path from 'path'; 18 | import * as archiver from 'archiver'; 19 | 20 | const dir = path.join(process.cwd(), '..', 'blueprint-infrastructure-asset'); 21 | if (!fs.existsSync(dir)) { 22 | fs.mkdirSync(dir); 23 | } 24 | 25 | const output = fs.createWriteStream( 26 | path.join( 27 | process.cwd(), 28 | '..', 29 | 'blueprint-infrastructure-asset', 30 | 'blueprint-infrastructure.zip', 31 | ), 32 | ); 33 | 34 | const archive = archiver('zip'); 35 | 36 | output.on('close', function () { 37 | console.log(archive.pointer() + ' total bytes'); 38 | console.log('archiver has been finalized and the output file descriptor has closed.'); 39 | }); 40 | 41 | archive.on('error', function (err) { 42 | throw err; 43 | }); 44 | 45 | archive.pipe(output); 46 | 47 | archive.glob('**/*', { 48 | cwd: process.cwd(), 49 | ignore: ['node_modules/**', 'cdk.out/**', 'dist/**', '*context.json'], 50 | }); 51 | 52 | archive.finalize(); 53 | -------------------------------------------------------------------------------- /source/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist", 4 | "target": "ES2019", 5 | "module": "commonjs", 6 | "lib": ["es2019", "dom"], 7 | "declaration": true, 8 | "skipLibCheck": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": ["./node_modules/@types"] 23 | }, 24 | "exclude": ["cdk.out", "dist", "blueprint-ui", "lambda", "blueprint-infrastructure"] 25 | } 26 | --------------------------------------------------------------------------------