diff --git a/codebuild_specs/amplify_migration_tests_multi_env_layers.yml b/codebuild_specs/amplify_migration_tests_multi_env_layers.yml deleted file mode 100644 index f51ee286a79..00000000000 --- a/codebuild_specs/amplify_migration_tests_multi_env_layers.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: 0.2 -env: - shell: bash - compute-type: BUILD_GENERAL1_SMALL - variables: - CI: true - CIRCLECI: true - IS_AMPLIFY_CI: true - CLI_REGION: us-east-1 - # mock values to test artifact scanning - ENV_VAR_WITH_SECRETS: 'MOCK_ENV_VAR_FOR_SCANNING_SECRETS' - MOCK_ENV_VAR_FOR_SCANNING_SECRETS: 'abc123xyz' - - # mock values for credentials below - FACEBOOK_APP_ID: 'fbAppId' - FACEBOOK_APP_SECRET: 'fbAppSecret' - GOOGLE_APP_ID: 'gglAppID' - GOOGLE_APP_SECRET: 'gglAppSecret' - AMAZON_APP_ID: 'amaznAppID' - AMAZON_APP_SECRET: 'amaznAppID' - APPLE_APP_ID: 'com.fake.app' - APPLE_TEAM_ID: '2QLEWNDK6K' - APPLE_KEY_ID: '2QLZXKYJ8J' - # mock value, Cognito validates the private key, this is an invalidated key. - APPLE_PRIVATE_KEY_2: '----BEGIN PRIVATE KEY-----MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw----END PRIVATE KEY----' -phases: - build: - commands: - # you can provide a codebuild source version to use old cache and skip all other jobs :) - - export NODE_OPTIONS=--max-old-space-size=8096 - - export AMPLIFY_DIR=$CODEBUILD_SRC_DIR/out - - export AMPLIFY_PATH=$HOME/.npm-global/lib/node_modules/@aws-amplify/cli/bin/amplify - - echo $AMPLIFY_DIR - - echo $AMPLIFY_PATH - - source ./shared-scripts.sh && _runMigrationMultiEnvLayersTest - post_build: - commands: - - source ./shared-scripts.sh && _scanArtifacts - - source ./shared-scripts.sh && _uploadReportsToS3 $CODEBUILD_SOURCE_VERSION $CODEBUILD_BATCH_BUILD_IDENTIFIER amplify-migration-tests -reports: - e2e-reports: - files: - - '*.xml' - file-format: 'JUNITXML' - base-directory: '$CODEBUILD_SRC_DIR/packages/amplify-migration-tests/reports/junit' -artifacts: - files: - - $CODEBUILD_SRC_DIR/packages/amplify-migration-tests/amplify-migration-reports/* diff --git a/codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml b/codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml deleted file mode 100644 index ac32f7b7376..00000000000 --- a/codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml +++ /dev/null @@ -1,48 +0,0 @@ -version: 0.2 -env: - shell: bash - compute-type: BUILD_GENERAL1_SMALL - variables: - CI: true - CIRCLECI: true - IS_AMPLIFY_CI: true - CLI_REGION: us-east-1 - # mock values to test artifact scanning - ENV_VAR_WITH_SECRETS: 'MOCK_ENV_VAR_FOR_SCANNING_SECRETS' - MOCK_ENV_VAR_FOR_SCANNING_SECRETS: 'abc123xyz' - - # mock values for credentials below - FACEBOOK_APP_ID: 'fbAppId' - FACEBOOK_APP_SECRET: 'fbAppSecret' - GOOGLE_APP_ID: 'gglAppID' - GOOGLE_APP_SECRET: 'gglAppSecret' - AMAZON_APP_ID: 'amaznAppID' - AMAZON_APP_SECRET: 'amaznAppID' - APPLE_APP_ID: 'com.fake.app' - APPLE_TEAM_ID: '2QLEWNDK6K' - APPLE_KEY_ID: '2QLZXKYJ8J' - # mock value, Cognito validates the private key, this is an invalidated key. - APPLE_PRIVATE_KEY_2: '----BEGIN PRIVATE KEY-----MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw----END PRIVATE KEY----' -phases: - build: - commands: - # you can provide a codebuild source version to use old cache and skip all other jobs :) - - export NODE_OPTIONS=--max-old-space-size=8096 - - export AMPLIFY_DIR=$CODEBUILD_SRC_DIR/out - - export AMPLIFY_PATH=$HOME/.npm-global/lib/node_modules/@aws-amplify/cli/bin/amplify - - echo $AMPLIFY_DIR - - echo $AMPLIFY_PATH - - source ./shared-scripts.sh && _runMigrationNonMultiEnvLayersTest - post_build: - commands: - - source ./shared-scripts.sh && _scanArtifacts - - source ./shared-scripts.sh && _uploadReportsToS3 $CODEBUILD_SOURCE_VERSION $CODEBUILD_BATCH_BUILD_IDENTIFIER amplify-migration-tests -reports: - e2e-reports: - files: - - '*.xml' - file-format: 'JUNITXML' - base-directory: '$CODEBUILD_SRC_DIR/packages/amplify-migration-tests/reports/junit' -artifacts: - files: - - $CODEBUILD_SRC_DIR/packages/amplify-migration-tests/amplify-migration-reports/* diff --git a/codebuild_specs/e2e_workflow.yml b/codebuild_specs/e2e_workflow.yml index 6c5db7adbbc..a6f2b52c5b6 100644 --- a/codebuild_specs/e2e_workflow.yml +++ b/codebuild_specs/e2e_workflow.yml @@ -172,18 +172,6 @@ batch: compute-type: BUILD_GENERAL1_LARGE depend-on: - upb - - identifier: amplify_migration_tests_non_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - depend-on: - - upb - - identifier: amplify_migration_tests_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_multi_env_layers.yml - env: - compute-type: BUILD_GENERAL1_MEDIUM - depend-on: - - upb - identifier: aggregate_e2e_reports buildspec: codebuild_specs/aggregate_e2e_reports.yml env: diff --git a/codebuild_specs/e2e_workflow_base.yml b/codebuild_specs/e2e_workflow_base.yml index c3ac346ff35..5d1e46626b1 100644 --- a/codebuild_specs/e2e_workflow_base.yml +++ b/codebuild_specs/e2e_workflow_base.yml @@ -130,14 +130,6 @@ batch: compute-type: BUILD_GENERAL1_LARGE depend-on: - upb - - identifier: amplify_migration_tests_non_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml - depend-on: - - upb - - identifier: amplify_migration_tests_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_multi_env_layers.yml - depend-on: - - upb - identifier: amplify_general_config_tests buildspec: codebuild_specs/amplify_general_config_tests.yml env: diff --git a/codebuild_specs/e2e_workflow_generated.yml b/codebuild_specs/e2e_workflow_generated.yml index bcbc6cfac46..e3d6a0179ec 100644 --- a/codebuild_specs/e2e_workflow_generated.yml +++ b/codebuild_specs/e2e_workflow_generated.yml @@ -130,14 +130,6 @@ batch: compute-type: BUILD_GENERAL1_LARGE depend-on: - upb - - identifier: amplify_migration_tests_non_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_non_multi_env_layers.yml - depend-on: - - upb - - identifier: amplify_migration_tests_multi_env_layers - buildspec: codebuild_specs/amplify_migration_tests_multi_env_layers.yml - depend-on: - - upb - identifier: amplify_general_config_tests buildspec: codebuild_specs/amplify_general_config_tests.yml env: @@ -2320,78 +2312,6 @@ batch: depend-on: - build_windows - upb - - identifier: l_api_key_migration_v8 - buildspec: codebuild_specs/migration_tests_v8.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests/transformer_migration/api.key.migration.test.ts - depend-on: - - upb - - identifier: l_api_key_migration_2_v8 - buildspec: codebuild_specs/migration_tests_v8.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests/transformer_migration/api.key.migration-2.test.ts - depend-on: - - upb - - identifier: l_auth_app_client_secret_migration_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-app-client-secret-migration.test.ts - depend-on: - - upb - - identifier: l_auth_hosted_ui_lambda_migration_1_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-1.test.ts - depend-on: - - upb - - identifier: l_auth_hosted_ui_lambda_migration_2_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-2.test.ts - depend-on: - - upb - - identifier: l_auth_lambda_callout_migration_rollback_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-lambda-callout-migration-rollback.test.ts - depend-on: - - upb - - identifier: l_auth_lambda_callout_migration_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-lambda-callout-migration.test.ts - depend-on: - - upb - - identifier: l_auth_oauth_lambda_migration_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth-oauth-lambda-migration.test.ts - depend-on: - - upb - - identifier: l_auth_migration_v12 - buildspec: codebuild_specs/migration_tests_v12.yml - env: - variables: - compute-type: BUILD_GENERAL1_SMALL - TEST_SUITE: src/__tests__/migration_tests_v12/auth.migration.test.ts - depend-on: - - upb - identifier: aggregate_e2e_reports env: compute-type: BUILD_GENERAL1_MEDIUM diff --git a/codebuild_specs/migration_tests_v12.yml b/codebuild_specs/migration_tests_v12.yml deleted file mode 100644 index 6465bedbb38..00000000000 --- a/codebuild_specs/migration_tests_v12.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: 0.2 -env: - shell: bash - compute-type: BUILD_GENERAL1_SMALL - variables: - CI: true - CIRCLECI: true - IS_AMPLIFY_CI: true - # mock values to test artifact scanning - ENV_VAR_WITH_SECRETS: 'MOCK_ENV_VAR_FOR_SCANNING_SECRETS' - MOCK_ENV_VAR_FOR_SCANNING_SECRETS: 'abc123xyz' - - # mock values for credentials below - FACEBOOK_APP_ID: 'fbAppId' - FACEBOOK_APP_SECRET: 'fbAppSecret' - GOOGLE_APP_ID: 'gglAppID' - GOOGLE_APP_SECRET: 'gglAppSecret' - AMAZON_APP_ID: 'amaznAppID' - AMAZON_APP_SECRET: 'amaznAppID' - APPLE_APP_ID: 'com.fake.app' - APPLE_TEAM_ID: '2QLEWNDK6K' - APPLE_KEY_ID: '2QLZXKYJ8J' - # mock value, Cognito validates the private key, this is an invalidated key. - APPLE_PRIVATE_KEY_2: '----BEGIN PRIVATE KEY-----MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw----END PRIVATE KEY----' -phases: - build: - commands: - # you can provide a codebuild source version to use old cache and skip all other jobs :) - - export AMPLIFY_DIR=$CODEBUILD_SRC_DIR/out - - export AMPLIFY_PATH=$HOME/.amplify/bin/amplify - - echo $AMPLIFY_DIR - - echo $AMPLIFY_PATH - - source ./shared-scripts.sh && _runMigrationV12Test - post_build: - commands: - - source ./shared-scripts.sh && _scanArtifacts - - source ./shared-scripts.sh && _uploadReportsToS3 $CODEBUILD_SOURCE_VERSION $CODEBUILD_BATCH_BUILD_IDENTIFIER amplify-migration-tests -reports: - e2e-reports: - files: - - '*.xml' - file-format: 'JUNITXML' - base-directory: '$CODEBUILD_SRC_DIR/packages/amplify-migration-tests/reports/junit' -artifacts: - files: - - $CODEBUILD_SRC_DIR/packages/amplify-migration-tests/amplify-migration-reports/* diff --git a/codebuild_specs/migration_tests_v8.yml b/codebuild_specs/migration_tests_v8.yml deleted file mode 100644 index 31650c49b84..00000000000 --- a/codebuild_specs/migration_tests_v8.yml +++ /dev/null @@ -1,46 +0,0 @@ -version: 0.2 -env: - shell: bash - compute-type: BUILD_GENERAL1_SMALL - variables: - CI: true - CIRCLECI: true - IS_AMPLIFY_CI: true - # mock values to test artifact scanning - ENV_VAR_WITH_SECRETS: 'MOCK_ENV_VAR_FOR_SCANNING_SECRETS' - MOCK_ENV_VAR_FOR_SCANNING_SECRETS: 'abc123xyz' - - # mock values for credentials below - FACEBOOK_APP_ID: 'fbAppId' - FACEBOOK_APP_SECRET: 'fbAppSecret' - GOOGLE_APP_ID: 'gglAppID' - GOOGLE_APP_SECRET: 'gglAppSecret' - AMAZON_APP_ID: 'amaznAppID' - AMAZON_APP_SECRET: 'amaznAppID' - APPLE_APP_ID: 'com.fake.app' - APPLE_TEAM_ID: '2QLEWNDK6K' - APPLE_KEY_ID: '2QLZXKYJ8J' - # mock value, Cognito validates the private key, this is an invalidated key. - APPLE_PRIVATE_KEY_2: '----BEGIN PRIVATE KEY-----MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw----END PRIVATE KEY----' -phases: - build: - commands: - # you can provide a codebuild source version to use old cache and skip all other jobs :) - - export AMPLIFY_DIR=$CODEBUILD_SRC_DIR/out - - export AMPLIFY_PATH=$HOME/.npm-global/bin/amplify - - echo $AMPLIFY_DIR - - echo $AMPLIFY_PATH - - source ./shared-scripts.sh && _runMigrationV8Test - post_build: - commands: - - source ./shared-scripts.sh && _scanArtifacts - - source ./shared-scripts.sh && _uploadReportsToS3 $CODEBUILD_SOURCE_VERSION $CODEBUILD_BATCH_BUILD_IDENTIFIER amplify-migration-tests -reports: - e2e-reports: - files: - - '*.xml' - file-format: 'JUNITXML' - base-directory: '$CODEBUILD_SRC_DIR/packages/amplify-migration-tests/reports/junit' -artifacts: - files: - - $CODEBUILD_SRC_DIR/packages/amplify-migration-tests/amplify-migration-reports/* diff --git a/codebuild_specs/wait_for_ids.json b/codebuild_specs/wait_for_ids.json index d1de355194f..805a1d24d5d 100644 --- a/codebuild_specs/wait_for_ids.json +++ b/codebuild_specs/wait_for_ids.json @@ -8,8 +8,6 @@ "l_api_4_containers_api_secrets_storage_4", "l_api_6a_auth_7b_export_pull_b", "l_api_7_export_pull_a_function_9a", - "l_api_key_migration_2_v8", - "l_api_key_migration_v8", "l_apigw_api_lambda_auth_1_api_key_migration2", "l_auth_12_auth_2g_auth_2h", "l_auth_1a_auth_trigger_custom_policies_function", @@ -25,14 +23,7 @@ "l_auth_5g_admin_api_hosted_ui", "l_auth_7a_auth_8c_feature_flags", "l_auth_9_custom_resources_env_5", - "l_auth_app_client_secret_migration_v12", - "l_auth_hosted_ui_lambda_migration_1_v12", - "l_auth_hosted_ui_lambda_migration_2_v12", - "l_auth_lambda_callout_migration_rollback_v12", - "l_auth_lambda_callout_migration_v12", "l_auth_migration_amplify_remove_api_2a", - "l_auth_migration_v12", - "l_auth_oauth_lambda_migration_v12", "l_build_function_custom_resource_with_storage_dynamodb_simulator", "l_container_hosting_init_b_notifications_apns", "l_containers_api_1", diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-app-client-secret-migration.test.ts.snap b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-app-client-secret-migration.test.ts.snap deleted file mode 100644 index 4d7ebc49d71..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-app-client-secret-migration.test.ts.snap +++ /dev/null @@ -1,69 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`amplify add auth... starting interactively with old... ...should init an Android project and add default auth 1`] = ` -"IAM Statement Changes -┌───┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┬────────────────────────────────────┬───────────────────────────┬───────────┐ -│ │ Resource │ Effect │ Action │ Principal │ Condition │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:DescribeUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${UserPoolClientLambda}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -└───┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┴────────────────────────────────────┴───────────────────────────┴───────────┘ -(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) - -Conditions -[-] Condition ShouldOutputAppClientSecrets: {"Fn::Equals":[{"Ref":"userpoolClientGenerateSecret"},true]} - -Resources -[-] AWS::Lambda::Function UserPoolClientLambda destroy -[-] AWS::IAM::Policy UserPoolClientLambdaPolicy destroy -[-] AWS::IAM::Policy UserPoolClientLogPolicy destroy -[-] Custom::LambdaCallout UserPoolClientInputs destroy -[~] AWS::IAM::Role UserPoolClientRole - └─ [-] DependsOn - └─ ["UserPoolClient"] -[~] AWS::Cognito::IdentityPool IdentityPool - └─ [-] DependsOn - └─ ["UserPoolClientInputs"] - -Outputs -[-] Output AppClientSecret: {"Value":{"Fn::GetAtt":["UserPoolClientInputs","appSecret"]},"Condition":"ShouldOutputAppClientSecrets"} - -" -`; - -exports[`amplify add auth... starting interactively with old... ...should init an Android project and add default auth 2`] = ` -"IAM Statement Changes -┌───┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┬────────────────────────────────────┬───────────────────────────┬───────────┐ -│ │ Resource │ Effect │ Action │ Principal │ Condition │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:DescribeUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${UserPoolClientLambda}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -└───┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┴────────────────────────────────────┴───────────────────────────┴───────────┘ -(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) - -Conditions -[-] Condition ShouldOutputAppClientSecrets: {"Fn::Equals":[{"Ref":"userpoolClientGenerateSecret"},true]} - -Resources -[-] AWS::Lambda::Function UserPoolClientLambda destroy -[-] AWS::IAM::Policy UserPoolClientLambdaPolicy destroy -[-] AWS::IAM::Policy UserPoolClientLogPolicy destroy -[-] Custom::LambdaCallout UserPoolClientInputs destroy -[~] AWS::IAM::Role UserPoolClientRole - └─ [-] DependsOn - └─ ["UserPoolClient"] -[~] AWS::Cognito::IdentityPool IdentityPool - └─ [-] DependsOn - └─ ["UserPoolClientInputs"] - -Outputs -[-] Output AppClientSecret: {"Value":{"Fn::GetAtt":["UserPoolClientInputs","appSecret"]},"Condition":"ShouldOutputAppClientSecrets"} - -" -`; diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-oauth-lambda-migration.test.ts.snap b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-oauth-lambda-migration.test.ts.snap deleted file mode 100644 index 35e6ada4929..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/__snapshots__/auth-oauth-lambda-migration.test.ts.snap +++ /dev/null @@ -1,939 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`amplify add auth... ...should init an Js project and add Oauth settings with userpool 1`] = ` -"IAM Statement Changes -┌───┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┬────────────────────────────────────┬───────────────────────────┬───────────┐ -│ │ Resource │ Effect │ Action │ Principal │ Condition │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:DescribeUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:UpdateUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${OAuthCustomResource}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${UserPoolClientLambda}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -└───┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┴────────────────────────────────────┴───────────────────────────┴───────────┘ -(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) - -Conditions -[-] Condition ShouldOutputAppClientSecrets: {"Fn::Equals":[{"Ref":"userpoolClientGenerateSecret"},true]} - -Resources -[-] AWS::Lambda::Function UserPoolClientLambda destroy -[-] AWS::IAM::Policy UserPoolClientLambdaPolicy destroy -[-] AWS::IAM::Policy UserPoolClientLogPolicy destroy -[-] Custom::LambdaCallout UserPoolClientInputs destroy -[-] AWS::Lambda::Function OAuthCustomResource destroy -[-] AWS::IAM::Policy OAuthCustomResourcePolicy destroy -[-] AWS::IAM::Policy OAuthCustomResourceLogPolicy destroy -[-] Custom::LambdaCallout OAuthCustomResourceInputs destroy -[~] AWS::Cognito::UserPoolClient UserPoolClientWeb - ├─ [+] AllowedOAuthFlows - │ └─ ["code"] - ├─ [+] AllowedOAuthFlowsUserPoolClient - │ └─ true - ├─ [+] AllowedOAuthScopes - │ └─ ["phone","email","openid","profile","aws.cognito.signin.user.admin"] - ├─ [+] CallbackURLs - │ └─ ["https://sin1/","https://sin2/"] - ├─ [+] LogoutURLs - │ └─ ["https://sout1/","https://sout2/"] - ├─ [+] SupportedIdentityProviders - │ └─ ["Facebook","Google","LoginWithAmazon","SignInWithApple","COGNITO"] - └─ [~] DependsOn - └─ @@ -1,3 +1,4 @@ - [ ] [ - [+] "HostedUIProvidersCustomResourceInputs", - [ ] "UserPool" - [ ] ] -[~] AWS::Cognito::UserPoolClient UserPoolClient - ├─ [+] AllowedOAuthFlows - │ └─ ["code"] - ├─ [+] AllowedOAuthFlowsUserPoolClient - │ └─ true - ├─ [+] AllowedOAuthScopes - │ └─ ["phone","email","openid","profile","aws.cognito.signin.user.admin"] - ├─ [+] CallbackURLs - │ └─ ["https://sin1/","https://sin2/"] - ├─ [+] LogoutURLs - │ └─ ["https://sout1/","https://sout2/"] - ├─ [+] SupportedIdentityProviders - │ └─ ["Facebook","Google","LoginWithAmazon","SignInWithApple","COGNITO"] - └─ [~] DependsOn - └─ @@ -1,3 +1,4 @@ - [ ] [ - [+] "HostedUIProvidersCustomResourceInputs", - [ ] "UserPool" - [ ] ] -[~] AWS::IAM::Role UserPoolClientRole - └─ [-] DependsOn - └─ ["UserPoolClient"] -[~] AWS::Lambda::Function HostedUICustomResource - ├─ [~] Code - │ └─ [~] .ZipFile: - │ ├─ [-] const response = require('cfn-response'); -const aws = require('aws-sdk'); -const identity = new aws.CognitoIdentityServiceProvider(); -exports.handler = (event, context, callback) => { - const userPoolId = event.ResourceProperties.userPoolId; - const inputDomainName = event.ResourceProperties.hostedUIDomainName; - let deleteUserPoolDomain = (domainName) => { - let params = { Domain: domainName, UserPoolId: userPoolId }; - return identity.deleteUserPoolDomain(params).promise(); - }; - if (event.RequestType == 'Delete') { - deleteUserPoolDomain(inputDomainName) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err); - response.send(event, context, response.FAILED, { err }); - }); - } - if (event.RequestType == 'Update' || event.RequestType == 'Create') { - let checkDomainAvailability = (domainName) => { - let params = { Domain: domainName }; - return identity - .describeUserPoolDomain(params) - .promise() - .then((res) => { - if (res.DomainDescription && res.DomainDescription.UserPool) { - return false; - } - return true; - }) - .catch((err) => { - return false; - }); - }; - let createUserPoolDomain = (domainName) => { - let params = { Domain: domainName, UserPoolId: userPoolId }; - return identity.createUserPoolDomain(params).promise(); - }; - identity - .describeUserPool({ UserPoolId: userPoolId }) - .promise() - .then((result) => { - if (inputDomainName) { - if (result.UserPool.Domain === inputDomainName) { - return; - } else { - if (!result.UserPool.Domain) { - return checkDomainAvailability(inputDomainName).then((isDomainAvailable) => { - if (isDomainAvailable) { - return createUserPoolDomain(inputDomainName); - } else { - throw new Error('Domain not available'); - } - }); - } else { - return checkDomainAvailability(inputDomainName).then((isDomainAvailable) => { - if (isDomainAvailable) { - return deleteUserPoolDomain(result.UserPool.Domain).then(() => createUserPoolDomain(inputDomainName)); - } else { - throw new Error('Domain not available'); - } - }); - } - } - } else { - if (result.UserPool.Domain) { - return deleteUserPoolDomain(result.UserPool.Domain); - } - } - }) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err); - response.send(event, context, response.FAILED, { err }); - }); - } -}; - - │ └─ [+] const response = require('cfn-response'); -const { - CognitoIdentityProviderClient, - CreateUserPoolDomainCommand, - DeleteUserPoolDomainCommand, - DescribeUserPoolCommand, - DescribeUserPoolDomainCommand, -} = require('@aws-sdk/client-cognito-identity-provider'); -const identity = new CognitoIdentityProviderClient({}); - -exports.handler = (event, context) => { - // Don't return promise, response.send() marks context as done internally - void tryHandleEvent(event, context); -}; - -async function tryHandleEvent(event, context) { - try { - await handleEvent(event); - response.send(event, context, response.SUCCESS, {}); - } catch (err) { - console.log(err); - response.send(event, context, response.FAILED, { err }); - } -} - -async function handleEvent(event) { - const userPoolId = event.ResourceProperties.userPoolId; - const inputDomainName = event.ResourceProperties.hostedUIDomainName; - if (event.RequestType === 'Delete') { - await deleteUserPoolDomain(inputDomainName, userPoolId); - } else if (event.RequestType === 'Update' || event.RequestType === 'Create') { - await createOrUpdateDomain(inputDomainName, userPoolId); - } -} - -async function checkDomainAvailability(domainName) { - const params = { Domain: domainName }; - try { - const res = await identity.send(new DescribeUserPoolDomainCommand(params)); - return !(res.DomainDescription && res.DomainDescription.UserPoolId); - } catch (err) { - return false; - } -} - -async function deleteUserPoolDomain(domainName, userPoolId) { - const params = { Domain: domainName, UserPoolId: userPoolId }; - await identity.send(new DeleteUserPoolDomainCommand(params)); -} - -async function createUserPoolDomain(domainName, userPoolId) { - const params = { - Domain: domainName, - UserPoolId: userPoolId, - }; - await identity.send(new CreateUserPoolDomainCommand(params)); -} - -async function createOrUpdateDomain(inputDomainName, userPoolId) { - const result = await identity.send(new DescribeUserPoolCommand({ UserPoolId: userPoolId })); - if (result.UserPool.Domain === inputDomainName) { - // if existing domain is same as input domain do nothing. - return; - } - if (inputDomainName) { - // create new or replace existing domain. - const isDomainAvailable = await checkDomainAvailability(inputDomainName); - if (isDomainAvailable) { - if (result.UserPool.Domain) { - await deleteUserPoolDomain(result.UserPool.Domain, userPoolId); - } - await createUserPoolDomain(inputDomainName, userPoolId); - } else { - throw new Error('Domain not available'); - } - } else if (result.UserPool.Domain) { - // if input domain is undefined delete existing domain if exists. - await deleteUserPoolDomain(result.UserPool.Domain, userPoolId); - } -} - - └─ [~] Runtime - ├─ [-] nodejs16.x - └─ [+] nodejs18.x -[~] AWS::Lambda::Function HostedUIProvidersCustomResource - ├─ [~] Code - │ └─ [~] .ZipFile: - │ ├─ [-] const response = require('cfn-response'); -const aws = require('aws-sdk'); -const identity = new aws.CognitoIdentityServiceProvider(); -exports.handler = (event, context, callback) => { - try { - const userPoolId = event.ResourceProperties.userPoolId; - let hostedUIProviderMeta = JSON.parse(event.ResourceProperties.hostedUIProviderMeta); - let hostedUIProviderCreds = JSON.parse(event.ResourceProperties.hostedUIProviderCreds); - if (hostedUIProviderCreds.length === 0) { - response.send(event, context, response.SUCCESS, {}); - } - if (event.RequestType == 'Delete') { - response.send(event, context, response.SUCCESS, {}); - } - if (event.RequestType == 'Update' || event.RequestType == 'Create') { - let getRequestParams = (providerName) => { - let providerMetaIndex = hostedUIProviderMeta.findIndex((provider) => provider.ProviderName === providerName); - let providerMeta = hostedUIProviderMeta[providerMetaIndex]; - let providerCredsIndex = hostedUIProviderCreds.findIndex((provider) => provider.ProviderName === providerName); - let providerCreds = hostedUIProviderCreds[providerCredsIndex]; - let requestParams = { - ProviderName: providerMeta.ProviderName, - UserPoolId: userPoolId, - AttributeMapping: providerMeta.AttributeMapping, - }; - if (providerMeta.ProviderName === 'SignInWithApple') { - if (providerCreds.client_id && providerCreds.team_id && providerCreds.key_id && providerCreds.private_key) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - team_id: providerCreds.team_id, - key_id: providerCreds.key_id, - private_key: providerCreds.private_key, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } else { - if (providerCreds.client_id && providerCreds.client_secret) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - client_secret: providerCreds.client_secret, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } - return requestParams; - }; - let createIdentityProvider = (providerName) => { - let requestParams = getRequestParams(providerName); - if (!requestParams) { - return Promise.resolve(); - } - requestParams.ProviderType = requestParams.ProviderName; - return identity.createIdentityProvider(requestParams).promise(); - }; - let updateIdentityProvider = (providerName) => { - let requestParams = getRequestParams(providerName); - if (!requestParams) { - return Promise.resolve(); - } - return identity.updateIdentityProvider(requestParams).promise(); - }; - let deleteIdentityProvider = (providerName) => { - let params = { ProviderName: providerName, UserPoolId: userPoolId }; - return identity.deleteIdentityProvider(params).promise(); - }; - let providerPromises = []; - identity - .listIdentityProviders({ UserPoolId: userPoolId, MaxResults: 60 }) - .promise() - .then((result) => { - console.log(result); - let providerList = result.Providers.map((provider) => provider.ProviderName); - let providerListInParameters = hostedUIProviderMeta.map((provider) => provider.ProviderName); - hostedUIProviderMeta.forEach((providerMetadata) => { - if (providerList.indexOf(providerMetadata.ProviderName) > -1) { - providerPromises.push(updateIdentityProvider(providerMetadata.ProviderName)); - } else { - providerPromises.push(createIdentityProvider(providerMetadata.ProviderName)); - } - }); - providerList.forEach((provider) => { - if (providerListInParameters.indexOf(provider) < 0) { - providerPromises.push(deleteIdentityProvider(provider)); - } - }); - return Promise.all(providerPromises); - }) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - }); - } - } catch (err) { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - } -}; - - │ └─ [+] const response = require('cfn-response'); -const { - CognitoIdentityProviderClient, - CreateIdentityProviderCommand, - DeleteIdentityProviderCommand, - ListIdentityProvidersCommand, - UpdateIdentityProviderCommand, -} = require('@aws-sdk/client-cognito-identity-provider'); -const identity = new CognitoIdentityProviderClient({}); - -exports.handler = (event, context) => { - // Don't return promise, response.send() marks context as done internally - void tryHandleEvent(event, context); -}; - -async function tryHandleEvent(event, context) { - try { - await handleEvent(event); - response.send(event, context, response.SUCCESS, {}); - } catch (err) { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - } -} - -async function handleEvent(event) { - const userPoolId = event.ResourceProperties.userPoolId; - const hostedUIProviderMeta = JSON.parse(event.ResourceProperties.hostedUIProviderMeta); - const hostedUIProviderCreds = JSON.parse(event.ResourceProperties.hostedUIProviderCreds); - const hasHostedUIProviderCreds = hostedUIProviderCreds.length && hostedUIProviderCreds.length > 0; - if (hasHostedUIProviderCreds && (event.RequestType === 'Update' || event.RequestType === 'Create')) { - const listIdentityProvidersResponse = await identity.send( - new ListIdentityProvidersCommand({ - UserPoolId: userPoolId, - MaxResults: 60, - }), - ); - console.log(listIdentityProvidersResponse); - const providerList = listIdentityProvidersResponse.Providers.map((provider) => provider.ProviderName); - const providerListInParameters = hostedUIProviderMeta.map((provider) => provider.ProviderName); - for (const providerMetadata of hostedUIProviderMeta) { - if (providerList.indexOf(providerMetadata.ProviderName) > -1) { - await updateIdentityProvider(providerMetadata.ProviderName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - } else { - await createIdentityProvider(providerMetadata.ProviderName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - } - } - for (const provider of providerList) { - if (providerListInParameters.indexOf(provider) < 0) { - await deleteIdentityProvider(provider, userPoolId); - } - } - } -} - -function getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const providerMeta = hostedUIProviderMeta.find((provider) => provider.ProviderName === providerName); - const providerCreds = hostedUIProviderCreds.find((provider) => provider.ProviderName === providerName); - let requestParams = { - ProviderName: providerMeta.ProviderName, - UserPoolId: userPoolId, - AttributeMapping: providerMeta.AttributeMapping, - }; - if (providerMeta.ProviderName === 'SignInWithApple') { - if (providerCreds.client_id && providerCreds.team_id && providerCreds.key_id && providerCreds.private_key) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - team_id: providerCreds.team_id, - key_id: providerCreds.key_id, - private_key: providerCreds.private_key, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } else { - if (providerCreds.client_id && providerCreds.client_secret) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - client_secret: providerCreds.client_secret, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } - return requestParams; -} - -async function createIdentityProvider(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const requestParams = getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - if (!requestParams) { - return; - } - requestParams.ProviderType = requestParams.ProviderName; - await identity.send(new CreateIdentityProviderCommand(requestParams)); -} - -async function updateIdentityProvider(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const requestParams = getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - if (!requestParams) { - return; - } - await identity.send(new UpdateIdentityProviderCommand(requestParams)); -} - -async function deleteIdentityProvider(providerName, userPoolId) { - const params = { ProviderName: providerName, UserPoolId: userPoolId }; - await identity.send(new DeleteIdentityProviderCommand(params)); -} - - └─ [~] Runtime - ├─ [-] nodejs16.x - └─ [+] nodejs18.x - -Outputs -[-] Output AppClientSecret: {"Value":{"Fn::GetAtt":["UserPoolClientInputs","appSecret"]},"Condition":"ShouldOutputAppClientSecrets"} - -" -`; - -exports[`amplify add auth... ...should init an Js project and add Oauth settings with userpool 2`] = ` -"IAM Statement Changes -┌───┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────┬────────────────────────────────────┬───────────────────────────┬───────────┐ -│ │ Resource │ Effect │ Action │ Principal │ Condition │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:DescribeUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -│ - │ \${UserPool.Arn} │ Allow │ cognito-idp:UpdateUserPoolClient │ AWS:\${UserPoolClientRole} │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${OAuthCustomResource}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -├───┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────┼────────────────────────────────────┼───────────────────────────┼───────────┤ -│ - │ {"Fn::Sub":["arn:aws:logs:\${region}:\${account}:log-group:/aws/lambda/\${lambda}:log-stream:*",{"region":"\${AWS::Region}","account":"\${AWS::AccountId}","lambda":"\${UserPoolClientLambda}"}]} │ Allow │ logs:CreateLogGroup │ AWS:\${UserPoolClientRole} │ │ -│ │ │ │ logs:CreateLogStream │ │ │ -│ │ │ │ logs:PutLogEvents │ │ │ -└───┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────┴────────────────────────────────────┴───────────────────────────┴───────────┘ -(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) - -Conditions -[-] Condition ShouldOutputAppClientSecrets: {"Fn::Equals":[{"Ref":"userpoolClientGenerateSecret"},true]} - -Resources -[-] AWS::Lambda::Function UserPoolClientLambda destroy -[-] AWS::IAM::Policy UserPoolClientLambdaPolicy destroy -[-] AWS::IAM::Policy UserPoolClientLogPolicy destroy -[-] Custom::LambdaCallout UserPoolClientInputs destroy -[-] AWS::Lambda::Function OAuthCustomResource destroy -[-] AWS::IAM::Policy OAuthCustomResourcePolicy destroy -[-] AWS::IAM::Policy OAuthCustomResourceLogPolicy destroy -[-] Custom::LambdaCallout OAuthCustomResourceInputs destroy -[~] AWS::Cognito::UserPoolClient UserPoolClientWeb - ├─ [+] AllowedOAuthFlows - │ └─ ["code"] - ├─ [+] AllowedOAuthFlowsUserPoolClient - │ └─ true - ├─ [+] AllowedOAuthScopes - │ └─ ["phone","email","openid","profile","aws.cognito.signin.user.admin"] - ├─ [+] CallbackURLs - │ └─ ["https://sin1/","https://sin2/"] - ├─ [+] LogoutURLs - │ └─ ["https://sout1/","https://sout2/"] - ├─ [+] SupportedIdentityProviders - │ └─ ["Facebook","Google","LoginWithAmazon","SignInWithApple","COGNITO"] - └─ [~] DependsOn - └─ @@ -1,3 +1,4 @@ - [ ] [ - [+] "HostedUIProvidersCustomResourceInputs", - [ ] "UserPool" - [ ] ] -[~] AWS::Cognito::UserPoolClient UserPoolClient - ├─ [+] AllowedOAuthFlows - │ └─ ["code"] - ├─ [+] AllowedOAuthFlowsUserPoolClient - │ └─ true - ├─ [+] AllowedOAuthScopes - │ └─ ["phone","email","openid","profile","aws.cognito.signin.user.admin"] - ├─ [+] CallbackURLs - │ └─ ["https://sin1/","https://sin2/"] - ├─ [+] LogoutURLs - │ └─ ["https://sout1/","https://sout2/"] - ├─ [+] SupportedIdentityProviders - │ └─ ["Facebook","Google","LoginWithAmazon","SignInWithApple","COGNITO"] - └─ [~] DependsOn - └─ @@ -1,3 +1,4 @@ - [ ] [ - [+] "HostedUIProvidersCustomResourceInputs", - [ ] "UserPool" - [ ] ] -[~] AWS::IAM::Role UserPoolClientRole - └─ [-] DependsOn - └─ ["UserPoolClient"] -[~] AWS::Lambda::Function HostedUICustomResource - ├─ [~] Code - │ └─ [~] .ZipFile: - │ ├─ [-] const response = require('cfn-response'); -const aws = require('aws-sdk'); -const identity = new aws.CognitoIdentityServiceProvider(); -exports.handler = (event, context, callback) => { - const userPoolId = event.ResourceProperties.userPoolId; - const inputDomainName = event.ResourceProperties.hostedUIDomainName; - let deleteUserPoolDomain = (domainName) => { - let params = { Domain: domainName, UserPoolId: userPoolId }; - return identity.deleteUserPoolDomain(params).promise(); - }; - if (event.RequestType == 'Delete') { - deleteUserPoolDomain(inputDomainName) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err); - response.send(event, context, response.FAILED, { err }); - }); - } - if (event.RequestType == 'Update' || event.RequestType == 'Create') { - let checkDomainAvailability = (domainName) => { - let params = { Domain: domainName }; - return identity - .describeUserPoolDomain(params) - .promise() - .then((res) => { - if (res.DomainDescription && res.DomainDescription.UserPool) { - return false; - } - return true; - }) - .catch((err) => { - return false; - }); - }; - let createUserPoolDomain = (domainName) => { - let params = { Domain: domainName, UserPoolId: userPoolId }; - return identity.createUserPoolDomain(params).promise(); - }; - identity - .describeUserPool({ UserPoolId: userPoolId }) - .promise() - .then((result) => { - if (inputDomainName) { - if (result.UserPool.Domain === inputDomainName) { - return; - } else { - if (!result.UserPool.Domain) { - return checkDomainAvailability(inputDomainName).then((isDomainAvailable) => { - if (isDomainAvailable) { - return createUserPoolDomain(inputDomainName); - } else { - throw new Error('Domain not available'); - } - }); - } else { - return checkDomainAvailability(inputDomainName).then((isDomainAvailable) => { - if (isDomainAvailable) { - return deleteUserPoolDomain(result.UserPool.Domain).then(() => createUserPoolDomain(inputDomainName)); - } else { - throw new Error('Domain not available'); - } - }); - } - } - } else { - if (result.UserPool.Domain) { - return deleteUserPoolDomain(result.UserPool.Domain); - } - } - }) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err); - response.send(event, context, response.FAILED, { err }); - }); - } -}; - - │ └─ [+] const response = require('cfn-response'); -const { - CognitoIdentityProviderClient, - CreateUserPoolDomainCommand, - DeleteUserPoolDomainCommand, - DescribeUserPoolCommand, - DescribeUserPoolDomainCommand, -} = require('@aws-sdk/client-cognito-identity-provider'); -const identity = new CognitoIdentityProviderClient({}); - -exports.handler = (event, context) => { - // Don't return promise, response.send() marks context as done internally - void tryHandleEvent(event, context); -}; - -async function tryHandleEvent(event, context) { - try { - await handleEvent(event); - response.send(event, context, response.SUCCESS, {}); - } catch (err) { - console.log(err); - response.send(event, context, response.FAILED, { err }); - } -} - -async function handleEvent(event) { - const userPoolId = event.ResourceProperties.userPoolId; - const inputDomainName = event.ResourceProperties.hostedUIDomainName; - if (event.RequestType === 'Delete') { - await deleteUserPoolDomain(inputDomainName, userPoolId); - } else if (event.RequestType === 'Update' || event.RequestType === 'Create') { - await createOrUpdateDomain(inputDomainName, userPoolId); - } -} - -async function checkDomainAvailability(domainName) { - const params = { Domain: domainName }; - try { - const res = await identity.send(new DescribeUserPoolDomainCommand(params)); - return !(res.DomainDescription && res.DomainDescription.UserPoolId); - } catch (err) { - return false; - } -} - -async function deleteUserPoolDomain(domainName, userPoolId) { - const params = { Domain: domainName, UserPoolId: userPoolId }; - await identity.send(new DeleteUserPoolDomainCommand(params)); -} - -async function createUserPoolDomain(domainName, userPoolId) { - const params = { - Domain: domainName, - UserPoolId: userPoolId, - }; - await identity.send(new CreateUserPoolDomainCommand(params)); -} - -async function createOrUpdateDomain(inputDomainName, userPoolId) { - const result = await identity.send(new DescribeUserPoolCommand({ UserPoolId: userPoolId })); - if (result.UserPool.Domain === inputDomainName) { - // if existing domain is same as input domain do nothing. - return; - } - if (inputDomainName) { - // create new or replace existing domain. - const isDomainAvailable = await checkDomainAvailability(inputDomainName); - if (isDomainAvailable) { - if (result.UserPool.Domain) { - await deleteUserPoolDomain(result.UserPool.Domain, userPoolId); - } - await createUserPoolDomain(inputDomainName, userPoolId); - } else { - throw new Error('Domain not available'); - } - } else if (result.UserPool.Domain) { - // if input domain is undefined delete existing domain if exists. - await deleteUserPoolDomain(result.UserPool.Domain, userPoolId); - } -} - - └─ [~] Runtime - ├─ [-] nodejs16.x - └─ [+] nodejs18.x -[~] AWS::Lambda::Function HostedUIProvidersCustomResource - ├─ [~] Code - │ └─ [~] .ZipFile: - │ ├─ [-] const response = require('cfn-response'); -const aws = require('aws-sdk'); -const identity = new aws.CognitoIdentityServiceProvider(); -exports.handler = (event, context, callback) => { - try { - const userPoolId = event.ResourceProperties.userPoolId; - let hostedUIProviderMeta = JSON.parse(event.ResourceProperties.hostedUIProviderMeta); - let hostedUIProviderCreds = JSON.parse(event.ResourceProperties.hostedUIProviderCreds); - if (hostedUIProviderCreds.length === 0) { - response.send(event, context, response.SUCCESS, {}); - } - if (event.RequestType == 'Delete') { - response.send(event, context, response.SUCCESS, {}); - } - if (event.RequestType == 'Update' || event.RequestType == 'Create') { - let getRequestParams = (providerName) => { - let providerMetaIndex = hostedUIProviderMeta.findIndex((provider) => provider.ProviderName === providerName); - let providerMeta = hostedUIProviderMeta[providerMetaIndex]; - let providerCredsIndex = hostedUIProviderCreds.findIndex((provider) => provider.ProviderName === providerName); - let providerCreds = hostedUIProviderCreds[providerCredsIndex]; - let requestParams = { - ProviderName: providerMeta.ProviderName, - UserPoolId: userPoolId, - AttributeMapping: providerMeta.AttributeMapping, - }; - if (providerMeta.ProviderName === 'SignInWithApple') { - if (providerCreds.client_id && providerCreds.team_id && providerCreds.key_id && providerCreds.private_key) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - team_id: providerCreds.team_id, - key_id: providerCreds.key_id, - private_key: providerCreds.private_key, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } else { - if (providerCreds.client_id && providerCreds.client_secret) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - client_secret: providerCreds.client_secret, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } - return requestParams; - }; - let createIdentityProvider = (providerName) => { - let requestParams = getRequestParams(providerName); - if (!requestParams) { - return Promise.resolve(); - } - requestParams.ProviderType = requestParams.ProviderName; - return identity.createIdentityProvider(requestParams).promise(); - }; - let updateIdentityProvider = (providerName) => { - let requestParams = getRequestParams(providerName); - if (!requestParams) { - return Promise.resolve(); - } - return identity.updateIdentityProvider(requestParams).promise(); - }; - let deleteIdentityProvider = (providerName) => { - let params = { ProviderName: providerName, UserPoolId: userPoolId }; - return identity.deleteIdentityProvider(params).promise(); - }; - let providerPromises = []; - identity - .listIdentityProviders({ UserPoolId: userPoolId, MaxResults: 60 }) - .promise() - .then((result) => { - console.log(result); - let providerList = result.Providers.map((provider) => provider.ProviderName); - let providerListInParameters = hostedUIProviderMeta.map((provider) => provider.ProviderName); - hostedUIProviderMeta.forEach((providerMetadata) => { - if (providerList.indexOf(providerMetadata.ProviderName) > -1) { - providerPromises.push(updateIdentityProvider(providerMetadata.ProviderName)); - } else { - providerPromises.push(createIdentityProvider(providerMetadata.ProviderName)); - } - }); - providerList.forEach((provider) => { - if (providerListInParameters.indexOf(provider) < 0) { - providerPromises.push(deleteIdentityProvider(provider)); - } - }); - return Promise.all(providerPromises); - }) - .then(() => { - response.send(event, context, response.SUCCESS, {}); - }) - .catch((err) => { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - }); - } - } catch (err) { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - } -}; - - │ └─ [+] const response = require('cfn-response'); -const { - CognitoIdentityProviderClient, - CreateIdentityProviderCommand, - DeleteIdentityProviderCommand, - ListIdentityProvidersCommand, - UpdateIdentityProviderCommand, -} = require('@aws-sdk/client-cognito-identity-provider'); -const identity = new CognitoIdentityProviderClient({}); - -exports.handler = (event, context) => { - // Don't return promise, response.send() marks context as done internally - void tryHandleEvent(event, context); -}; - -async function tryHandleEvent(event, context) { - try { - await handleEvent(event); - response.send(event, context, response.SUCCESS, {}); - } catch (err) { - console.log(err.stack); - response.send(event, context, response.FAILED, { err }); - } -} - -async function handleEvent(event) { - const userPoolId = event.ResourceProperties.userPoolId; - const hostedUIProviderMeta = JSON.parse(event.ResourceProperties.hostedUIProviderMeta); - const hostedUIProviderCreds = JSON.parse(event.ResourceProperties.hostedUIProviderCreds); - const hasHostedUIProviderCreds = hostedUIProviderCreds.length && hostedUIProviderCreds.length > 0; - if (hasHostedUIProviderCreds && (event.RequestType === 'Update' || event.RequestType === 'Create')) { - const listIdentityProvidersResponse = await identity.send( - new ListIdentityProvidersCommand({ - UserPoolId: userPoolId, - MaxResults: 60, - }), - ); - console.log(listIdentityProvidersResponse); - const providerList = listIdentityProvidersResponse.Providers.map((provider) => provider.ProviderName); - const providerListInParameters = hostedUIProviderMeta.map((provider) => provider.ProviderName); - for (const providerMetadata of hostedUIProviderMeta) { - if (providerList.indexOf(providerMetadata.ProviderName) > -1) { - await updateIdentityProvider(providerMetadata.ProviderName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - } else { - await createIdentityProvider(providerMetadata.ProviderName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - } - } - for (const provider of providerList) { - if (providerListInParameters.indexOf(provider) < 0) { - await deleteIdentityProvider(provider, userPoolId); - } - } - } -} - -function getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const providerMeta = hostedUIProviderMeta.find((provider) => provider.ProviderName === providerName); - const providerCreds = hostedUIProviderCreds.find((provider) => provider.ProviderName === providerName); - let requestParams = { - ProviderName: providerMeta.ProviderName, - UserPoolId: userPoolId, - AttributeMapping: providerMeta.AttributeMapping, - }; - if (providerMeta.ProviderName === 'SignInWithApple') { - if (providerCreds.client_id && providerCreds.team_id && providerCreds.key_id && providerCreds.private_key) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - team_id: providerCreds.team_id, - key_id: providerCreds.key_id, - private_key: providerCreds.private_key, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } else { - if (providerCreds.client_id && providerCreds.client_secret) { - requestParams.ProviderDetails = { - client_id: providerCreds.client_id, - client_secret: providerCreds.client_secret, - authorize_scopes: providerMeta.authorize_scopes, - }; - } else { - requestParams = null; - } - } - return requestParams; -} - -async function createIdentityProvider(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const requestParams = getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - if (!requestParams) { - return; - } - requestParams.ProviderType = requestParams.ProviderName; - await identity.send(new CreateIdentityProviderCommand(requestParams)); -} - -async function updateIdentityProvider(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId) { - const requestParams = getRequestParams(providerName, hostedUIProviderMeta, hostedUIProviderCreds, userPoolId); - if (!requestParams) { - return; - } - await identity.send(new UpdateIdentityProviderCommand(requestParams)); -} - -async function deleteIdentityProvider(providerName, userPoolId) { - const params = { ProviderName: providerName, UserPoolId: userPoolId }; - await identity.send(new DeleteIdentityProviderCommand(params)); -} - - └─ [~] Runtime - ├─ [-] nodejs16.x - └─ [+] nodejs18.x - -Outputs -[-] Output AppClientSecret: {"Value":{"Fn::GetAtt":["UserPoolClientInputs","appSecret"]},"Condition":"ShouldOutputAppClientSecrets"} - -" -`; diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-app-client-secret-migration.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-app-client-secret-migration.test.ts deleted file mode 100644 index 1037ca746c7..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-app-client-secret-migration.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { - addAuthWithDefault, - amplifyPullNonInteractive, - amplifyPushAuth, - amplifyPushForce, - createNewProjectDir, - deleteProject, - deleteProjectDir, - getAppId, - assertAppClientSecretInFiles, - updateAuthAddUserGroups, - addHeadlessAuth, - amplifyPushNonInteractive, - updateHeadlessAuth, - updateCLIParametersToGenerateUserPoolClientSecret, -} from '@aws-amplify/amplify-e2e-core'; -import { allowedVersionsToMigrateFrom, versionCheck } from '../../migration-helpers'; -import { initAndroidProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { pullPushForceWithLatestCodebaseValidateParameterAndCfnDrift } from '../../migration-helpers/utils'; -import { AddAuthRequest, CognitoUserPoolSigninMethod, CognitoUserProperty, UpdateAuthRequest } from 'amplify-headless-interface'; - -const defaultsSettings = { - name: 'authTest', - disableAmplifyAppCreation: false, -}; - -describe('amplify add auth...', () => { - let projRoot: string; - const projectName: string = 'authAppClientSecret'; - - beforeAll(async () => { - const migrateFromVersion = { v: 'uninitialized' }; - const migrateToVersion = { v: 'uninitialized' }; - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - console.log(`Test migration from: ${migrateFromVersion.v} to ${migrateToVersion.v}`); - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - beforeEach(async () => { - projRoot = await createNewProjectDir(projectName); - }); - - afterEach(async () => { - await deleteProject(projRoot); - deleteProjectDir(projRoot); - }); - - describe('starting interactively with old...', () => { - beforeEach(async () => { - await initAndroidProjectWithProfileV12(projRoot, defaultsSettings); - await addAuthWithDefault(projRoot); - await amplifyPushAuth(projRoot); - updateCLIParametersToGenerateUserPoolClientSecret(projRoot); - }); - - it('...should init an Android project and add default auth', async () => { - await amplifyPushAuth(projRoot); - // assert client secret in projRoot - await assertAppClientSecretInFiles(projRoot, 'android'); - const projRoot2 = await createNewProjectDir(`${projectName}2`); - const projRoot3 = await createNewProjectDir(`${projectName}3`); - // using amplify push force here as changes are only related to build files - await pullPushForceWithLatestCodebaseValidateParameterAndCfnDrift(projRoot, projRoot2); - const appId = getAppId(projRoot); - expect(appId).toBeDefined(); - const frontendConfig = { - frontend: 'android', - config: { - ResDir: 'app/src/main/res', - }, - }; - const envName = 'integtest'; - try { - await amplifyPullNonInteractive(projRoot3, { - appId, - frontend: frontendConfig, - envName, - }); - await amplifyPushForce(projRoot3, true); - await assertAppClientSecretInFiles(projRoot3, 'android'); - } finally { - deleteProjectDir(projRoot3); - } - }); - - it('update auth and push with latest interactively, write secret', async () => { - await updateAuthAddUserGroups(projRoot, ['group1', 'group2'], { testingWithLatestCodebase: true }); - updateCLIParametersToGenerateUserPoolClientSecret(projRoot); - await amplifyPushAuth(projRoot, true); - await assertAppClientSecretInFiles(projRoot, 'android'); - }); - }); - - describe('starting non-interactively with old...', () => { - beforeEach(async () => { - await initAndroidProjectWithProfileV12(projRoot, defaultsSettings); - const addAuthRequest: AddAuthRequest = { - version: 2, - resourceName: 'myAuthResource', - serviceConfiguration: { - serviceName: 'Cognito', - includeIdentityPool: false, - userPoolConfiguration: { - requiredSignupAttributes: [CognitoUserProperty.EMAIL, CognitoUserProperty.PHONE_NUMBER], - // eslint-disable-next-line spellcheck/spell-checker - signinMethod: CognitoUserPoolSigninMethod.USERNAME, - }, - }, - }; - await addHeadlessAuth(projRoot, addAuthRequest); - updateCLIParametersToGenerateUserPoolClientSecret(projRoot, addAuthRequest.resourceName); - await amplifyPushNonInteractive(projRoot); - }); - - it('update auth and push with latest non-interactively, write secret', async () => { - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - ], - }, - includeIdentityPool: false, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - updateCLIParametersToGenerateUserPoolClientSecret(projRoot); - await amplifyPushNonInteractive(projRoot, true); - await assertAppClientSecretInFiles(projRoot, 'android'); - }); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-1.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-1.test.ts deleted file mode 100644 index 50339be7319..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-1.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { allowedVersionsToMigrateFrom, versionCheck } from '../../migration-helpers'; -import { - addAuthUserPoolOnlyWithOAuth, - AddAuthUserPoolOnlyWithOAuthSettings, - amplifyPushAuth, - amplifyPushForce, - amplifyPushNonInteractive, - createNewProjectDir, - createUserPoolOnlyWithOAuthSettings, - deleteProject, - deleteProjectDir, - generateRandomShortId, - getHostedUIDomain, - getProjectMeta, - getUserPool, - getUserPoolId, - tryScheduleCredentialRefresh, - updateAuthAddUserGroups, - updateHeadlessAuth, -} from '@aws-amplify/amplify-e2e-core'; -import { initJSProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { UpdateAuthRequest } from 'amplify-headless-interface'; - -describe('amplify auth hosted ui', () => { - beforeAll(async () => { - tryScheduleCredentialRefresh(); - - const migrateFromVersion = { v: '12.0.3' }; - const migrateToVersion = { v: 'uninitialized' }; - - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - let projRoot: string; - - beforeEach(async () => { - projRoot = await createNewProjectDir('hostedUIMigration'); - }); - - afterEach(async () => { - await deleteProject(projRoot, null, true); - deleteProjectDir(projRoot); - }); - - describe('project with hosted ui created by old version', () => { - let oauthSettings: AddAuthUserPoolOnlyWithOAuthSettings; - let originalUserPoolId: string; - let originalHostedUIDomain: string; - let region: string; - beforeEach(async () => { - oauthSettings = createUserPoolOnlyWithOAuthSettings('hui', generateRandomShortId()); - await initJSProjectWithProfileV12(projRoot); - await addAuthUserPoolOnlyWithOAuth(projRoot, oauthSettings); - await amplifyPushAuth(projRoot); - originalUserPoolId = getUserPoolId(projRoot); - originalHostedUIDomain = getHostedUIDomain(projRoot); - const meta = getProjectMeta(projRoot); - region = meta.providers.awscloudformation.Region; - expect(originalHostedUIDomain).toMatch(oauthSettings.domainPrefix); - }); - - it('keeps hosted ui domain after force push with new version', async () => { - await amplifyPushForce(projRoot, true); - const userPoolId = getUserPoolId(projRoot); - const hostedUIDomain = getHostedUIDomain(projRoot); - - expect(userPoolId).toEqual(originalUserPoolId); - const userPoolRes = await getUserPool(userPoolId, region); - expect(hostedUIDomain).toEqual(originalHostedUIDomain); - expect(hostedUIDomain).toEqual(userPoolRes.UserPool.Domain); - }); - - it('keeps hosted ui domain after update and push with new version', async () => { - await updateAuthAddUserGroups(projRoot, ['group1', 'group2'], { testingWithLatestCodebase: true, updateUserPoolGroupsPosition: 5 }); - await amplifyPushAuth(projRoot, true); - const userPoolId = getUserPoolId(projRoot); - const hostedUIDomain = getHostedUIDomain(projRoot); - - expect(userPoolId).toEqual(originalUserPoolId); - const userPoolRes = await getUserPool(userPoolId, region); - expect(hostedUIDomain).toEqual(originalHostedUIDomain); - expect(hostedUIDomain).toEqual(userPoolRes.UserPool.Domain); - }); - - it('keeps hosted ui domain after headless update and push with new version', async () => { - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - ], - }, - includeIdentityPool: false, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - await amplifyPushNonInteractive(projRoot, true); - const userPoolId = getUserPoolId(projRoot); - const hostedUIDomain = getHostedUIDomain(projRoot); - - expect(userPoolId).toEqual(originalUserPoolId); - const userPoolRes = await getUserPool(userPoolId, region); - expect(hostedUIDomain).toEqual(originalHostedUIDomain); - expect(hostedUIDomain).toEqual(userPoolRes.UserPool.Domain); - }); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-2.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-2.test.ts deleted file mode 100644 index 6518abe0f52..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-2.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { allowedVersionsToMigrateFrom, versionCheck } from '../../migration-helpers'; -import { - addAuthUserPoolOnlyWithOAuth, - AddAuthUserPoolOnlyWithOAuthSettings, - amplifyPushAuth, - amplifyPushNonInteractive, - createNewProjectDir, - createUserPoolOnlyWithOAuthSettings, - deleteProject, - deleteProjectDir, - deleteUserPoolDomain, - generateRandomShortId, - getHostedUIDomain, - getProjectMeta, - getUserPool, - getUserPoolDomain, - getUserPoolId, - tryScheduleCredentialRefresh, - updateAuthDomainPrefixWithAllProvidersConfigured, - updateHeadlessAuth, -} from '@aws-amplify/amplify-e2e-core'; -import { initJSProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { UpdateAuthRequest } from 'amplify-headless-interface'; - -describe('amplify auth hosted ui', () => { - beforeAll(async () => { - tryScheduleCredentialRefresh(); - - const migrateFromVersion = { v: '12.0.3' }; - const migrateToVersion = { v: 'uninitialized' }; - - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - let projRoot: string; - - beforeEach(async () => { - projRoot = await createNewProjectDir('hostedUIMigration'); - }); - - afterEach(async () => { - await deleteProject(projRoot, null, true); - deleteProjectDir(projRoot); - }); - - describe('project with hosted ui created by old version', () => { - let oauthSettings: AddAuthUserPoolOnlyWithOAuthSettings; - let originalUserPoolId: string; - let originalHostedUIDomain: string; - let region: string; - beforeEach(async () => { - oauthSettings = createUserPoolOnlyWithOAuthSettings('hui', generateRandomShortId()); - await initJSProjectWithProfileV12(projRoot); - await addAuthUserPoolOnlyWithOAuth(projRoot, oauthSettings); - await amplifyPushAuth(projRoot); - originalUserPoolId = getUserPoolId(projRoot); - originalHostedUIDomain = getHostedUIDomain(projRoot); - const meta = getProjectMeta(projRoot); - region = meta.providers.awscloudformation.Region; - expect(originalHostedUIDomain).toMatch(oauthSettings.domainPrefix); - }); - - it('updates hosted ui domain headless with new version and pushes', async () => { - const updatedDomainPrefix = `new-prefix-${generateRandomShortId()}`; - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - ], - oAuth: { - domainPrefix: updatedDomainPrefix, - }, - }, - includeIdentityPool: false, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - await amplifyPushNonInteractive(projRoot, true); - - const userPoolId = getUserPoolId(projRoot); - const hostedUIDomain = getHostedUIDomain(projRoot); - - expect(userPoolId).toEqual(originalUserPoolId); - const userPoolRes = await getUserPool(userPoolId, region); - expect(hostedUIDomain).not.toEqual(originalHostedUIDomain); - expect(hostedUIDomain).toMatch(updatedDomainPrefix); - expect(hostedUIDomain).toEqual(userPoolRes.UserPool.Domain); - - const updatedDomainRes = await getUserPoolDomain(hostedUIDomain, region); - expect(updatedDomainRes).toBeDefined(); - const originalDomainRes = await getUserPoolDomain(originalHostedUIDomain, region); - expect(originalDomainRes).toEqual({ DomainDescription: {} }); - - const deleteOriginalDomainRes = await deleteUserPoolDomain(originalHostedUIDomain, userPoolId, region); - // undefined response as it throws InvalidParameterException: No such domain or user pool exists. - expect(deleteOriginalDomainRes).toBeUndefined(); - }); - - it('updates hosted ui domain with new version and pushes', async () => { - const updatedDomainPrefix = `new-prefix-${generateRandomShortId()}`; - await updateAuthDomainPrefixWithAllProvidersConfigured(projRoot, { - domainPrefix: updatedDomainPrefix, - testingWithLatestCodebase: true, - }); - await amplifyPushAuth(projRoot, true); - - const userPoolId = getUserPoolId(projRoot); - const hostedUIDomain = getHostedUIDomain(projRoot); - - expect(userPoolId).toEqual(originalUserPoolId); - const userPoolRes = await getUserPool(userPoolId, region); - expect(hostedUIDomain).not.toEqual(originalHostedUIDomain); - expect(hostedUIDomain).toMatch(updatedDomainPrefix); - expect(hostedUIDomain).toEqual(userPoolRes.UserPool.Domain); - - const updatedDomainRes = await getUserPoolDomain(hostedUIDomain, region); - expect(updatedDomainRes).toBeDefined(); - const originalDomainRes = await getUserPoolDomain(originalHostedUIDomain, region); - expect(originalDomainRes).toEqual({ DomainDescription: {} }); - - const deleteOriginalDomainRes = await deleteUserPoolDomain(originalHostedUIDomain, userPoolId, region); - // undefined response as it throws InvalidParameterException: No such domain or user pool exists. - expect(deleteOriginalDomainRes).toBeUndefined(); - }); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration-rollback.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration-rollback.test.ts deleted file mode 100644 index c69ea27bd67..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration-rollback.test.ts +++ /dev/null @@ -1,120 +0,0 @@ -import type { IAmplifyResource } from '@aws-amplify/amplify-cli-core'; -import { - addAuthWithMaxOptions, - amplifyPushAuth, - amplifyPushForce, - createNewProjectDir, - configureAmplify, - deleteProject, - deleteProjectDir, - generateRandomShortId, - getProjectMeta, - listUsersInUserPool, - setupUser, - signInUser, - signOutUser, - getUserPool, - listSocialIdpProviders, - initJSProjectWithProfile, - addS3StorageWithIdpAuth, -} from '@aws-amplify/amplify-e2e-core'; -import { validateVersionsForMigrationTest } from '../../migration-helpers'; - -const defaultsSettings = { - name: 'authTest', - disableAmplifyAppCreation: true, -}; - -describe('lambda callouts rollback', () => { - let projRoot: string; - const projectName: string = 'lambdaRollback'; - - beforeAll(async () => { - await validateVersionsForMigrationTest(); - }); - - beforeEach(async () => { - projRoot = await createNewProjectDir(projectName); - }); - - afterEach(async () => { - await deleteProject(projRoot); - deleteProjectDir(projRoot); - }); - - it('should rollback without affecting user pool functionality', async () => { - await initJSProjectWithProfile(projRoot, { ...defaultsSettings, testingWithLatestCodebase: true }); - - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName, testingWithLatestCodebase: true }); - - await amplifyPushAuth(projRoot, true); - - const meta = getProjectMeta(projRoot); - expect(meta?.providers?.awscloudformation?.Region).toBeDefined(); - expect(meta?.auth).toBeDefined(); - const region = meta.providers.awscloudformation.Region; - const { UserPoolId } = Object.values(meta.auth as Record).find( - (resource) => resource.service === 'Cognito', - ).output; - - await configureAmplify(projRoot); - - const username = 'testUser'; - const password = 'Password12#'; - await setupUser(UserPoolId, username, 'Password12#', 'userPoolGroup1', region); - - await signInUser(username, password); - await signOutUser(); - - await amplifyPushForce(projRoot, false); - - const users = await listUsersInUserPool(UserPoolId, region); - expect(users).toEqual([username.toLowerCase()]); - - await signInUser(username, password); - await signOutUser(); - }); - - it('should keep identity providers and domain during rollback', async () => { - await initJSProjectWithProfile(projRoot, { ...defaultsSettings, testingWithLatestCodebase: true }); - - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName, testingWithLatestCodebase: true }); - - await amplifyPushAuth(projRoot, true); - - const meta = getProjectMeta(projRoot); - const region = meta.providers.awscloudformation.Region; - const { UserPoolId } = Object.keys(meta.auth) - .map((key) => meta.auth[key]) - .find((auth) => auth.service === 'Cognito').output; - const userPoolRes1 = await getUserPool(UserPoolId, region); - const userPoolDomainLatest = userPoolRes1.UserPool.Domain; - const socialIdpProvidersLatest = await listSocialIdpProviders(UserPoolId, region); - - await amplifyPushForce(projRoot, false); - - const userPoolRes2 = await getUserPool(UserPoolId, region); - const userPoolDomainV12 = userPoolRes2.UserPool.Domain; - const socialIdpProvidersV12 = await listSocialIdpProviders(UserPoolId, region); - - // check same domain should exist - expect(userPoolDomainV12).toEqual(userPoolDomainLatest); - // check the Social Idp Provider exists - expect(socialIdpProvidersV12).toEqual(socialIdpProvidersLatest); - }); - - it('can rollback, add new other resource and push', async () => { - await initJSProjectWithProfile(projRoot, { ...defaultsSettings, testingWithLatestCodebase: true }); - - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName, testingWithLatestCodebase: true }); - - await amplifyPushAuth(projRoot, true); - - await addS3StorageWithIdpAuth(projRoot, false); - - await amplifyPushAuth(projRoot, false); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration.test.ts deleted file mode 100644 index 8a72726c5bc..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-lambda-callout-migration.test.ts +++ /dev/null @@ -1,195 +0,0 @@ -import type { IAmplifyResource } from '@aws-amplify/amplify-cli-core'; -import { - addAuthWithMaxOptions, - amplifyPushAuth, - amplifyPushForce, - createNewProjectDir, - configureAmplify, - deleteProject, - deleteProjectDir, - generateRandomShortId, - getCloudFormationTemplate, - getProjectMeta, - listUsersInUserPool, - setupUser, - signInUser, - signOutUser, - getUserPool, - listSocialIdpProviders, - updateHeadlessAuth, - addAuthWithDefault, -} from '@aws-amplify/amplify-e2e-core'; -import { validateVersionsForMigrationTest } from '../../migration-helpers'; -import { expectLambdasInCfnTemplate, migratedLambdas, nonMigratedLambdas } from '../../migration-helpers-v12/auth-helpers/utilities'; -import { initJSProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { UpdateAuthRequest } from 'amplify-headless-interface'; - -const defaultsSettings = { - name: 'authTest', - disableAmplifyAppCreation: true, -}; - -describe('lambda callouts', () => { - let projRoot: string; - const projectName: string = 'lambdaRemove'; - - beforeAll(async () => { - await validateVersionsForMigrationTest(); - }); - - beforeEach(async () => { - projRoot = await createNewProjectDir(projectName); - }); - - afterEach(async () => { - await deleteProject(projRoot); - deleteProjectDir(projRoot); - }); - - it('should be migrated when auth is in the create state, then reverted back', async () => { - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName }); - - const preMigrationTemplate = await getCloudFormationTemplate(projRoot, 'auth', resourceName); - expectLambdasInCfnTemplate(preMigrationTemplate, migratedLambdas.concat(nonMigratedLambdas), []); - - // push with latest should regenerate auth stack and start migrating lambda callouts - await amplifyPushAuth(projRoot, true); - - // a second push with latest should finish migrating the lambda callouts - await amplifyPushForce(projRoot, true); - - const postMigrationTemplate = await getCloudFormationTemplate(projRoot, 'auth', resourceName); - expectLambdasInCfnTemplate(postMigrationTemplate, nonMigratedLambdas, migratedLambdas); - - // revert to previous CLI version - await amplifyPushForce(projRoot, false); - - const revertTemplate = await getCloudFormationTemplate(projRoot, 'auth', resourceName); - expectLambdasInCfnTemplate(revertTemplate, migratedLambdas.concat(nonMigratedLambdas), []); - }); - - it('should migrate when force pushing without affecting user pool functionality', async () => { - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName }); - - await amplifyPushAuth(projRoot, false); - - const meta = getProjectMeta(projRoot); - expect(meta?.providers?.awscloudformation?.Region).toBeDefined(); - expect(meta?.auth).toBeDefined(); - const region = meta.providers.awscloudformation.Region; - const { UserPoolId } = Object.values(meta.auth as Record).find( - (resource) => resource.service === 'Cognito', - ).output; - - await configureAmplify(projRoot); - - const username = 'testUser'; - const password = 'Password12#'; - await setupUser(UserPoolId, username, 'Password12#', 'userPoolGroup1', region); - - await signInUser(username, password); - await signOutUser(); - - await amplifyPushForce(projRoot, true); - - let users = await listUsersInUserPool(UserPoolId, region); - expect(users).toEqual([username.toLowerCase()]); - - await signInUser(username, password); - await signOutUser(); - - await amplifyPushForce(projRoot, true); - - users = await listUsersInUserPool(UserPoolId, region); - expect(users).toEqual([username.toLowerCase()]); - - await signInUser(username, password); - await signOutUser(); - }); - - it('should keep identity providers and domain during migration', async () => { - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - - const resourceName = `test${generateRandomShortId()}`; - await addAuthWithMaxOptions(projRoot, { name: resourceName }); - - await amplifyPushAuth(projRoot, false); - - const meta = getProjectMeta(projRoot); - const region = meta.providers.awscloudformation.Region; - const { UserPoolId } = Object.keys(meta.auth) - .map((key) => meta.auth[key]) - .find((auth) => auth.service === 'Cognito').output; - const userPoolRes1 = await getUserPool(UserPoolId, region); - const userPoolDomainV12 = userPoolRes1.UserPool.Domain; - const socialIdpProvidersV12 = await listSocialIdpProviders(UserPoolId, region); - - await amplifyPushForce(projRoot, true); - - const userPoolRes2 = await getUserPool(UserPoolId, region); - const userPoolDomainLatest = userPoolRes2.UserPool.Domain; - const socialIdpProvidersLatest = await listSocialIdpProviders(UserPoolId, region); - // check same domain should exist - expect(userPoolDomainV12).toEqual(userPoolDomainLatest); - // check the Social Idp Provider exists - expect(socialIdpProvidersV12).toEqual(socialIdpProvidersLatest); - }); - - it('should be migrated when updating using headless commands', async () => { - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - await addAuthWithDefault(projRoot, false); - await amplifyPushAuth(projRoot, false); - - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - ], - oAuth: { - domainPrefix: generateRandomShortId(), - redirectSigninURIs: ['http://localhost/'], - redirectSignoutURIs: ['http://localhost/'], - socialProviderConfigurations: [ - { - provider: 'FACEBOOK', - clientId: '1234', - clientSecret: '5678', - }, - ], - }, - }, - includeIdentityPool: true, - identityPoolModification: { - identitySocialFederation: [{ provider: 'GOOGLE', clientId: 'fakeClientId' }], - }, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - await amplifyPushAuth(projRoot, true); - await amplifyPushForce(projRoot, true); - - const meta = getProjectMeta(projRoot); - const resourceName = Object.keys(meta.auth)[0]; - const template = await getCloudFormationTemplate(projRoot, 'auth', resourceName); - expectLambdasInCfnTemplate(template, nonMigratedLambdas, migratedLambdas); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-oauth-lambda-migration.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-oauth-lambda-migration.test.ts deleted file mode 100644 index 2eb9d9483cf..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-oauth-lambda-migration.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { - AddAuthUserPoolOnlyWithOAuthSettings, - amplifyPushForce, - amplifyPushNonInteractive, - createNewProjectDir, - deleteProject, - deleteProjectDir, - updateHeadlessAuth, -} from '@aws-amplify/amplify-e2e-core'; -import { allowedVersionsToMigrateFrom, versionCheck } from '../../migration-helpers'; -import { expectCorrectOAuthSettings, setupOgProjectWithAuth } from '../../migration-helpers-v12/auth-helpers/utilities'; -import { initJSProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { pullPushForceWithLatestCodebaseValidateParameterAndCfnDrift } from '../../migration-helpers/utils'; -import { UpdateAuthRequest } from 'amplify-headless-interface'; - -const defaultsSettings = { - name: 'authTest', - disableAmplifyAppCreation: false, -}; - -describe('amplify add auth...', () => { - let projRoot: string; - let oAuthSettings: AddAuthUserPoolOnlyWithOAuthSettings; - const projectName: string = 'oauthlambdaRemove'; - - beforeAll(async () => { - const migrateFromVersion = { v: 'uninitialized' }; - const migrateToVersion = { v: 'uninitialized' }; - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - console.log(`Test migration from: ${migrateFromVersion.v} to ${migrateToVersion.v}`); - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - beforeEach(async () => { - projRoot = await createNewProjectDir(projectName); - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - // creates a userPool only with OauthSetting and pushes Auth - oAuthSettings = await setupOgProjectWithAuth(projRoot, { name: 'ogauimphea' }); - }); - - afterEach(async () => { - await deleteProject(projRoot); - deleteProjectDir(projRoot); - }); - - it('...should init an Js project and add Oauth settings with userpool', async () => { - const projRoot2 = await createNewProjectDir(`${projectName}2`); - // using amplify push force here as changes are only related to build files - await pullPushForceWithLatestCodebaseValidateParameterAndCfnDrift(projRoot, projRoot2); - }); - - it('...should preserve Oauth settings on force push with new', async () => { - await amplifyPushForce(projRoot, true); - await expectCorrectOAuthSettings(projRoot, oAuthSettings); - }); - - it('...should update auth headless and push with new', async () => { - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - ], - }, - includeIdentityPool: false, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - await amplifyPushNonInteractive(projRoot, true); - await expectCorrectOAuthSettings(projRoot, oAuthSettings); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-role-mapping-migration-test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-role-mapping-migration-test.ts deleted file mode 100644 index ce1c6eb81ec..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth-role-mapping-migration-test.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { allowedVersionsToMigrateFrom, versionCheck } from '../../migration-helpers'; -import { - addAuthWithDefault, - addS3WithFirstGroupAccess, - amplifyPushAuth, - amplifyPushForce, - amplifyPushNonInteractive, - configureAmplify, - createNewProjectDir, - deleteProject, - deleteProjectDir, - getProjectMeta, - getS3StorageBucketName, - getUserPoolId, - setupUser, - signInUser, - signOutUser, - updateAuthAddUserGroups, - updateHeadlessAuth, -} from '@aws-amplify/amplify-e2e-core'; -import { initJSProjectWithProfileV12 } from '../../migration-helpers-v12/init'; -import { Auth } from 'aws-amplify'; -import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'; -import { UpdateAuthRequest } from 'amplify-headless-interface'; - -describe('amplify auth group mapping', () => { - beforeAll(async () => { - const migrateFromVersion = { v: '12.0.3' }; - const migrateToVersion = { v: 'uninitialized' }; - - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - let projRoot: string; - - beforeEach(async () => { - projRoot = await createNewProjectDir('groupMapping'); - }); - - afterEach(async () => { - await deleteProject(projRoot, null, true); - deleteProjectDir(projRoot); - }); - - const defaultsSettings = { - name: 'authS3Test', - }; - - const username1 = 'testUser1'; - const password1 = 'Password12#1'; - const username2 = 'testUser2'; - const password2 = 'Password12#2'; - - const setupUsers = async () => { - const meta = getProjectMeta(projRoot); - const region = meta.providers.awscloudformation.Region; - const userPoolId = getUserPoolId(projRoot); - - await configureAmplify(projRoot); - await setupUser(userPoolId, username1, password1, 'group1', region); - await setupUser(userPoolId, username2, password2, 'group2', region); - }; - - const verifyUserAccess = async () => { - const meta = getProjectMeta(projRoot); - const region = meta.providers.awscloudformation.Region; - const bucketName = getS3StorageBucketName(projRoot); - - await configureAmplify(projRoot); - - const s3key = 'foo'; - const s3val = 'bar'; - - // Check that user 1 can interact with S3 bucket - await signInUser(username1, password1); - const user1Credentials = await Auth.currentCredentials(); - - const s3Client1 = new S3Client({ - region, - credentials: Auth.essentialCredentials(user1Credentials), - }); - await s3Client1.send( - new PutObjectCommand({ - Bucket: bucketName, - Key: s3key, - Body: s3val, - }), - ); - const valRes = await ( - await s3Client1.send( - new GetObjectCommand({ - Bucket: bucketName, - Key: s3key, - }), - ) - ).Body.transformToString(); - expect(valRes).toEqual(s3val); - await signOutUser(); - - // Check that user 2 does not have permissions to interact with S3 bucket - await signInUser(username2, password2); - const user2Credentials = await Auth.currentCredentials(); - const s3Client2 = new S3Client({ - region, - credentials: Auth.essentialCredentials(user2Credentials), - }); - await expect( - s3Client2.send( - new GetObjectCommand({ - Bucket: bucketName, - Key: s3key, - }), - ), - ).rejects.toThrow('Access Denied'); - await expect( - s3Client2.send( - new PutObjectCommand({ - Bucket: bucketName, - Key: s3key, - Body: s3val, - }), - ), - ).rejects.toThrow('Access Denied'); - await signOutUser(); - }; - - describe('project with group mapping created by old version', () => { - beforeEach(async () => { - await initJSProjectWithProfileV12(projRoot, defaultsSettings); - await addAuthWithDefault(projRoot); - await updateAuthAddUserGroups(projRoot, ['group1', 'group2']); - await addS3WithFirstGroupAccess(projRoot); - await amplifyPushNonInteractive(projRoot); - await setupUsers(); - await verifyUserAccess(); - }); - - it('force pushes with latest and checks access', async () => { - await amplifyPushForce(projRoot, true); - await verifyUserAccess(); - }); - - it('updates auth with latest, pushes and checks access', async () => { - await updateAuthAddUserGroups(projRoot, ['group3'], { testingWithLatestCodebase: true, hasExistingUserPoolGroups: true }); - await amplifyPushAuth(projRoot, true); - await verifyUserAccess(); - }); - - it('updates auth headless with latest, pushes and checks access', async () => { - const updateAuthRequest: UpdateAuthRequest = { - version: 2, - serviceModification: { - serviceName: 'Cognito', - userPoolModification: { - autoVerifiedAttributes: [ - { - type: 'EMAIL', - }, - ], - userPoolGroups: [ - { - groupName: 'group1', - }, - { - groupName: 'group2', - }, - { - groupName: 'group3', - }, - ], - }, - includeIdentityPool: true, - identityPoolModification: {}, - }, - }; - - await updateHeadlessAuth(projRoot, updateAuthRequest, { testingWithLatestCodebase: true }); - await amplifyPushNonInteractive(projRoot, true); - await verifyUserAccess(); - }); - }); -}); diff --git a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth.migration.test.ts b/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth.migration.test.ts deleted file mode 100644 index e57fa981f28..00000000000 --- a/packages/amplify-migration-tests/src/__tests__/migration_tests_v12/auth.migration.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - addAuthWithGroups, - amplifyPull, - amplifyPushAuth, - createNewProjectDir, - deleteProject, - deleteProjectDir, - getAppId, - getIdentityPoolRoles, - getProjectMeta, - initJSProjectWithProfile, - updateAuthAddUserGroupsAfterPull, -} from '@aws-amplify/amplify-e2e-core'; -import { versionCheck, allowedVersionsToMigrateFrom } from '../../migration-helpers'; - -describe('v12: amplify migration test auth', () => { - let projRoot1: string; - - beforeAll(async () => { - const migrateFromVersion = { v: '12.0.3' }; - const migrateToVersion = { v: 'uninitialized' }; - - await versionCheck(process.cwd(), false, migrateFromVersion); - await versionCheck(process.cwd(), true, migrateToVersion); - - expect(allowedVersionsToMigrateFrom).toContain(migrateFromVersion.v); - }); - - beforeEach(async () => { - projRoot1 = await createNewProjectDir('authMigration1'); - }); - - afterEach(async () => { - await deleteProject(projRoot1, null, true); - deleteProjectDir(projRoot1); - }); - - describe('...uses user groups and role mappings', () => { - it('...maintains correct role mapping when updated with latest version', async () => { - await initJSProjectWithProfile(projRoot1, { - name: 'authTest', - disableAmplifyAppCreation: false, - includeGen2RecommendationPrompt: false, - }); - await addAuthWithGroups(projRoot1); - await amplifyPushAuth(projRoot1); - - const meta = getProjectMeta(projRoot1); - const region = meta.providers.awscloudformation.Region; - const { AppClientID, AppClientIDWeb, IdentityPoolId, UserPoolId } = Object.keys(meta.auth) - .map((key) => meta.auth[key]) - .find((auth) => auth.service === 'Cognito').output; - - const roleMapKeyClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientID}`; - const roleMapKeyWebClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientIDWeb}`; - const appId = getAppId(projRoot1); - const projRoot2 = await createNewProjectDir('authMigration2'); - - expect(appId).toBeDefined(); - - const identityPoolRolesBefore = await getIdentityPoolRoles(IdentityPoolId, region); - const roleMapKeyClientIdAmbigousRoleRes = identityPoolRolesBefore.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution; - const roleMapKeyClientIdType = identityPoolRolesBefore.RoleMappings[roleMapKeyClientId].Type; - const roleMapKeyWebClientIdAmbigousRoleRes = identityPoolRolesBefore.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution; - const roleMapKeyWebClientIdType = identityPoolRolesBefore.RoleMappings[roleMapKeyWebClientId].Type; - - try { - await amplifyPull(projRoot2, { emptyDir: true, appId }, true); - await updateAuthAddUserGroupsAfterPull(projRoot2, ['SuperUsers'], { testingWithLatestCodebase: true }); - await amplifyPushAuth(projRoot2, true); - - const identityPoolRolesAfter = await getIdentityPoolRoles(IdentityPoolId, region); - - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution).toEqual(roleMapKeyClientIdAmbigousRoleRes); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyClientId].Type).toEqual(roleMapKeyClientIdType); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution).toEqual( - roleMapKeyWebClientIdAmbigousRoleRes, - ); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyWebClientId].Type).toEqual(roleMapKeyWebClientIdType); - - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyClientId].Type).toEqual('Token'); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); - expect(identityPoolRolesAfter.RoleMappings[roleMapKeyWebClientId].Type).toEqual('Token'); - } finally { - deleteProjectDir(projRoot2); - } - }); - }); -}); diff --git a/packages/amplify-migration-tests/src/migration-helpers-v12/auth-helpers/utilities.ts b/packages/amplify-migration-tests/src/migration-helpers-v12/auth-helpers/utilities.ts deleted file mode 100644 index 8d1861ff09d..00000000000 --- a/packages/amplify-migration-tests/src/migration-helpers-v12/auth-helpers/utilities.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type { $TSObject } from '@aws-amplify/amplify-cli-core'; -import { - addAuthUserPoolOnlyWithOAuth, - AddAuthUserPoolOnlyWithOAuthSettings, - amplifyPushAuth, - generateRandomShortId, - getProjectMeta, - getSocialIdpProvider, -} from '@aws-amplify/amplify-e2e-core'; - -/** - * sets up a project with auth (UserPool only or UserPool & IdentityPool) - */ -export const setupOgProjectWithAuth = async ( - ogProjectRoot: string, - ogProjectSettings: { name: string }, -): Promise => { - const ogShortId = generateRandomShortId(); - const oauthSettings = createUserPoolWithOAuthSettings(ogProjectSettings.name, ogShortId); - await addAuthUserPoolOnlyWithOAuth(ogProjectRoot, createUserPoolWithOAuthSettings(ogProjectSettings.name, ogShortId)); - await amplifyPushAuth(ogProjectRoot); - return oauthSettings; -}; - -const createUserPoolWithOAuthSettings = (projectPrefix: string, shortId: string): AddAuthUserPoolOnlyWithOAuthSettings => { - return { - // eslint-disable spellcheck/spell-checker - resourceName: `${projectPrefix}oares${shortId}`, - userPoolName: `${projectPrefix}oaup${shortId}`, - domainPrefix: `${projectPrefix}oadom${shortId}`, - signInUrl1: 'https://sin1/', - signInUrl2: 'https://sin2/', - signOutUrl1: 'https://sout1/', - signOutUrl2: 'https://sout2/', - facebookAppId: 'facebookAppId', - facebookAppSecret: 'facebookAppSecret', - googleAppId: 'googleAppId', - googleAppSecret: 'googleAppSecret', - amazonAppId: 'amazonAppId', - amazonAppSecret: 'amazonAppSecret', - appleAppClientId: 'com.fake.app', - appleAppTeamId: '2QLEWNDK6K', - appleAppKeyID: '2QLZXKYJ8J', - appleAppPrivateKey: - '----BEGIN PRIVATE KEY----MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw----END PRIVATE KEY----', - // eslint-enable spellcheck/spell-checker - }; -}; - -const lambdaCalloutFilter = (r: $TSObject) => r?.Type === 'AWS::Lambda::Function' || r?.Type === 'Custom::LambdaCallout'; - -export const migratedLambdas = ['UserPoolClientLambda', 'UserPoolClientInputs', 'OAuthCustomResource', 'OAuthCustomResourceInputs']; -export const nonMigratedLambdas = [ - 'HostedUICustomResource', - 'HostedUICustomResourceInputs', - 'HostedUIProvidersCustomResource', - 'HostedUIProvidersCustomResourceInputs', -]; - -const getLambdaNamesInCfnTemplate = (template: $TSObject): Array => { - return Object.entries(template.Resources) - .filter((entry) => lambdaCalloutFilter(entry[1])) - .map((entry) => entry[0]); -}; - -export const expectLambdasInCfnTemplate = (template: $TSObject, namesPresent: Array, namesAbsent: Array): void => { - expect(template?.Resources).toBeDefined(); - const lambdasInCfnTemplate = getLambdaNamesInCfnTemplate(template); - for (const name of namesPresent) { - expect(lambdasInCfnTemplate).toContain(name); - } - for (const name of namesAbsent) { - expect(lambdasInCfnTemplate).not.toContain(name); - } -}; - -export const expectCorrectOAuthSettings = async (projRoot: string, oAuthSettings: AddAuthUserPoolOnlyWithOAuthSettings): Promise => { - const meta = getProjectMeta(projRoot); - const authMeta = Object.keys(meta.auth).map((key) => meta.auth[key])[0]; - const id = authMeta.output.UserPoolId; - const idpFacebook = await getSocialIdpProvider(id, 'Facebook', meta.providers.awscloudformation.Region); - const idpGoogle = await getSocialIdpProvider(id, 'Google', meta.providers.awscloudformation.Region); - const idpAmazon = await getSocialIdpProvider(id, 'LoginWithAmazon', meta.providers.awscloudformation.Region); - const idpApple = await getSocialIdpProvider(id, 'SignInWithApple', meta.providers.awscloudformation.Region); - expect(idpFacebook.IdentityProvider.ProviderDetails.client_id).toEqual(oAuthSettings.facebookAppId); - expect(idpFacebook.IdentityProvider.ProviderDetails.client_secret).toEqual(oAuthSettings.facebookAppSecret); - expect(idpGoogle.IdentityProvider.ProviderDetails.client_id).toEqual(oAuthSettings.googleAppId); - expect(idpGoogle.IdentityProvider.ProviderDetails.client_secret).toEqual(oAuthSettings.googleAppSecret); - expect(idpAmazon.IdentityProvider.ProviderDetails.client_id).toEqual(oAuthSettings.amazonAppId); - expect(idpAmazon.IdentityProvider.ProviderDetails.client_secret).toEqual(oAuthSettings.amazonAppSecret); - expect(idpApple.IdentityProvider.ProviderDetails.client_id).toEqual(oAuthSettings.appleAppClientId); - expect(idpApple.IdentityProvider.ProviderDetails.key_id).toEqual(oAuthSettings.appleAppKeyID); -}; diff --git a/packages/amplify-migration-tests/src/migration-helpers-v12/cfn-diff-exclusions.ts b/packages/amplify-migration-tests/src/migration-helpers-v12/cfn-diff-exclusions.ts deleted file mode 100644 index 8b237fb0cb8..00000000000 --- a/packages/amplify-migration-tests/src/migration-helpers-v12/cfn-diff-exclusions.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ExcludeFromCFNDiff } from '../migration-helpers/utils'; - -/** - * Due to a known limitation of APIGateway, we do not want the AWS::ApiGateway::Deployment resource - * from being compared in the CFN diff because it is regenerated whenever an amplify app is pulled down. - * This would produce a false positive when checking for differences in the CFN templates of project1 & project2. - * https://github.com/aws/aws-cdk/issues/8646#issuecomment-647561856 - * - * AWS::ApiGateway::GatewayResponse is also excluded - */ -export const cfnDiffExclusions: ExcludeFromCFNDiff = ( - currentCategory: string, - currentResourceKey: string, - cfnTemplates: { - project1: Record; - project2: Record; - }, -) => { - const excludeAPIGateWayDeploymentResource = (cfnTemplate: Record): void => { - const resources = cfnTemplate.Resources ?? {}; - const resourceKeys = Object.keys(resources); - for (const key of resourceKeys) { - const resource = resources[key]; - if (resource.Type === 'AWS::ApiGateway::Deployment' || resource.Type === 'AWS::ApiGateway::GatewayResponse') { - delete resources[key]; - } - if (resource.Type === 'AWS::AppSync::ApiKey' && resource.Properties) { - delete resource.Properties.Expires; - } - } - }; - if (currentCategory === 'api') { - excludeAPIGateWayDeploymentResource(cfnTemplates.project1); - excludeAPIGateWayDeploymentResource(cfnTemplates.project2); - } - return { project1: cfnTemplates.project1, project2: cfnTemplates.project2 }; -}; diff --git a/packages/amplify-migration-tests/src/migration-helpers-v12/init.ts b/packages/amplify-migration-tests/src/migration-helpers-v12/init.ts deleted file mode 100644 index abf45abd853..00000000000 --- a/packages/amplify-migration-tests/src/migration-helpers-v12/init.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { getCLIPath, nspawn as spawn } from '@aws-amplify/amplify-e2e-core'; -import { EOL } from 'os'; - -const defaultSettings = { - name: EOL, - // eslint-disable-next-line spellcheck/spell-checker - envName: 'integtest', - editor: EOL, - appType: EOL, - framework: EOL, - srcDir: EOL, - distDir: EOL, - buildCmd: EOL, - startCmd: EOL, - useProfile: EOL, - profileName: EOL, - region: process.env.CLI_REGION, - local: false, - disableAmplifyAppCreation: true, - disableCIDetection: false, - providerConfig: undefined, - permissionsBoundaryArn: undefined, -}; - -export function initJSProjectWithProfileV12(cwd: string, settings?: Partial): Promise { - const s = { ...defaultSettings, ...settings }; - let env; - - if (s.disableAmplifyAppCreation === true) { - env = { - CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1', - }; - } - - const cliArgs = ['init']; - const providerConfigSpecified = !!s.providerConfig && typeof s.providerConfig === 'object'; - if (providerConfigSpecified) { - cliArgs.push('--providers', JSON.stringify(s.providerConfig)); - } - - if (s.permissionsBoundaryArn) { - cliArgs.push('--permissions-boundary', s.permissionsBoundaryArn); - } - - if (s?.name?.length > 20) console.warn('Project names should not be longer than 20 characters. This may cause tests to break.'); - - const chain = spawn(getCLIPath(), cliArgs, { - cwd, - stripColors: true, - env, - disableCIDetection: s.disableCIDetection, - }) - .wait('Enter a name for the project') - .sendLine(s.name) - .wait('Initialize the project with the above configuration?') - .sendConfirmNo() - .wait('Enter a name for the environment') - .sendLine(s.envName) - .wait('Choose your default editor:') - .sendLine(s.editor) - .wait("Choose the type of app that you're building") - .sendLine(s.appType) - .wait('What javascript framework are you using') - .sendLine(s.framework) - .wait('Source Directory Path:') - .sendLine(s.srcDir) - .wait('Distribution Directory Path:') - .sendLine(s.distDir) - .wait('Build Command:') - .sendLine(s.buildCmd) - .wait('Start Command:') - .sendCarriageReturn(); - - if (!providerConfigSpecified) { - chain - .wait('Using default provider awscloudformation') - .wait('Select the authentication method you want to use:') - .sendCarriageReturn() - .wait('Please choose the profile you want to use') - .sendLine(s.profileName); - } - return chain - .wait(/Help improve Amplify CLI by sharing non( |-)sensitive( | project )configurations on failures/) - .sendYes() - .wait(/Try "amplify add api" to create a backend API and then "amplify (push|publish)" to deploy everything/) - .runAsync(); -} - -export function initIosProjectWithProfileV12(cwd: string, settings: Record): Promise { - const s = { ...defaultSettings, ...settings }; - - let env; - - if (s.disableAmplifyAppCreation === true) { - env = { - CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1', - }; - } - - return spawn(getCLIPath(), ['init'], { - cwd, - stripColors: true, - env, - }) - .wait('Do you want to continue with Amplify Gen 1?') - .sendYes() - .wait('Why would you like to use Amplify Gen 1?') - .sendCarriageReturn() - .wait('Enter a name for the project') - .sendLine(s.name) - .wait('Initialize the project with the above configuration?') - .sendConfirmNo() - .wait('Enter a name for the environment') - .sendLine(s.envName) - .wait('Choose your default editor:') - .sendLine(s.editor) - .wait("Choose the type of app that you're building") - .sendKeyDown(3) - .sendCarriageReturn() - .wait('Select the authentication method you want to use:') - .sendCarriageReturn() - .wait('Please choose the profile you want to use') - .sendLine(s.profileName) - .wait(/Help improve Amplify CLI by sharing non( |-)sensitive( | project )configurations on failures/) - .sendYes() - .wait(/Try "amplify add api" to create a backend API and then "amplify (push|publish)" to deploy everything/) - .runAsync(); -} - -export function initAndroidProjectWithProfileV12(cwd: string, settings: Partial): Promise { - const s = { ...defaultSettings, ...settings }; - - let env; - - if (s.disableAmplifyAppCreation) { - env = { - CLI_DEV_INTERNAL_DISABLE_AMPLIFY_APP_CREATION: '1', - }; - } - - return spawn(getCLIPath(), ['init'], { - cwd, - stripColors: true, - env, - }) - .wait('Enter a name for the project') - .sendLine(s.name) - .wait('Initialize the project with the above configuration?') - .sendConfirmNo() - .wait('Enter a name for the environment') - .sendLine(s.envName) - .wait('Choose your default editor:') - .sendLine(s.editor) - .wait("Choose the type of app that you're building") - .sendKeyDown(1) - .sendCarriageReturn() - .wait('Where is your Res directory') - .sendCarriageReturn() - .wait('Select the authentication method you want to use:') - .sendCarriageReturn() - .wait('Please choose the profile you want to use') - .sendLine(s.profileName) - .wait(/Help improve Amplify CLI by sharing non( |-)sensitive( | project )configurations on failures/) - .sendYes() - .wait(/Try "amplify add api" to create a backend API and then "amplify (push|publish)" to deploy everything/) - .runAsync(); -} diff --git a/scripts/split-e2e-test-filters.ts b/scripts/split-e2e-test-filters.ts index 1451a7bbbdf..e69de29bb2d 100644 --- a/scripts/split-e2e-test-filters.ts +++ b/scripts/split-e2e-test-filters.ts @@ -1,15 +0,0 @@ -export const migrationFromV8Tests = [ - 'src/__tests__/migration_tests/transformer_migration/api.key.migration-2.test.ts', - 'src/__tests__/migration_tests/transformer_migration/api.key.migration.test.ts', -]; - -export const migrationFromV12Tests = [ - 'src/__tests__/migration_tests_v12/auth.migration.test.ts', - 'src/__tests__/migration_tests_v12/auth-app-client-secret-migration.test.ts', - 'src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-1.test.ts', - 'src/__tests__/migration_tests_v12/auth-hosted-ui-lambda-migration-2.test.ts', - 'src/__tests__/migration_tests_v12/auth-lambda-callout-migration.test.ts', - 'src/__tests__/migration_tests_v12/auth-lambda-callout-migration-rollback.test.ts', - 'src/__tests__/migration_tests_v12/auth-oauth-lambda-migration.test.ts', - 'src/__tests__/migration_tests_v12/auth-role-mapping-migration-test.ts', -]; diff --git a/scripts/split-e2e-tests-codebuild.ts b/scripts/split-e2e-tests-codebuild.ts index 163c9cc76d7..8759de97b4d 100644 --- a/scripts/split-e2e-tests-codebuild.ts +++ b/scripts/split-e2e-tests-codebuild.ts @@ -4,7 +4,6 @@ import { join } from 'path'; import * as yaml from 'js-yaml'; import { REPO_ROOT } from './cci-utils'; import { FORCE_REGION_MAP, getOldJobNameWithoutSuffixes, loadTestTimings, USE_PARENT_ACCOUNT } from './cci-utils'; -import { migrationFromV12Tests, migrationFromV8Tests } from './split-e2e-test-filters'; const CODEBUILD_CONFIG_BASE_PATH = join(REPO_ROOT, 'codebuild_specs', 'e2e_workflow_base.yml'); const CODEBUILD_GENERATE_CONFIG_PATH = join(REPO_ROOT, 'codebuild_specs', 'e2e_workflow_generated'); const RUN_SOLO = [ @@ -329,36 +328,8 @@ function main(): void { false, undefined, ); - const splitMigrationV8Tests = splitTestsV3( - { - identifier: 'migration_tests_v8', - buildspec: 'codebuild_specs/migration_tests_v8.yml', - env: {}, - 'depend-on': ['upb'], - }, - undefined, - join(REPO_ROOT, 'packages', 'amplify-migration-tests'), - true, - (tests: string[]) => { - return tests.filter((testName) => migrationFromV8Tests.find((t: string) => t === testName)); - }, - ); - const splitMigrationV12Tests = splitTestsV3( - { - identifier: 'migration_tests_v12', - buildspec: 'codebuild_specs/migration_tests_v12.yml', - env: {}, - 'depend-on': ['upb'], - }, - undefined, - join(REPO_ROOT, 'packages', 'amplify-migration-tests'), - true, - (tests: string[]) => { - return tests.filter((testName) => migrationFromV12Tests.find((t) => t === testName)); - }, - ); - let allBuilds = [...splitE2ETests, ...splitMigrationV8Tests, ...splitMigrationV12Tests]; + let allBuilds = [...splitE2ETests]; const dependeeIdentifiers: string[] = allBuilds.map((buildObject) => buildObject.identifier).sort(); const dependeeIdentifiersFileContents = `${JSON.stringify(dependeeIdentifiers, null, 2)}\n`; const waitForIdsFilePath = './codebuild_specs/wait_for_ids.json';