├── amplify
├── backend
│ ├── storage
│ │ └── S3chopperthao
│ │ │ ├── storage-params.json
│ │ │ ├── parameters.json
│ │ │ └── s3-cloudformation-template.json
│ ├── tags.json
│ ├── backend-config.json
│ ├── analytics
│ │ └── cloudchopper
│ │ │ ├── parameters.json
│ │ │ └── pinpoint-cloudformation-template.json
│ ├── auth
│ │ └── cloudchopperd20aa567
│ │ │ ├── parameters.json
│ │ │ └── cloudchopperd20aa567-cloudformation-template.yml
│ ├── amplify-meta.json
│ └── awscloudformation
│ │ ├── build
│ │ ├── auth
│ │ │ └── cloudchopperd20aa567
│ │ │ │ └── cloudchopperd20aa567-cloudformation-template.yml
│ │ └── awscloudformation
│ │ │ └── nested-cloudformation-stack.yml
│ │ └── nested-cloudformation-stack.yml
├── #current-cloud-backend
│ ├── storage
│ │ └── S3chopperthao
│ │ │ ├── storage-params.json
│ │ │ ├── parameters.json
│ │ │ └── s3-cloudformation-template.json
│ ├── tags.json
│ ├── backend-config.json
│ ├── analytics
│ │ └── cloudchopper
│ │ │ └── parameters.json
│ ├── auth
│ │ └── cloudchopperd20aa567
│ │ │ ├── parameters.json
│ │ │ └── cloudchopperd20aa567-cloudformation-template.yml
│ └── amplify-meta.json
├── .config
│ ├── local-env-info.json
│ ├── local-aws-info.json
│ └── project-config.json
├── README.md
├── cli.json
└── team-provider-info.json
├── ios
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── .gitignore
└── Podfile
├── images
└── image.png
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ └── values
│ │ │ │ │ └── styles.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── sample_app
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
└── build.gradle
├── .metadata
├── .vscode
└── settings.json
├── .gitignore
├── lib
├── Pages
│ ├── LoadingPage.dart
│ ├── MainPage.dart
│ └── LandingPage.dart
├── Views
│ ├── ImageLineItem.dart
│ ├── ErrorView.dart
│ ├── ImageUploader.dart
│ ├── ImagePreview.dart
│ ├── UserView.dart
│ ├── SignInView.dart
│ └── SignUpView.dart
├── main.dart
└── amplifyconfiguration.dart
├── test
└── widget_test.dart
├── README.md
├── pubspec.yaml
└── pubspec.lock
/amplify/backend/storage/S3chopperthao/storage-params.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/storage/S3chopperthao/storage-params.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/images/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/images/image.png
--------------------------------------------------------------------------------
/amplify/.config/local-env-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectPath": "/media/lambiengcode/src/flutter/project/example",
3 | "envName": "dev"
4 | }
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/amplify/.config/local-aws-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "dev": {
3 | "configLevel": "project",
4 | "useProfile": false,
5 | "awsConfigFilePath": "/root/.amplify/awscloudformation/wsmwEeEQlL"
6 | }
7 | }
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/amplify/backend/tags.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Key": "user:Stack",
4 | "Value": "{project-env}"
5 | },
6 | {
7 | "Key": "user:Application",
8 | "Value": "{project-name}"
9 | }
10 | ]
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lambiengcode/flutter_cloud_storage/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/tags.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Key": "user:Stack",
4 | "Value": "{project-env}"
5 | },
6 | {
7 | "Key": "user:Application",
8 | "Value": "{project-name}"
9 | }
10 | ]
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "cloudchopper",
3 | "version": "3.1",
4 | "frontend": "flutter",
5 | "flutter": {
6 | "config": {
7 | "ResDir": "./lib/"
8 | }
9 | },
10 | "providers": [
11 | "awscloudformation"
12 | ]
13 | }
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8fe7655ed20ffd1395f68e30539a847a01a30351
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "amplify/.config": true,
4 | "amplify/**/*-parameters.json": true,
5 | "amplify/**/amplify.state": true,
6 | "amplify/**/transform.conf.json": true,
7 | "amplify/#current-cloud-backend": true,
8 | "amplify/backend/amplify-meta.json": true,
9 | "amplify/backend/awscloudformation": true
10 | }
11 | }
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/amplify/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Amplify CLI
2 | This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli).
3 |
4 | Helpful resources:
5 | - Amplify documentation: https://docs.amplify.aws
6 | - Amplify CLI documentation: https://docs.amplify.aws/cli
7 | - More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files
8 | - Join Amplify's community: https://amplify.aws/community/
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/amplify/backend/backend-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "auth": {
3 | "cloudchopperd20aa567": {
4 | "service": "Cognito",
5 | "providerPlugin": "awscloudformation",
6 | "dependsOn": [],
7 | "customAuth": false
8 | }
9 | },
10 | "storage": {
11 | "S3chopperthao": {
12 | "service": "S3",
13 | "providerPlugin": "awscloudformation"
14 | }
15 | },
16 | "analytics": {
17 | "cloudchopper": {
18 | "service": "Pinpoint",
19 | "providerPlugin": "awscloudformation"
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/backend-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "auth": {
3 | "cloudchopperd20aa567": {
4 | "service": "Cognito",
5 | "providerPlugin": "awscloudformation",
6 | "dependsOn": [],
7 | "customAuth": false
8 | }
9 | },
10 | "storage": {
11 | "S3chopperthao": {
12 | "service": "S3",
13 | "providerPlugin": "awscloudformation"
14 | }
15 | },
16 | "analytics": {
17 | "cloudchopper": {
18 | "service": "Pinpoint",
19 | "providerPlugin": "awscloudformation"
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | include ':app'
6 |
7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
8 | def properties = new Properties()
9 |
10 | assert localPropertiesFile.exists()
11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
12 |
13 | def flutterSdkPath = properties.getProperty("flutter.sdk")
14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
16 |
--------------------------------------------------------------------------------
/amplify/backend/analytics/cloudchopper/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": "cloudchopper",
3 | "roleName": "pinpointLambdaRoleaaf79265",
4 | "cloudformationPolicyName": "cloudformationPolicyaaf79265",
5 | "cloudWatchPolicyName": "cloudWatchPolicyaaf79265",
6 | "pinpointPolicyName": "pinpointPolicyaaf79265",
7 | "authPolicyName": "pinpoint_amplify_aaf79265",
8 | "unauthPolicyName": "pinpoint_amplify_aaf79265",
9 | "authRoleName": {
10 | "Ref": "AuthRoleName"
11 | },
12 | "unauthRoleName": {
13 | "Ref": "UnauthRoleName"
14 | },
15 | "authRoleArn": {
16 | "Fn::GetAtt": [
17 | "AuthRole",
18 | "Arn"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/analytics/cloudchopper/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": "cloudchopper",
3 | "roleName": "pinpointLambdaRoleaaf79265",
4 | "cloudformationPolicyName": "cloudformationPolicyaaf79265",
5 | "cloudWatchPolicyName": "cloudWatchPolicyaaf79265",
6 | "pinpointPolicyName": "pinpointPolicyaaf79265",
7 | "authPolicyName": "pinpoint_amplify_aaf79265",
8 | "unauthPolicyName": "pinpoint_amplify_aaf79265",
9 | "authRoleName": {
10 | "Ref": "AuthRoleName"
11 | },
12 | "unauthRoleName": {
13 | "Ref": "UnauthRoleName"
14 | },
15 | "authRoleArn": {
16 | "Fn::GetAtt": [
17 | "AuthRole",
18 | "Arn"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/sample_app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | package com.example.sample_app
17 |
18 | import io.flutter.embedding.android.FlutterActivity
19 |
20 | class MainActivity: FlutterActivity() {
21 | }
22 |
--------------------------------------------------------------------------------
/amplify/cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "features": {
3 | "graphqltransformer": {
4 | "addmissingownerfields": true,
5 | "validatetypenamereservedwords": true,
6 | "useexperimentalpipelinedtransformer": false,
7 | "enableiterativegsiupdates": true,
8 | "secondarykeyasgsi": true,
9 | "skipoverridemutationinputtypes": true
10 | },
11 | "frontend-ios": {
12 | "enablexcodeintegration": true
13 | },
14 | "auth": {
15 | "enablecaseinsensitivity": true,
16 | "useinclusiveterminology": true
17 | },
18 | "codegen": {
19 | "useappsyncmodelgenplugin": true,
20 | "usedocsgeneratorplugin": true,
21 | "usetypesgeneratorplugin": true,
22 | "cleangeneratedmodelsdirectory": true,
23 | "retaincasestyle": true
24 | },
25 | "appsync": {
26 | "generategraphqlpermissions": true
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Exceptions to above rules.
44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
--------------------------------------------------------------------------------
/amplify/team-provider-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "dev": {
3 | "awscloudformation": {
4 | "AuthRoleName": "amplify-cloudchopper-dev-204628-authRole",
5 | "UnauthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-unauthRole",
6 | "AuthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-authRole",
7 | "Region": "ap-southeast-1",
8 | "DeploymentBucketName": "amplify-cloudchopper-dev-204628-deployment",
9 | "UnauthRoleName": "amplify-cloudchopper-dev-204628-unauthRole",
10 | "StackName": "amplify-cloudchopper-dev-204628",
11 | "StackId": "arn:aws:cloudformation:ap-southeast-1:198101249191:stack/amplify-cloudchopper-dev-204628/4ba97a60-bbcd-11eb-b0c7-02ab63576a78",
12 | "AmplifyAppId": "d9myyhl3m04b9"
13 | },
14 | "categories": {
15 | "auth": {
16 | "cloudchopperd20aa567": {}
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/lib/Pages/LoadingPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import 'package:flutter/cupertino.dart';
17 | import 'package:flutter/material.dart';
18 |
19 | class LoadingPage extends StatelessWidget {
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: AppBar(title: Text("Landing Page")),
24 | body:
25 | Center(child: Text("Please Wait. Configuring Amplify Flutter SDK")),
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/Views/ImageLineItem.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'ImagePreview.dart';
4 |
5 | class ImageLineItem extends StatelessWidget {
6 | final String storageKey;
7 |
8 | const ImageLineItem({
9 | Key key,
10 | this.storageKey,
11 | }) : super(key: key);
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Padding(
16 | padding: EdgeInsets.all(5.0),
17 | child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
18 | Text(storageKey),
19 | Spacer(),
20 | ElevatedButton(
21 | child: const Text("open"),
22 | onPressed: () => {
23 | showDialog(
24 | context: context,
25 | builder: (BuildContext context) {
26 | return new SimpleDialog(
27 | title: Text(storageKey),
28 | children: [ImagePreview(storageKey: storageKey)]);
29 | })
30 | })
31 | ]));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:sample_app/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/lib/Views/ErrorView.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import 'package:flutter/material.dart';
17 |
18 | class ErrorView extends StatelessWidget {
19 | final String error;
20 |
21 | ErrorView(this.error);
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | if (error.isNotEmpty) {
26 | return Column(children: [
27 | Text('Error: $error',
28 | textAlign: TextAlign.center,
29 | overflow: TextOverflow.visible,
30 | style: TextStyle(fontWeight: FontWeight.bold)),
31 | ]);
32 | } else {
33 | return Container();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/Views/ImageUploader.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:io';
3 | import 'package:file_picker/file_picker.dart';
4 | import 'package:amplify_flutter/amplify.dart';
5 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
6 |
7 | class ImageUploader extends StatelessWidget {
8 | void _upload(BuildContext context) async {
9 | try {
10 | print('In upload');
11 | // Uploading the file with options
12 | File local = await FilePicker.getFile(type: FileType.image);
13 | local.existsSync();
14 | final key = new DateTime.now().toString();
15 | Map metadata = {};
16 | metadata['name'] = 'filename';
17 | metadata['desc'] = 'A test file';
18 | S3UploadFileOptions options = S3UploadFileOptions(
19 | accessLevel: StorageAccessLevel.guest, metadata: metadata);
20 | UploadFileResult result = await Amplify.Storage.uploadFile(
21 | key: key, local: local, options: options);
22 |
23 | print('File uploaded. Key: ' + result.key);
24 | Navigator.pop(context, result.key);
25 | } catch (e) {
26 | print('UploadFile Err: ' + e.toString());
27 | }
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Column(children: [
33 | ElevatedButton(
34 | child: const Text("Upload Image"),
35 | onPressed: () {
36 | _upload(context);
37 | },
38 | )
39 | ]);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/amplify/backend/storage/S3chopperthao/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "bucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414",
3 | "authPolicyName": "s3_amplify_899f92fa",
4 | "unauthPolicyName": "s3_amplify_899f92fa",
5 | "authRoleName": {
6 | "Ref": "AuthRoleName"
7 | },
8 | "unauthRoleName": {
9 | "Ref": "UnauthRoleName"
10 | },
11 | "selectedGuestPermissions": [
12 | "s3:PutObject",
13 | "s3:GetObject",
14 | "s3:ListBucket",
15 | "s3:DeleteObject"
16 | ],
17 | "selectedAuthenticatedPermissions": [
18 | "s3:PutObject",
19 | "s3:GetObject",
20 | "s3:ListBucket",
21 | "s3:DeleteObject"
22 | ],
23 | "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
24 | "s3PublicPolicy": "Public_policy_7d6cabc6",
25 | "s3PermissionsAuthenticatedUploads": "s3:PutObject",
26 | "s3UploadsPolicy": "Uploads_policy_7d6cabc6",
27 | "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
28 | "s3ProtectedPolicy": "Protected_policy_5e148ded",
29 | "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
30 | "s3PrivatePolicy": "Private_policy_5e148ded",
31 | "AuthenticatedAllowList": "ALLOW",
32 | "s3ReadPolicy": "read_policy_7d6cabc6",
33 | "s3PermissionsGuestPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
34 | "s3PermissionsGuestUploads": "s3:PutObject",
35 | "GuestAllowList": "ALLOW",
36 | "triggerFunction": "NONE"
37 | }
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/storage/S3chopperthao/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "bucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414",
3 | "authPolicyName": "s3_amplify_899f92fa",
4 | "unauthPolicyName": "s3_amplify_899f92fa",
5 | "authRoleName": {
6 | "Ref": "AuthRoleName"
7 | },
8 | "unauthRoleName": {
9 | "Ref": "UnauthRoleName"
10 | },
11 | "selectedGuestPermissions": [
12 | "s3:PutObject",
13 | "s3:GetObject",
14 | "s3:ListBucket",
15 | "s3:DeleteObject"
16 | ],
17 | "selectedAuthenticatedPermissions": [
18 | "s3:PutObject",
19 | "s3:GetObject",
20 | "s3:ListBucket",
21 | "s3:DeleteObject"
22 | ],
23 | "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
24 | "s3PublicPolicy": "Public_policy_7d6cabc6",
25 | "s3PermissionsAuthenticatedUploads": "s3:PutObject",
26 | "s3UploadsPolicy": "Uploads_policy_7d6cabc6",
27 | "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
28 | "s3ProtectedPolicy": "Protected_policy_5e148ded",
29 | "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
30 | "s3PrivatePolicy": "Private_policy_5e148ded",
31 | "AuthenticatedAllowList": "ALLOW",
32 | "s3ReadPolicy": "read_policy_7d6cabc6",
33 | "s3PermissionsGuestPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
34 | "s3PermissionsGuestUploads": "s3:PutObject",
35 | "GuestAllowList": "ALLOW",
36 | "triggerFunction": "NONE"
37 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Amplify Flutter Example
2 |
3 | Sample flutter app for getting started with the Amplify Flutter Library. This example uses the Auth, Analytics, and Storage components of the Flutter library.
4 |
5 | Please check out our docs here:
6 | https://docs.amplify.aws/start/q/integration/flutter
7 |
8 | ## Getting Started
9 |
10 | **IMPORTANT**
11 |
12 | **The app will not compile until you use the Amplify CLI to configure AWS resources necessary for running this app, or create your own amplifyconfiguration.dart file using the example in our documentation'.**
13 |
14 | This is because it does not contain an `amplifyconfiguration.dart` file necessary for connecting with AWS services.
15 |
16 | You will need to use Amplify CLI to init the app and configure Analytics, Auth, and Storage. Please follow the instructions here:
17 |
18 | https://docs.amplify.aws/start/getting-started/add-api/q/integration/flutter#setup-aws-cloud-resources-with-amplify-cli
19 |
20 | For this example app you will also need to call `amplify add auth`, and `amplify add storage` with the Amplify CLI and call `amplify push` again.
21 |
22 | Running these steps will generate the `amplifyconfiguration.dart` file within the `lib` folder.
23 |
24 | ## Important Notes
25 |
26 | This is a very basic app that interacts with AWS resources. We did not implement UI showing that the app is "loading" or "uploading" something from AWS. Some operations like logging in or uploading an image can take some time.
27 |
28 | Please note when signing up that you MUST provide a country code for a new user's phone number. For example, if your number is American, you will need to append +1 to the beginning.
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | sample_app
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/lib/Views/ImagePreview.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
2 | import 'package:amplify_flutter/amplify.dart';
3 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | class ImagePreview extends StatefulWidget {
7 | final String storageKey;
8 |
9 | ImagePreview({Key key, this.storageKey}) : super(key: key);
10 |
11 | @override
12 | _ImagePreviewState createState() => _ImagePreviewState();
13 | }
14 |
15 | class _ImagePreviewState extends State {
16 | String _imageURL = '';
17 |
18 | @override
19 | void initState() {
20 | super.initState();
21 | _getUrl(widget.storageKey);
22 | }
23 |
24 | void _getUrl(String storageKey) async {
25 | try {
26 | print('In getUrl');
27 | String key = storageKey;
28 | S3GetUrlOptions options = S3GetUrlOptions(
29 | accessLevel: StorageAccessLevel.guest, expires: 10000);
30 | GetUrlResult result =
31 | await Amplify.Storage.getUrl(key: key, options: options);
32 |
33 | setState(() {
34 | _imageURL = result.url;
35 | });
36 |
37 | print('URL: ' + _imageURL);
38 | AnalyticsEvent event = AnalyticsEvent("image_url_retrieved");
39 | event.properties.addStringProperty("file_key", storageKey);
40 | Amplify.Analytics.recordEvent(event: event);
41 | } catch (e) {
42 | print('GetUrl Err: ' + e.toString());
43 | }
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | return Column(children: [
49 | //Image(image: AssetImage('images/image.png')),
50 | Center(child: Image.network(_imageURL))
51 | ]);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/Views/UserView.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
17 | import 'package:amplify_flutter/amplify.dart';
18 | import 'package:flutter/material.dart';
19 | import 'package:sample_app/Pages/LandingPage.dart';
20 |
21 | class UserView extends StatefulWidget {
22 | @override
23 | _UserProfileState createState() => _UserProfileState();
24 | }
25 |
26 | class _UserProfileState extends State {
27 | @override
28 | void initState() {
29 | super.initState();
30 | }
31 |
32 | void _signOut() async {
33 | try {
34 | SignOutResult res = await Amplify.Auth.signOut();
35 |
36 | Navigator.pushAndRemoveUntil(
37 | context,
38 | MaterialPageRoute(builder: (context) => LandingPage()),
39 | (route) => false);
40 | } on AuthException catch (e) {
41 | print(e);
42 | }
43 | }
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return Row(
48 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
49 | children: [
50 | ElevatedButton(onPressed: _signOut, child: const Text("Log Out")),
51 | ],
52 | );
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/amplify/backend/auth/cloudchopperd20aa567/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "identityPoolName": "cloudchopperd20aa567_identitypool_d20aa567",
3 | "allowUnauthenticatedIdentities": true,
4 | "resourceNameTruncated": "cloudcd20aa567",
5 | "userPoolName": "cloudchopperd20aa567_userpool_d20aa567",
6 | "autoVerifiedAttributes": [
7 | "email"
8 | ],
9 | "mfaConfiguration": "OFF",
10 | "mfaTypes": [
11 | "SMS Text Message"
12 | ],
13 | "smsAuthenticationMessage": "Your authentication code is {####}",
14 | "smsVerificationMessage": "Your verification code is {####}",
15 | "emailVerificationSubject": "Your verification code",
16 | "emailVerificationMessage": "Your verification code is {####}",
17 | "defaultPasswordPolicy": false,
18 | "passwordPolicyMinLength": 8,
19 | "passwordPolicyCharacters": [],
20 | "requiredAttributes": [
21 | "email"
22 | ],
23 | "userpoolClientGenerateSecret": false,
24 | "userpoolClientRefreshTokenValidity": 30,
25 | "userpoolClientWriteAttributes": [
26 | "email"
27 | ],
28 | "userpoolClientReadAttributes": [
29 | "email"
30 | ],
31 | "userpoolClientLambdaRole": "cloudcd20aa567_userpoolclient_lambda_role",
32 | "userpoolClientSetAttributes": false,
33 | "sharedId": "d20aa567",
34 | "resourceName": "cloudchopperd20aa567",
35 | "authSelections": "identityPoolAndUserPool",
36 | "authRoleArn": {
37 | "Fn::GetAtt": [
38 | "AuthRole",
39 | "Arn"
40 | ]
41 | },
42 | "unauthRoleArn": {
43 | "Fn::GetAtt": [
44 | "UnauthRole",
45 | "Arn"
46 | ]
47 | },
48 | "useDefault": "default",
49 | "userPoolGroupList": [],
50 | "serviceName": "Cognito",
51 | "usernameCaseSensitive": false,
52 | "dependsOn": []
53 | }
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/auth/cloudchopperd20aa567/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "identityPoolName": "cloudchopperd20aa567_identitypool_d20aa567",
3 | "allowUnauthenticatedIdentities": true,
4 | "resourceNameTruncated": "cloudcd20aa567",
5 | "userPoolName": "cloudchopperd20aa567_userpool_d20aa567",
6 | "autoVerifiedAttributes": [
7 | "email"
8 | ],
9 | "mfaConfiguration": "OFF",
10 | "mfaTypes": [
11 | "SMS Text Message"
12 | ],
13 | "smsAuthenticationMessage": "Your authentication code is {####}",
14 | "smsVerificationMessage": "Your verification code is {####}",
15 | "emailVerificationSubject": "Your verification code",
16 | "emailVerificationMessage": "Your verification code is {####}",
17 | "defaultPasswordPolicy": false,
18 | "passwordPolicyMinLength": 8,
19 | "passwordPolicyCharacters": [],
20 | "requiredAttributes": [
21 | "email"
22 | ],
23 | "userpoolClientGenerateSecret": false,
24 | "userpoolClientRefreshTokenValidity": 30,
25 | "userpoolClientWriteAttributes": [
26 | "email"
27 | ],
28 | "userpoolClientReadAttributes": [
29 | "email"
30 | ],
31 | "userpoolClientLambdaRole": "cloudcd20aa567_userpoolclient_lambda_role",
32 | "userpoolClientSetAttributes": false,
33 | "sharedId": "d20aa567",
34 | "resourceName": "cloudchopperd20aa567",
35 | "authSelections": "identityPoolAndUserPool",
36 | "authRoleArn": {
37 | "Fn::GetAtt": [
38 | "AuthRole",
39 | "Arn"
40 | ]
41 | },
42 | "unauthRoleArn": {
43 | "Fn::GetAtt": [
44 | "UnauthRole",
45 | "Arn"
46 | ]
47 | },
48 | "useDefault": "default",
49 | "userPoolGroupList": [],
50 | "serviceName": "Cognito",
51 | "usernameCaseSensitive": false,
52 | "dependsOn": []
53 | }
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
2 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
3 | import 'package:amplify_flutter/amplify.dart';
4 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:sample_app/Pages/LoadingPage.dart';
7 | import 'Pages/LandingPage.dart';
8 | import 'amplifyconfiguration.dart';
9 |
10 | void main() {
11 | runApp(MyApp());
12 | }
13 |
14 | class MyApp extends StatefulWidget {
15 | @override
16 | State createState() => _MyAppState();
17 | }
18 |
19 | class _MyAppState extends State {
20 | bool _isAmplifyConfigured = false;
21 |
22 | @override
23 | initState() {
24 | super.initState();
25 | _initAmplifyFlutter();
26 | }
27 |
28 | void _initAmplifyFlutter() async {
29 | AmplifyAuthCognito auth = AmplifyAuthCognito();
30 | AmplifyStorageS3 storage = AmplifyStorageS3();
31 | AmplifyAnalyticsPinpoint analyticsPinpoint = AmplifyAnalyticsPinpoint();
32 |
33 | Amplify.addPlugins([auth, storage, analyticsPinpoint]);
34 |
35 | // Initialize AmplifyFlutter
36 | try {
37 | await Amplify.configure(amplifyconfig);
38 | } on AmplifyAlreadyConfiguredException {
39 | print(
40 | "Amplify was already configured. Looks like app restarted on android.");
41 | }
42 |
43 | setState(() {
44 | _isAmplifyConfigured = true;
45 | });
46 | }
47 |
48 | Widget _display() {
49 | if (_isAmplifyConfigured) {
50 | return LandingPage();
51 | } else {
52 | return LoadingPage();
53 | }
54 | }
55 |
56 | @override
57 | Widget build(BuildContext context) {
58 | return MaterialApp(
59 | title: 'Flutter Amplify App',
60 | theme: ThemeData(
61 | primarySwatch: Colors.blue,
62 | visualDensity: VisualDensity.adaptivePlatformDensity,
63 | ),
64 | home: _display(),
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 30
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.sample_app"
42 | minSdkVersion 21
43 | targetSdkVersion 30
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
--------------------------------------------------------------------------------
/lib/Pages/MainPage.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_flutter/amplify.dart';
2 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:sample_app/Views/ImageLineItem.dart';
5 | import 'package:sample_app/Views/ImageUploader.dart';
6 | import 'package:sample_app/Views/UserView.dart';
7 |
8 | class MainPage extends StatefulWidget {
9 | @override
10 | _MainPageState createState() => _MainPageState();
11 | }
12 |
13 | class _MainPageState extends State {
14 | List itemKeys = [];
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | _loadImages();
20 | }
21 |
22 | void _loadImages() async {
23 | try {
24 | print('In list');
25 | S3ListOptions options =
26 | S3ListOptions(accessLevel: StorageAccessLevel.guest);
27 | ListResult result = await Amplify.Storage.list(options: options);
28 |
29 | var newList = itemKeys.toList();
30 | for (StorageItem item in result.items) {
31 | newList.add(item.key);
32 | }
33 |
34 | setState(() {
35 | itemKeys = newList;
36 | });
37 | } catch (e) {
38 | print('List Err: ' + e.toString());
39 | }
40 | }
41 |
42 | void _showImageUploader() async {
43 | String key = await showDialog(
44 | context: context,
45 | builder: (BuildContext context) {
46 | return new SimpleDialog(
47 | title: Text("Upload Image"), children: [ImageUploader()]);
48 | });
49 |
50 | if (key.isNotEmpty) {
51 | var newList = itemKeys.toList();
52 | newList.add(key);
53 |
54 | setState(() {
55 | itemKeys = newList;
56 | });
57 | }
58 | }
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | return Scaffold(
63 | appBar: AppBar(
64 | title: Row(
65 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
66 | children: [Text("Main Page"), UserView()])),
67 | body: ListView.builder(
68 | itemCount: itemKeys.length,
69 | itemBuilder: (context, index) {
70 | return ImageLineItem(storageKey: itemKeys[index]);
71 | }),
72 | floatingActionButton: FloatingActionButton(
73 | onPressed: () {
74 | _showImageUploader();
75 | },
76 | tooltip: 'Increment',
77 | child: Icon(Icons.add),
78 | ),
79 | );
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/lib/Pages/LandingPage.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import 'package:flutter/material.dart';
17 |
18 | import '../Views/SignInView.dart';
19 | import '../Views/SignUpView.dart';
20 | import 'MainPage.dart';
21 |
22 | class LandingPage extends StatefulWidget {
23 | LandingPage({Key key}) : super(key: key);
24 |
25 | @override
26 | _LandingPageState createState() => _LandingPageState();
27 | }
28 |
29 | class _LandingPageState extends State {
30 | Future _showDialogForResult(
31 | String text, Function onSuccess, Widget dialogWidget) async {
32 | bool result = await showDialog(
33 | context: context,
34 | builder: (BuildContext context) {
35 | return new SimpleDialog(title: Text(text), children: [
36 | dialogWidget,
37 | ElevatedButton(
38 | child: const Text("Cancel"),
39 | onPressed: () {
40 | Navigator.pop(context, false);
41 | },
42 | ),
43 | ]);
44 | });
45 |
46 | if (result) onSuccess();
47 | }
48 |
49 | // dialogWidget must return true or false
50 | Widget openDialogButton(
51 | String text, Function onSuccess, Widget dialogWidget) {
52 | return ElevatedButton(
53 | child: Text(text),
54 | onPressed: () {
55 | _showDialogForResult(text, onSuccess, dialogWidget);
56 | });
57 | }
58 |
59 | void onSignInSuccess() {
60 | Navigator.pushAndRemoveUntil(context,
61 | MaterialPageRoute(builder: (context) => MainPage()), (route) => false);
62 | }
63 |
64 | @override
65 | Widget build(BuildContext context) {
66 | return Scaffold(
67 | appBar: AppBar(
68 | title: Text("Landing Page"),
69 | ),
70 | body: Center(
71 | child: Row(
72 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
73 | children: [
74 | openDialogButton("Sign In", onSignInSuccess, SignInView()),
75 | openDialogButton(
76 | "Sign Up", () => {print("sign up success")}, SignUpView())
77 | ],
78 | )));
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
23 |
27 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/lib/amplifyconfiguration.dart:
--------------------------------------------------------------------------------
1 | const amplifyconfig = ''' {
2 | "UserAgent": "aws-amplify-cli/2.0",
3 | "Version": "1.0",
4 | "auth": {
5 | "plugins": {
6 | "awsCognitoAuthPlugin": {
7 | "UserAgent": "aws-amplify-cli/0.1.0",
8 | "Version": "0.1.0",
9 | "IdentityManager": {
10 | "Default": {}
11 | },
12 | "CredentialsProvider": {
13 | "CognitoIdentity": {
14 | "Default": {
15 | "PoolId": "ap-southeast-1:08efc3f6-bb71-4d8f-9ada-8b38f9c77691",
16 | "Region": "ap-southeast-1"
17 | }
18 | }
19 | },
20 | "CognitoUserPool": {
21 | "Default": {
22 | "PoolId": "ap-southeast-1_9WxFEXgEx",
23 | "AppClientId": "1a8dod847cqa2m5pas3v6c8n5u",
24 | "Region": "ap-southeast-1"
25 | }
26 | },
27 | "Auth": {
28 | "Default": {
29 | "authenticationFlowType": "USER_SRP_AUTH"
30 | }
31 | },
32 | "S3TransferUtility": {
33 | "Default": {
34 | "Bucket": "cloudchopper5de8d1549c594acca63ed06abae2d414204628-dev",
35 | "Region": "ap-southeast-1"
36 | }
37 | },
38 | "PinpointAnalytics": {
39 | "Default": {
40 | "AppId": "269495fe54cb40d8ba1d0a393776a11c",
41 | "Region": "us-west-2"
42 | }
43 | },
44 | "PinpointTargeting": {
45 | "Default": {
46 | "Region": "us-west-2"
47 | }
48 | }
49 | }
50 | }
51 | },
52 | "storage": {
53 | "plugins": {
54 | "awsS3StoragePlugin": {
55 | "bucket": "cloudchopper5de8d1549c594acca63ed06abae2d414204628-dev",
56 | "region": "ap-southeast-1",
57 | "defaultAccessLevel": "guest"
58 | }
59 | }
60 | },
61 | "analytics": {
62 | "plugins": {
63 | "awsPinpointAnalyticsPlugin": {
64 | "pinpointAnalytics": {
65 | "appId": "269495fe54cb40d8ba1d0a393776a11c",
66 | "region": "us-west-2"
67 | },
68 | "pinpointTargeting": {
69 | "region": "us-west-2"
70 | }
71 | }
72 | }
73 | }
74 | }''';
--------------------------------------------------------------------------------
/amplify/backend/amplify-meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": {
3 | "awscloudformation": {
4 | "AuthRoleName": "amplify-cloudchopper-dev-204628-authRole",
5 | "UnauthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-unauthRole",
6 | "AuthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-authRole",
7 | "Region": "ap-southeast-1",
8 | "DeploymentBucketName": "amplify-cloudchopper-dev-204628-deployment",
9 | "UnauthRoleName": "amplify-cloudchopper-dev-204628-unauthRole",
10 | "StackName": "amplify-cloudchopper-dev-204628",
11 | "StackId": "arn:aws:cloudformation:ap-southeast-1:198101249191:stack/amplify-cloudchopper-dev-204628/4ba97a60-bbcd-11eb-b0c7-02ab63576a78",
12 | "AmplifyAppId": "d9myyhl3m04b9"
13 | }
14 | },
15 | "auth": {
16 | "cloudchopperd20aa567": {
17 | "service": "Cognito",
18 | "providerPlugin": "awscloudformation",
19 | "dependsOn": [],
20 | "customAuth": false,
21 | "providerMetadata": {
22 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/auth/cloudchopperd20aa567-cloudformation-template.yml",
23 | "logicalId": "authcloudchopperd20aa567"
24 | },
25 | "lastPushTimeStamp": "2021-05-23T14:06:24.114Z",
26 | "output": {
27 | "UserPoolId": "ap-southeast-1_9WxFEXgEx",
28 | "AppClientIDWeb": "7nmsq7nfs8rfcuijt4arnsph4v",
29 | "AppClientID": "1a8dod847cqa2m5pas3v6c8n5u",
30 | "IdentityPoolId": "ap-southeast-1:08efc3f6-bb71-4d8f-9ada-8b38f9c77691",
31 | "IdentityPoolName": "cloudchopperd20aa567_identitypool_d20aa567__dev",
32 | "UserPoolName": "cloudchopperd20aa567_userpool_d20aa567"
33 | },
34 | "lastPushDirHash": "p1D6cyya+gsMcV8MMLL7VL7ggvo="
35 | }
36 | },
37 | "storage": {
38 | "S3chopperthao": {
39 | "service": "S3",
40 | "providerPlugin": "awscloudformation",
41 | "providerMetadata": {
42 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/storage/s3-cloudformation-template.json",
43 | "logicalId": "storageS3chopperthao"
44 | },
45 | "lastPushTimeStamp": "2021-05-23T14:06:24.405Z",
46 | "output": {
47 | "BucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414204628-dev",
48 | "Region": "ap-southeast-1"
49 | },
50 | "lastPushDirHash": "1cDWKe4EN1u8vfYiXo/C/ogNixg="
51 | }
52 | },
53 | "analytics": {
54 | "cloudchopper": {
55 | "service": "Pinpoint",
56 | "providerPlugin": "awscloudformation",
57 | "providerMetadata": {
58 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/analytics/pinpoint-cloudformation-template.json",
59 | "logicalId": "analyticscloudchopper"
60 | },
61 | "lastPushTimeStamp": "2021-05-23T14:06:24.412Z",
62 | "output": {
63 | "appName": "cloudchopper-dev",
64 | "Region": "us-west-2",
65 | "Id": "269495fe54cb40d8ba1d0a393776a11c"
66 | },
67 | "lastPushDirHash": "A5pBxCVNfOAGje8cV6s3MGuLm1M="
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/amplify-meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": {
3 | "awscloudformation": {
4 | "AuthRoleName": "amplify-cloudchopper-dev-204628-authRole",
5 | "UnauthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-unauthRole",
6 | "AuthRoleArn": "arn:aws:iam::198101249191:role/amplify-cloudchopper-dev-204628-authRole",
7 | "Region": "ap-southeast-1",
8 | "DeploymentBucketName": "amplify-cloudchopper-dev-204628-deployment",
9 | "UnauthRoleName": "amplify-cloudchopper-dev-204628-unauthRole",
10 | "StackName": "amplify-cloudchopper-dev-204628",
11 | "StackId": "arn:aws:cloudformation:ap-southeast-1:198101249191:stack/amplify-cloudchopper-dev-204628/4ba97a60-bbcd-11eb-b0c7-02ab63576a78",
12 | "AmplifyAppId": "d9myyhl3m04b9"
13 | }
14 | },
15 | "auth": {
16 | "cloudchopperd20aa567": {
17 | "service": "Cognito",
18 | "providerPlugin": "awscloudformation",
19 | "dependsOn": [],
20 | "customAuth": false,
21 | "providerMetadata": {
22 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/auth/cloudchopperd20aa567-cloudformation-template.yml",
23 | "logicalId": "authcloudchopperd20aa567"
24 | },
25 | "lastPushTimeStamp": "2021-05-23T14:06:24.114Z",
26 | "output": {
27 | "UserPoolId": "ap-southeast-1_9WxFEXgEx",
28 | "AppClientIDWeb": "7nmsq7nfs8rfcuijt4arnsph4v",
29 | "AppClientID": "1a8dod847cqa2m5pas3v6c8n5u",
30 | "IdentityPoolId": "ap-southeast-1:08efc3f6-bb71-4d8f-9ada-8b38f9c77691",
31 | "IdentityPoolName": "cloudchopperd20aa567_identitypool_d20aa567__dev",
32 | "UserPoolName": "cloudchopperd20aa567_userpool_d20aa567"
33 | },
34 | "lastPushDirHash": "p1D6cyya+gsMcV8MMLL7VL7ggvo="
35 | }
36 | },
37 | "storage": {
38 | "S3chopperthao": {
39 | "service": "S3",
40 | "providerPlugin": "awscloudformation",
41 | "providerMetadata": {
42 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/storage/s3-cloudformation-template.json",
43 | "logicalId": "storageS3chopperthao"
44 | },
45 | "lastPushTimeStamp": "2021-05-23T14:06:24.405Z",
46 | "output": {
47 | "BucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414204628-dev",
48 | "Region": "ap-southeast-1"
49 | },
50 | "lastPushDirHash": "1cDWKe4EN1u8vfYiXo/C/ogNixg="
51 | }
52 | },
53 | "analytics": {
54 | "cloudchopper": {
55 | "service": "Pinpoint",
56 | "providerPlugin": "awscloudformation",
57 | "providerMetadata": {
58 | "s3TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/analytics/pinpoint-cloudformation-template.json",
59 | "logicalId": "analyticscloudchopper"
60 | },
61 | "lastPushTimeStamp": "2021-05-23T14:06:24.412Z",
62 | "output": {
63 | "appName": "cloudchopper-dev",
64 | "Region": "us-west-2",
65 | "Id": "269495fe54cb40d8ba1d0a393776a11c"
66 | },
67 | "lastPushDirHash": "A5pBxCVNfOAGje8cV6s3MGuLm1M="
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/lib/Views/SignInView.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
17 | import 'package:amplify_flutter/amplify.dart';
18 | import 'package:flutter/material.dart';
19 |
20 | import 'ErrorView.dart';
21 |
22 | class SignInView extends StatefulWidget {
23 | @override
24 | _SignInViewState createState() => _SignInViewState();
25 | }
26 |
27 | class _SignInViewState extends State {
28 | final usernameController = TextEditingController();
29 | final passwordController = TextEditingController();
30 |
31 | String _signUpError = "";
32 |
33 | @override
34 | void initState() {
35 | super.initState();
36 | }
37 |
38 | void _signIn() async {
39 | try {
40 | await Amplify.Auth.signOut();
41 | } on AuthException catch (e) {
42 | print(e);
43 | }
44 |
45 | try {
46 | SignInResult res = await Amplify.Auth.signIn(
47 | username: usernameController.text.trim(),
48 | password: passwordController.text.trim());
49 | Navigator.pop(context, true);
50 | } on AuthException catch (e) {
51 | setState(() {
52 | _signUpError = e.message;
53 | });
54 | }
55 | }
56 |
57 | @override
58 | Widget build(BuildContext context) {
59 | return Row(
60 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
61 | children: [
62 | Expanded(
63 | // wrap your Column in Expanded
64 | child: Padding(
65 | padding: EdgeInsets.all(10.0),
66 | child: Column(
67 | children: [
68 | TextFormField(
69 | controller: usernameController,
70 | decoration: const InputDecoration(
71 | icon: Icon(Icons.person),
72 | hintText: 'Enter your username',
73 | labelText: 'Username *',
74 | ),
75 | ),
76 | TextFormField(
77 | obscureText: true,
78 | controller: passwordController,
79 | decoration: const InputDecoration(
80 | icon: Icon(Icons.lock),
81 | hintText: 'Enter your password',
82 | labelText: 'Password *',
83 | ),
84 | ),
85 | const Padding(padding: EdgeInsets.all(10.0)),
86 | ElevatedButton(
87 | onPressed: _signIn,
88 | child: const Text('Sign In'),
89 | ),
90 | ErrorView(_signUpError)
91 | ],
92 | ),
93 | ),
94 | ),
95 | ],
96 | );
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: sample_app
2 | description: A new Flutter application.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.7.0 <3.0.0"
22 | flutter: ">=1.10.0"
23 |
24 | dependencies:
25 | flutter:
26 | sdk: flutter
27 | file_picker: ^1.8.0+1
28 | amplify_flutter: 0.1.4
29 | amplify_analytics_pinpoint: 0.1.4
30 | amplify_auth_cognito: 0.1.4
31 | amplify_storage_s3: 0.1.4
32 | # The following adds the Cupertino Icons font to your application.
33 | # Use with the CupertinoIcons class for iOS style icons.
34 | cupertino_icons: ^0.1.3
35 |
36 | dev_dependencies:
37 | flutter_test:
38 | sdk: flutter
39 |
40 | # For information on the generic Dart part of this file, see the
41 | # following page: https://dart.dev/tools/pub/pubspec
42 |
43 | # The following section is specific to Flutter.
44 | flutter:
45 | # The following line ensures that the Material Icons font is
46 | # included with your application, so that you can use the icons in
47 | # the material Icons class.
48 | uses-material-design: true
49 |
50 | # To add assets to your application, add an assets section, like this:
51 | assets:
52 | - images/image.png
53 | # - images/a_dot_ham.jpeg
54 |
55 | # An image asset can refer to one or more resolution-specific "variants", see
56 | # https://flutter.dev/assets-and-images/#resolution-aware.
57 |
58 | # For details regarding adding assets from package dependencies, see
59 | # https://flutter.dev/assets-and-images/#from-packages
60 |
61 | # To add custom fonts to your application, add a fonts section here,
62 | # in this "flutter" section. Each entry in this list should have a
63 | # "family" key with the font family name, and a "fonts" key with a
64 | # list giving the asset and other descriptors for the font. For
65 | # example:
66 | # fonts:
67 | # - family: Schyler
68 | # fonts:
69 | # - asset: fonts/Schyler-Regular.ttf
70 | # - asset: fonts/Schyler-Italic.ttf
71 | # style: italic
72 | # - family: Trajan Pro
73 | # fonts:
74 | # - asset: fonts/TrajanPro.ttf
75 | # - asset: fonts/TrajanPro_Bold.ttf
76 | # weight: 700
77 | #
78 | # For details regarding fonts from package dependencies,
79 | # see https://flutter.dev/custom-fonts/#from-packages
80 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | generated_key_values = {}
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) do |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | generated_key_values[podname] = podpath
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | end
32 | generated_key_values
33 | end
34 |
35 | target 'Runner' do
36 | use_frameworks!
37 | use_modular_headers!
38 |
39 | # Flutter Pod
40 |
41 | copied_flutter_dir = File.join(__dir__, 'Flutter')
42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
48 |
49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
50 | unless File.exist?(generated_xcode_build_settings_path)
51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
52 | end
53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
55 |
56 | unless File.exist?(copied_framework_path)
57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
58 | end
59 | unless File.exist?(copied_podspec_path)
60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
61 | end
62 | end
63 |
64 | # Keep pod path relative so it can be checked into Podfile.lock.
65 | pod 'Flutter', :path => 'Flutter'
66 |
67 | # Plugin Pods
68 |
69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
70 | # referring to absolute paths on developers' machines.
71 | system('rm -rf .symlinks')
72 | system('mkdir -p .symlinks/plugins')
73 | plugin_pods = parse_KV_file('../.flutter-plugins')
74 | plugin_pods.each do |name, path|
75 | symlink = File.join('.symlinks', 'plugins', name)
76 | File.symlink(path, symlink)
77 | pod name, :path => File.join(symlink, 'ios')
78 | end
79 | end
80 |
81 | post_install do |installer|
82 | installer.pods_project.targets.each do |target|
83 | target.build_configurations.each do |config|
84 | config.build_settings['ENABLE_BITCODE'] = 'NO'
85 | end
86 | end
87 | end
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/lib/Views/SignUpView.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
2 | import 'package:amplify_flutter/amplify.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:sample_app/Views/ErrorView.dart';
5 |
6 | class SignUpView extends StatefulWidget {
7 | @override
8 | _SignUpViewState createState() => _SignUpViewState();
9 | }
10 |
11 | class _SignUpViewState extends State {
12 | final usernameController = TextEditingController();
13 | final passwordController = TextEditingController();
14 | final emailController = TextEditingController();
15 | final phoneController = TextEditingController();
16 | final confirmationCodeController = TextEditingController();
17 |
18 | String _signUpError = "";
19 | bool _isSignedUp = false;
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | }
25 |
26 | void _signUp() async {
27 | setState(() {
28 | _signUpError = "";
29 | });
30 |
31 | Map userAttributes = {
32 | "email": emailController.text,
33 | "phone_number": phoneController.text,
34 | };
35 | try {
36 | SignUpResult res = await Amplify.Auth.signUp(
37 | username: usernameController.text.trim(),
38 | password: passwordController.text.trim(),
39 | options: CognitoSignUpOptions(userAttributes: userAttributes));
40 |
41 | setState(() {
42 | _isSignedUp = true;
43 | });
44 | } on AuthException catch (error) {
45 | _setError(error);
46 | }
47 | }
48 |
49 | void _confirmSignUp() async {
50 | setState(() {
51 | _signUpError = "";
52 | });
53 |
54 | try {
55 | SignUpResult res = await Amplify.Auth.confirmSignUp(
56 | username: usernameController.text.trim(),
57 | confirmationCode: confirmationCodeController.text.trim());
58 | Navigator.pop(context, true);
59 | } on AuthException catch (error) {
60 | _setError(error);
61 | }
62 | }
63 |
64 | void _setError(AuthException error) {
65 | setState(() {
66 | _signUpError = error.message;
67 | });
68 | }
69 |
70 | @override
71 | Widget build(BuildContext context) {
72 | return Row(
73 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
74 | children: [
75 | Expanded(
76 | // wrap your Column in Expanded
77 | child: Padding(
78 | padding: EdgeInsets.all(10.0),
79 | child: Column(
80 | children: [
81 | Visibility(
82 | visible: !_isSignedUp,
83 | child: Column(children: [
84 | TextFormField(
85 | controller: usernameController,
86 | decoration: const InputDecoration(
87 | icon: Icon(Icons.person),
88 | hintText: 'Username',
89 | labelText: 'Username *',
90 | ),
91 | ),
92 | TextFormField(
93 | obscureText: true,
94 | controller: passwordController,
95 | decoration: const InputDecoration(
96 | icon: Icon(Icons.lock),
97 | hintText: 'Password',
98 | labelText: 'Password *',
99 | ),
100 | ),
101 | TextFormField(
102 | controller: emailController,
103 | decoration: const InputDecoration(
104 | icon: Icon(Icons.email),
105 | hintText: 'Email',
106 | labelText: 'Email *',
107 | ),
108 | ),
109 | TextFormField(
110 | controller: phoneController,
111 | decoration: const InputDecoration(
112 | icon: Icon(Icons.phone),
113 | hintText: 'Phone number (WITH AREA CODE)',
114 | labelText: 'Phone number *',
115 | ),
116 | ),
117 | ElevatedButton(
118 | onPressed: _signUp,
119 | child: const Text('Sign Up'),
120 | ),
121 | ]),
122 | ),
123 | Visibility(
124 | visible: _isSignedUp,
125 | child: Column(children: [
126 | TextFormField(
127 | controller: confirmationCodeController,
128 | decoration: const InputDecoration(
129 | icon: Icon(Icons.confirmation_number),
130 | hintText: 'The code we sent you',
131 | labelText: 'Confirmation Code *',
132 | )),
133 | ElevatedButton(
134 | onPressed: _confirmSignUp,
135 | child: const Text('Confirm Sign Up'),
136 | ),
137 | ])),
138 | const Padding(padding: EdgeInsets.all(10.0)),
139 | ErrorView(_signUpError)
140 | ],
141 | ),
142 | ),
143 | ),
144 | ],
145 | );
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | amplify_analytics_pinpoint:
5 | dependency: "direct main"
6 | description:
7 | name: amplify_analytics_pinpoint
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "0.1.4"
11 | amplify_analytics_plugin_interface:
12 | dependency: transitive
13 | description:
14 | name: amplify_analytics_plugin_interface
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "0.1.4"
18 | amplify_api_plugin_interface:
19 | dependency: transitive
20 | description:
21 | name: amplify_api_plugin_interface
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "0.1.4"
25 | amplify_auth_cognito:
26 | dependency: "direct main"
27 | description:
28 | name: amplify_auth_cognito
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "0.1.4"
32 | amplify_auth_plugin_interface:
33 | dependency: transitive
34 | description:
35 | name: amplify_auth_plugin_interface
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "0.1.4"
39 | amplify_core:
40 | dependency: transitive
41 | description:
42 | name: amplify_core
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "0.1.4"
46 | amplify_datastore_plugin_interface:
47 | dependency: transitive
48 | description:
49 | name: amplify_datastore_plugin_interface
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "0.1.4"
53 | amplify_flutter:
54 | dependency: "direct main"
55 | description:
56 | name: amplify_flutter
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "0.1.4"
60 | amplify_storage_plugin_interface:
61 | dependency: transitive
62 | description:
63 | name: amplify_storage_plugin_interface
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "0.1.4"
67 | amplify_storage_s3:
68 | dependency: "direct main"
69 | description:
70 | name: amplify_storage_s3
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "0.1.4"
74 | async:
75 | dependency: transitive
76 | description:
77 | name: async
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "2.6.1"
81 | boolean_selector:
82 | dependency: transitive
83 | description:
84 | name: boolean_selector
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "2.1.0"
88 | characters:
89 | dependency: transitive
90 | description:
91 | name: characters
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "1.1.0"
95 | charcode:
96 | dependency: transitive
97 | description:
98 | name: charcode
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "1.2.0"
102 | clock:
103 | dependency: transitive
104 | description:
105 | name: clock
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "1.1.0"
109 | collection:
110 | dependency: transitive
111 | description:
112 | name: collection
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "1.15.0"
116 | crypto:
117 | dependency: transitive
118 | description:
119 | name: crypto
120 | url: "https://pub.dartlang.org"
121 | source: hosted
122 | version: "3.0.1"
123 | cupertino_icons:
124 | dependency: "direct main"
125 | description:
126 | name: cupertino_icons
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "0.1.3"
130 | date_time_format:
131 | dependency: transitive
132 | description:
133 | name: date_time_format
134 | url: "https://pub.dartlang.org"
135 | source: hosted
136 | version: "1.1.1+1"
137 | fake_async:
138 | dependency: transitive
139 | description:
140 | name: fake_async
141 | url: "https://pub.dartlang.org"
142 | source: hosted
143 | version: "1.2.0"
144 | file_picker:
145 | dependency: "direct main"
146 | description:
147 | name: file_picker
148 | url: "https://pub.dartlang.org"
149 | source: hosted
150 | version: "1.10.0"
151 | flutter:
152 | dependency: "direct main"
153 | description: flutter
154 | source: sdk
155 | version: "0.0.0"
156 | flutter_plugin_android_lifecycle:
157 | dependency: transitive
158 | description:
159 | name: flutter_plugin_android_lifecycle
160 | url: "https://pub.dartlang.org"
161 | source: hosted
162 | version: "1.0.11"
163 | flutter_test:
164 | dependency: "direct dev"
165 | description: flutter
166 | source: sdk
167 | version: "0.0.0"
168 | matcher:
169 | dependency: transitive
170 | description:
171 | name: matcher
172 | url: "https://pub.dartlang.org"
173 | source: hosted
174 | version: "0.12.10"
175 | meta:
176 | dependency: transitive
177 | description:
178 | name: meta
179 | url: "https://pub.dartlang.org"
180 | source: hosted
181 | version: "1.3.0"
182 | path:
183 | dependency: transitive
184 | description:
185 | name: path
186 | url: "https://pub.dartlang.org"
187 | source: hosted
188 | version: "1.8.0"
189 | plugin_platform_interface:
190 | dependency: transitive
191 | description:
192 | name: plugin_platform_interface
193 | url: "https://pub.dartlang.org"
194 | source: hosted
195 | version: "2.0.0"
196 | sky_engine:
197 | dependency: transitive
198 | description: flutter
199 | source: sdk
200 | version: "0.0.99"
201 | source_span:
202 | dependency: transitive
203 | description:
204 | name: source_span
205 | url: "https://pub.dartlang.org"
206 | source: hosted
207 | version: "1.8.1"
208 | stack_trace:
209 | dependency: transitive
210 | description:
211 | name: stack_trace
212 | url: "https://pub.dartlang.org"
213 | source: hosted
214 | version: "1.10.0"
215 | stream_channel:
216 | dependency: transitive
217 | description:
218 | name: stream_channel
219 | url: "https://pub.dartlang.org"
220 | source: hosted
221 | version: "2.1.0"
222 | string_scanner:
223 | dependency: transitive
224 | description:
225 | name: string_scanner
226 | url: "https://pub.dartlang.org"
227 | source: hosted
228 | version: "1.1.0"
229 | term_glyph:
230 | dependency: transitive
231 | description:
232 | name: term_glyph
233 | url: "https://pub.dartlang.org"
234 | source: hosted
235 | version: "1.2.0"
236 | test_api:
237 | dependency: transitive
238 | description:
239 | name: test_api
240 | url: "https://pub.dartlang.org"
241 | source: hosted
242 | version: "0.3.0"
243 | typed_data:
244 | dependency: transitive
245 | description:
246 | name: typed_data
247 | url: "https://pub.dartlang.org"
248 | source: hosted
249 | version: "1.3.0"
250 | uuid:
251 | dependency: transitive
252 | description:
253 | name: uuid
254 | url: "https://pub.dartlang.org"
255 | source: hosted
256 | version: "3.0.4"
257 | vector_math:
258 | dependency: transitive
259 | description:
260 | name: vector_math
261 | url: "https://pub.dartlang.org"
262 | source: hosted
263 | version: "2.1.0"
264 | sdks:
265 | dart: ">=2.12.0 <3.0.0"
266 | flutter: ">=1.20.0"
267 |
--------------------------------------------------------------------------------
/amplify/backend/awscloudformation/build/auth/cloudchopperd20aa567/cloudchopperd20aa567-cloudformation-template.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: '2010-09-09'
2 | Parameters:
3 | env:
4 | Type: String
5 | authRoleArn:
6 | Type: String
7 | unauthRoleArn:
8 | Type: String
9 | identityPoolName:
10 | Type: String
11 | allowUnauthenticatedIdentities:
12 | Type: String
13 | resourceNameTruncated:
14 | Type: String
15 | userPoolName:
16 | Type: String
17 | autoVerifiedAttributes:
18 | Type: CommaDelimitedList
19 | mfaConfiguration:
20 | Type: String
21 | mfaTypes:
22 | Type: CommaDelimitedList
23 | smsAuthenticationMessage:
24 | Type: String
25 | smsVerificationMessage:
26 | Type: String
27 | emailVerificationSubject:
28 | Type: String
29 | emailVerificationMessage:
30 | Type: String
31 | defaultPasswordPolicy:
32 | Type: String
33 | passwordPolicyMinLength:
34 | Type: Number
35 | passwordPolicyCharacters:
36 | Type: CommaDelimitedList
37 | requiredAttributes:
38 | Type: CommaDelimitedList
39 | userpoolClientGenerateSecret:
40 | Type: String
41 | userpoolClientRefreshTokenValidity:
42 | Type: Number
43 | userpoolClientWriteAttributes:
44 | Type: CommaDelimitedList
45 | userpoolClientReadAttributes:
46 | Type: CommaDelimitedList
47 | userpoolClientLambdaRole:
48 | Type: String
49 | userpoolClientSetAttributes:
50 | Type: String
51 | sharedId:
52 | Type: String
53 | resourceName:
54 | Type: String
55 | authSelections:
56 | Type: String
57 | useDefault:
58 | Type: String
59 | userPoolGroupList:
60 | Type: CommaDelimitedList
61 | serviceName:
62 | Type: String
63 | usernameCaseSensitive:
64 | Type: String
65 | dependsOn:
66 | Type: CommaDelimitedList
67 | Conditions:
68 | ShouldNotCreateEnvResources:
69 | Fn::Equals:
70 | - Ref: env
71 | - NONE
72 | ShouldOutputAppClientSecrets:
73 | Fn::Equals:
74 | - Ref: userpoolClientGenerateSecret
75 | - 'true'
76 | Resources:
77 | SNSRole:
78 | Type: AWS::IAM::Role
79 | Properties:
80 | RoleName:
81 | Fn::If:
82 | - ShouldNotCreateEnvResources
83 | - cloudcd20aa567_sns-role
84 | - Fn::Join:
85 | - ''
86 | - - sns
87 | - d20aa567
88 | - Fn::Select:
89 | - '3'
90 | - Fn::Split:
91 | - '-'
92 | - Ref: AWS::StackName
93 | - '-'
94 | - Ref: env
95 | AssumeRolePolicyDocument:
96 | Version: '2012-10-17'
97 | Statement:
98 | - Sid: ''
99 | Effect: Allow
100 | Principal:
101 | Service: cognito-idp.amazonaws.com
102 | Action:
103 | - sts:AssumeRole
104 | Condition:
105 | StringEquals:
106 | sts:ExternalId: cloudcd20aa567_role_external_id
107 | Policies:
108 | - PolicyName: cloudcd20aa567-sns-policy
109 | PolicyDocument:
110 | Version: '2012-10-17'
111 | Statement:
112 | - Effect: Allow
113 | Action:
114 | - sns:Publish
115 | Resource: '*'
116 | UserPool:
117 | Type: AWS::Cognito::UserPool
118 | UpdateReplacePolicy: Retain
119 | Properties:
120 | UserPoolName:
121 | Fn::If:
122 | - ShouldNotCreateEnvResources
123 | - Ref: userPoolName
124 | - Fn::Join:
125 | - ''
126 | - - Ref: userPoolName
127 | - '-'
128 | - Ref: env
129 | UsernameConfiguration:
130 | CaseSensitive: 'false'
131 | Schema:
132 | - Name: email
133 | Required: 'true'
134 | Mutable: 'true'
135 | AutoVerifiedAttributes:
136 | Ref: autoVerifiedAttributes
137 | EmailVerificationMessage:
138 | Ref: emailVerificationMessage
139 | EmailVerificationSubject:
140 | Ref: emailVerificationSubject
141 | Policies:
142 | PasswordPolicy:
143 | MinimumLength:
144 | Ref: passwordPolicyMinLength
145 | RequireLowercase: 'false'
146 | RequireNumbers: 'false'
147 | RequireSymbols: 'false'
148 | RequireUppercase: 'false'
149 | MfaConfiguration:
150 | Ref: mfaConfiguration
151 | SmsVerificationMessage:
152 | Ref: smsVerificationMessage
153 | SmsAuthenticationMessage:
154 | Ref: smsAuthenticationMessage
155 | SmsConfiguration:
156 | SnsCallerArn:
157 | Fn::GetAtt:
158 | - SNSRole
159 | - Arn
160 | ExternalId: cloudcd20aa567_role_external_id
161 | UserPoolClientWeb:
162 | Type: AWS::Cognito::UserPoolClient
163 | Properties:
164 | ClientName: cloudcd20aa567_app_clientWeb
165 | RefreshTokenValidity:
166 | Ref: userpoolClientRefreshTokenValidity
167 | UserPoolId:
168 | Ref: UserPool
169 | DependsOn: UserPool
170 | UserPoolClient:
171 | Type: AWS::Cognito::UserPoolClient
172 | Properties:
173 | ClientName: cloudcd20aa567_app_client
174 | GenerateSecret:
175 | Ref: userpoolClientGenerateSecret
176 | RefreshTokenValidity:
177 | Ref: userpoolClientRefreshTokenValidity
178 | UserPoolId:
179 | Ref: UserPool
180 | DependsOn: UserPool
181 | UserPoolClientRole:
182 | Type: AWS::IAM::Role
183 | Properties:
184 | RoleName:
185 | Fn::If:
186 | - ShouldNotCreateEnvResources
187 | - Ref: userpoolClientLambdaRole
188 | - Fn::Join:
189 | - ''
190 | - - upClientLambdaRole
191 | - d20aa567
192 | - Fn::Select:
193 | - '3'
194 | - Fn::Split:
195 | - '-'
196 | - Ref: AWS::StackName
197 | - '-'
198 | - Ref: env
199 | AssumeRolePolicyDocument:
200 | Version: '2012-10-17'
201 | Statement:
202 | - Effect: Allow
203 | Principal:
204 | Service:
205 | - lambda.amazonaws.com
206 | Action:
207 | - sts:AssumeRole
208 | DependsOn: UserPoolClient
209 | UserPoolClientLambda:
210 | Type: AWS::Lambda::Function
211 | Properties:
212 | Code:
213 | ZipFile:
214 | Fn::Join:
215 | - ''
216 | - - const response = require('cfn-response');
217 | - const aws = require('aws-sdk');
218 | - const identity = new aws.CognitoIdentityServiceProvider();
219 | - exports.handler = (event, context, callback) => {
220 | - ' if (event.RequestType == ''Delete'') { '
221 | - ' response.send(event, context, response.SUCCESS, {})'
222 | - ' }'
223 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
224 | - ' const params = {'
225 | - ' ClientId: event.ResourceProperties.clientId,'
226 | - ' UserPoolId: event.ResourceProperties.userpoolId'
227 | - ' };'
228 | - ' identity.describeUserPoolClient(params).promise()'
229 | - ' .then((res) => {'
230 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
231 | - ' })'
232 | - ' .catch((err) => {'
233 | - ' response.send(event, context, response.FAILED, {err});'
234 | - ' });'
235 | - ' }'
236 | - '};'
237 | Handler: index.handler
238 | Runtime: nodejs12.x
239 | Timeout: '300'
240 | Role:
241 | Fn::GetAtt:
242 | - UserPoolClientRole
243 | - Arn
244 | DependsOn: UserPoolClientRole
245 | UserPoolClientLambdaPolicy:
246 | Type: AWS::IAM::Policy
247 | Properties:
248 | PolicyName: cloudcd20aa567_userpoolclient_lambda_iam_policy
249 | Roles:
250 | - Ref: UserPoolClientRole
251 | PolicyDocument:
252 | Version: '2012-10-17'
253 | Statement:
254 | - Effect: Allow
255 | Action:
256 | - cognito-idp:DescribeUserPoolClient
257 | Resource:
258 | Fn::GetAtt:
259 | - UserPool
260 | - Arn
261 | DependsOn: UserPoolClientLambda
262 | UserPoolClientLogPolicy:
263 | Type: AWS::IAM::Policy
264 | Properties:
265 | PolicyName: cloudcd20aa567_userpoolclient_lambda_log_policy
266 | Roles:
267 | - Ref: UserPoolClientRole
268 | PolicyDocument:
269 | Version: '2012-10-17'
270 | Statement:
271 | - Effect: Allow
272 | Action:
273 | - logs:CreateLogGroup
274 | - logs:CreateLogStream
275 | - logs:PutLogEvents
276 | Resource:
277 | Fn::Sub:
278 | - >-
279 | arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
280 | - region:
281 | Ref: AWS::Region
282 | account:
283 | Ref: AWS::AccountId
284 | lambda:
285 | Ref: UserPoolClientLambda
286 | DependsOn: UserPoolClientLambdaPolicy
287 | UserPoolClientInputs:
288 | Type: Custom::LambdaCallout
289 | Properties:
290 | ServiceToken:
291 | Fn::GetAtt:
292 | - UserPoolClientLambda
293 | - Arn
294 | clientId:
295 | Ref: UserPoolClient
296 | userpoolId:
297 | Ref: UserPool
298 | DependsOn: UserPoolClientLogPolicy
299 | IdentityPool:
300 | Type: AWS::Cognito::IdentityPool
301 | Properties:
302 | IdentityPoolName:
303 | Fn::If:
304 | - ShouldNotCreateEnvResources
305 | - cloudchopperd20aa567_identitypool_d20aa567
306 | - Fn::Join:
307 | - ''
308 | - - cloudchopperd20aa567_identitypool_d20aa567
309 | - __
310 | - Ref: env
311 | CognitoIdentityProviders:
312 | - ClientId:
313 | Ref: UserPoolClient
314 | ProviderName:
315 | Fn::Sub:
316 | - cognito-idp.${region}.amazonaws.com/${client}
317 | - region:
318 | Ref: AWS::Region
319 | client:
320 | Ref: UserPool
321 | - ClientId:
322 | Ref: UserPoolClientWeb
323 | ProviderName:
324 | Fn::Sub:
325 | - cognito-idp.${region}.amazonaws.com/${client}
326 | - region:
327 | Ref: AWS::Region
328 | client:
329 | Ref: UserPool
330 | AllowUnauthenticatedIdentities:
331 | Ref: allowUnauthenticatedIdentities
332 | DependsOn: UserPoolClientInputs
333 | IdentityPoolRoleMap:
334 | Type: AWS::Cognito::IdentityPoolRoleAttachment
335 | Properties:
336 | IdentityPoolId:
337 | Ref: IdentityPool
338 | Roles:
339 | unauthenticated:
340 | Ref: unauthRoleArn
341 | authenticated:
342 | Ref: authRoleArn
343 | DependsOn: IdentityPool
344 | Outputs:
345 | IdentityPoolId:
346 | Value:
347 | Ref: IdentityPool
348 | Description: Id for the identity pool
349 | IdentityPoolName:
350 | Value:
351 | Fn::GetAtt:
352 | - IdentityPool
353 | - Name
354 | UserPoolId:
355 | Value:
356 | Ref: UserPool
357 | Description: Id for the user pool
358 | UserPoolName:
359 | Value:
360 | Ref: userPoolName
361 | AppClientIDWeb:
362 | Value:
363 | Ref: UserPoolClientWeb
364 | Description: The user pool app client id for web
365 | AppClientID:
366 | Value:
367 | Ref: UserPoolClient
368 | Description: The user pool app client id
369 | AppClientSecret:
370 | Value:
371 | Fn::GetAtt:
372 | - UserPoolClientInputs
373 | - appSecret
374 | Condition: ShouldOutputAppClientSecrets
375 |
--------------------------------------------------------------------------------
/amplify/backend/auth/cloudchopperd20aa567/cloudchopperd20aa567-cloudformation-template.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: 2010-09-09
2 |
3 | Parameters:
4 | env:
5 | Type: String
6 | authRoleArn:
7 | Type: String
8 | unauthRoleArn:
9 | Type: String
10 |
11 |
12 |
13 |
14 | identityPoolName:
15 | Type: String
16 |
17 |
18 |
19 | allowUnauthenticatedIdentities:
20 | Type: String
21 |
22 | resourceNameTruncated:
23 | Type: String
24 |
25 |
26 | userPoolName:
27 | Type: String
28 |
29 |
30 |
31 | autoVerifiedAttributes:
32 | Type: CommaDelimitedList
33 |
34 | mfaConfiguration:
35 | Type: String
36 |
37 |
38 |
39 | mfaTypes:
40 | Type: CommaDelimitedList
41 |
42 | smsAuthenticationMessage:
43 | Type: String
44 |
45 |
46 | smsVerificationMessage:
47 | Type: String
48 |
49 |
50 | emailVerificationSubject:
51 | Type: String
52 |
53 |
54 | emailVerificationMessage:
55 | Type: String
56 |
57 |
58 |
59 | defaultPasswordPolicy:
60 | Type: String
61 |
62 |
63 | passwordPolicyMinLength:
64 | Type: Number
65 |
66 |
67 | passwordPolicyCharacters:
68 | Type: CommaDelimitedList
69 |
70 |
71 | requiredAttributes:
72 | Type: CommaDelimitedList
73 |
74 |
75 | userpoolClientGenerateSecret:
76 | Type: String
77 |
78 |
79 | userpoolClientRefreshTokenValidity:
80 | Type: Number
81 |
82 |
83 | userpoolClientWriteAttributes:
84 | Type: CommaDelimitedList
85 |
86 |
87 | userpoolClientReadAttributes:
88 | Type: CommaDelimitedList
89 |
90 | userpoolClientLambdaRole:
91 | Type: String
92 |
93 |
94 |
95 | userpoolClientSetAttributes:
96 | Type: String
97 |
98 | sharedId:
99 | Type: String
100 |
101 |
102 | resourceName:
103 | Type: String
104 |
105 |
106 | authSelections:
107 | Type: String
108 |
109 |
110 |
111 |
112 | useDefault:
113 | Type: String
114 |
115 |
116 |
117 | userPoolGroupList:
118 | Type: CommaDelimitedList
119 |
120 | serviceName:
121 | Type: String
122 |
123 |
124 |
125 | usernameCaseSensitive:
126 | Type: String
127 |
128 |
129 | dependsOn:
130 | Type: CommaDelimitedList
131 |
132 | Conditions:
133 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
134 |
135 | ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ]
136 |
137 |
138 | Resources:
139 |
140 |
141 | # BEGIN SNS ROLE RESOURCE
142 | SNSRole:
143 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
144 | Type: AWS::IAM::Role
145 | Properties:
146 | RoleName: !If [ShouldNotCreateEnvResources, 'cloudcd20aa567_sns-role', !Join ['',[ 'sns', 'd20aa567', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
147 | AssumeRolePolicyDocument:
148 | Version: "2012-10-17"
149 | Statement:
150 | - Sid: ""
151 | Effect: "Allow"
152 | Principal:
153 | Service: "cognito-idp.amazonaws.com"
154 | Action:
155 | - "sts:AssumeRole"
156 | Condition:
157 | StringEquals:
158 | sts:ExternalId: cloudcd20aa567_role_external_id
159 | Policies:
160 | -
161 | PolicyName: cloudcd20aa567-sns-policy
162 | PolicyDocument:
163 | Version: "2012-10-17"
164 | Statement:
165 | -
166 | Effect: "Allow"
167 | Action:
168 | - "sns:Publish"
169 | Resource: "*"
170 | # BEGIN USER POOL RESOURCES
171 | UserPool:
172 | # Created upon user selection
173 | # Depends on SNS Role for Arn if MFA is enabled
174 | Type: AWS::Cognito::UserPool
175 | UpdateReplacePolicy: Retain
176 | Properties:
177 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
178 |
179 |
180 | UsernameConfiguration:
181 | CaseSensitive: false
182 |
183 | Schema:
184 |
185 | -
186 | Name: email
187 | Required: true
188 | Mutable: true
189 |
190 |
191 |
192 |
193 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes
194 |
195 |
196 | EmailVerificationMessage: !Ref emailVerificationMessage
197 | EmailVerificationSubject: !Ref emailVerificationSubject
198 |
199 | Policies:
200 | PasswordPolicy:
201 | MinimumLength: !Ref passwordPolicyMinLength
202 | RequireLowercase: false
203 | RequireNumbers: false
204 | RequireSymbols: false
205 | RequireUppercase: false
206 |
207 | MfaConfiguration: !Ref mfaConfiguration
208 | SmsVerificationMessage: !Ref smsVerificationMessage
209 | SmsAuthenticationMessage: !Ref smsAuthenticationMessage
210 | SmsConfiguration:
211 | SnsCallerArn: !GetAtt SNSRole.Arn
212 | ExternalId: cloudcd20aa567_role_external_id
213 |
214 |
215 | UserPoolClientWeb:
216 | # Created provide application access to user pool
217 | # Depends on UserPool for ID reference
218 | Type: "AWS::Cognito::UserPoolClient"
219 | Properties:
220 | ClientName: cloudcd20aa567_app_clientWeb
221 |
222 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
223 | UserPoolId: !Ref UserPool
224 | DependsOn: UserPool
225 | UserPoolClient:
226 | # Created provide application access to user pool
227 | # Depends on UserPool for ID reference
228 | Type: "AWS::Cognito::UserPoolClient"
229 | Properties:
230 | ClientName: cloudcd20aa567_app_client
231 |
232 | GenerateSecret: !Ref userpoolClientGenerateSecret
233 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
234 | UserPoolId: !Ref UserPool
235 | DependsOn: UserPool
236 | # BEGIN USER POOL LAMBDA RESOURCES
237 | UserPoolClientRole:
238 | # Created to execute Lambda which gets userpool app client config values
239 | Type: 'AWS::IAM::Role'
240 | Properties:
241 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'd20aa567', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
242 | AssumeRolePolicyDocument:
243 | Version: '2012-10-17'
244 | Statement:
245 | - Effect: Allow
246 | Principal:
247 | Service:
248 | - lambda.amazonaws.com
249 | Action:
250 | - 'sts:AssumeRole'
251 | DependsOn: UserPoolClient
252 | UserPoolClientLambda:
253 | # Lambda which gets userpool app client config values
254 | # Depends on UserPool for id
255 | # Depends on UserPoolClientRole for role ARN
256 | Type: 'AWS::Lambda::Function'
257 | Properties:
258 | Code:
259 | ZipFile: !Join
260 | - |+
261 | - - 'const response = require(''cfn-response'');'
262 | - 'const aws = require(''aws-sdk'');'
263 | - 'const identity = new aws.CognitoIdentityServiceProvider();'
264 | - 'exports.handler = (event, context, callback) => {'
265 | - ' if (event.RequestType == ''Delete'') { '
266 | - ' response.send(event, context, response.SUCCESS, {})'
267 | - ' }'
268 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
269 | - ' const params = {'
270 | - ' ClientId: event.ResourceProperties.clientId,'
271 | - ' UserPoolId: event.ResourceProperties.userpoolId'
272 | - ' };'
273 | - ' identity.describeUserPoolClient(params).promise()'
274 | - ' .then((res) => {'
275 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
276 | - ' })'
277 | - ' .catch((err) => {'
278 | - ' response.send(event, context, response.FAILED, {err});'
279 | - ' });'
280 | - ' }'
281 | - '};'
282 | Handler: index.handler
283 | Runtime: nodejs12.x
284 | Timeout: '300'
285 | Role: !GetAtt
286 | - UserPoolClientRole
287 | - Arn
288 | DependsOn: UserPoolClientRole
289 | UserPoolClientLambdaPolicy:
290 | # Sets userpool policy for the role that executes the Userpool Client Lambda
291 | # Depends on UserPool for Arn
292 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
293 | Type: 'AWS::IAM::Policy'
294 | Properties:
295 | PolicyName: cloudcd20aa567_userpoolclient_lambda_iam_policy
296 | Roles:
297 | - !Ref UserPoolClientRole
298 | PolicyDocument:
299 | Version: '2012-10-17'
300 | Statement:
301 | - Effect: Allow
302 | Action:
303 | - 'cognito-idp:DescribeUserPoolClient'
304 | Resource: !GetAtt UserPool.Arn
305 | DependsOn: UserPoolClientLambda
306 | UserPoolClientLogPolicy:
307 | # Sets log policy for the role that executes the Userpool Client Lambda
308 | # Depends on UserPool for Arn
309 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
310 | Type: 'AWS::IAM::Policy'
311 | Properties:
312 | PolicyName: cloudcd20aa567_userpoolclient_lambda_log_policy
313 | Roles:
314 | - !Ref UserPoolClientRole
315 | PolicyDocument:
316 | Version: 2012-10-17
317 | Statement:
318 | - Effect: Allow
319 | Action:
320 | - 'logs:CreateLogGroup'
321 | - 'logs:CreateLogStream'
322 | - 'logs:PutLogEvents'
323 | Resource: !Sub
324 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
325 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
326 | DependsOn: UserPoolClientLambdaPolicy
327 | UserPoolClientInputs:
328 | # Values passed to Userpool client Lambda
329 | # Depends on UserPool for Id
330 | # Depends on UserPoolClient for Id
331 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
332 | Type: 'Custom::LambdaCallout'
333 | Properties:
334 | ServiceToken: !GetAtt UserPoolClientLambda.Arn
335 | clientId: !Ref UserPoolClient
336 | userpoolId: !Ref UserPool
337 | DependsOn: UserPoolClientLogPolicy
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 | # BEGIN IDENTITY POOL RESOURCES
346 |
347 |
348 | IdentityPool:
349 | # Always created
350 | Type: AWS::Cognito::IdentityPool
351 | Properties:
352 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'cloudchopperd20aa567_identitypool_d20aa567', !Join ['',['cloudchopperd20aa567_identitypool_d20aa567', '__', !Ref env]]]
353 |
354 | CognitoIdentityProviders:
355 | - ClientId: !Ref UserPoolClient
356 | ProviderName: !Sub
357 | - cognito-idp.${region}.amazonaws.com/${client}
358 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
359 | - ClientId: !Ref UserPoolClientWeb
360 | ProviderName: !Sub
361 | - cognito-idp.${region}.amazonaws.com/${client}
362 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
363 |
364 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
365 |
366 |
367 | DependsOn: UserPoolClientInputs
368 |
369 |
370 | IdentityPoolRoleMap:
371 | # Created to map Auth and Unauth roles to the identity pool
372 | # Depends on Identity Pool for ID ref
373 | Type: AWS::Cognito::IdentityPoolRoleAttachment
374 | Properties:
375 | IdentityPoolId: !Ref IdentityPool
376 | Roles:
377 | unauthenticated: !Ref unauthRoleArn
378 | authenticated: !Ref authRoleArn
379 | DependsOn: IdentityPool
380 |
381 |
382 | Outputs :
383 |
384 | IdentityPoolId:
385 | Value: !Ref 'IdentityPool'
386 | Description: Id for the identity pool
387 | IdentityPoolName:
388 | Value: !GetAtt IdentityPool.Name
389 |
390 |
391 |
392 |
393 | UserPoolId:
394 | Value: !Ref 'UserPool'
395 | Description: Id for the user pool
396 | UserPoolName:
397 | Value: !Ref userPoolName
398 | AppClientIDWeb:
399 | Value: !Ref 'UserPoolClientWeb'
400 | Description: The user pool app client id for web
401 | AppClientID:
402 | Value: !Ref 'UserPoolClient'
403 | Description: The user pool app client id
404 | AppClientSecret:
405 | Value: !GetAtt UserPoolClientInputs.appSecret
406 | Condition: ShouldOutputAppClientSecrets
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/auth/cloudchopperd20aa567/cloudchopperd20aa567-cloudformation-template.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: 2010-09-09
2 |
3 | Parameters:
4 | env:
5 | Type: String
6 | authRoleArn:
7 | Type: String
8 | unauthRoleArn:
9 | Type: String
10 |
11 |
12 |
13 |
14 | identityPoolName:
15 | Type: String
16 |
17 |
18 |
19 | allowUnauthenticatedIdentities:
20 | Type: String
21 |
22 | resourceNameTruncated:
23 | Type: String
24 |
25 |
26 | userPoolName:
27 | Type: String
28 |
29 |
30 |
31 | autoVerifiedAttributes:
32 | Type: CommaDelimitedList
33 |
34 | mfaConfiguration:
35 | Type: String
36 |
37 |
38 |
39 | mfaTypes:
40 | Type: CommaDelimitedList
41 |
42 | smsAuthenticationMessage:
43 | Type: String
44 |
45 |
46 | smsVerificationMessage:
47 | Type: String
48 |
49 |
50 | emailVerificationSubject:
51 | Type: String
52 |
53 |
54 | emailVerificationMessage:
55 | Type: String
56 |
57 |
58 |
59 | defaultPasswordPolicy:
60 | Type: String
61 |
62 |
63 | passwordPolicyMinLength:
64 | Type: Number
65 |
66 |
67 | passwordPolicyCharacters:
68 | Type: CommaDelimitedList
69 |
70 |
71 | requiredAttributes:
72 | Type: CommaDelimitedList
73 |
74 |
75 | userpoolClientGenerateSecret:
76 | Type: String
77 |
78 |
79 | userpoolClientRefreshTokenValidity:
80 | Type: Number
81 |
82 |
83 | userpoolClientWriteAttributes:
84 | Type: CommaDelimitedList
85 |
86 |
87 | userpoolClientReadAttributes:
88 | Type: CommaDelimitedList
89 |
90 | userpoolClientLambdaRole:
91 | Type: String
92 |
93 |
94 |
95 | userpoolClientSetAttributes:
96 | Type: String
97 |
98 | sharedId:
99 | Type: String
100 |
101 |
102 | resourceName:
103 | Type: String
104 |
105 |
106 | authSelections:
107 | Type: String
108 |
109 |
110 |
111 |
112 | useDefault:
113 | Type: String
114 |
115 |
116 |
117 | userPoolGroupList:
118 | Type: CommaDelimitedList
119 |
120 | serviceName:
121 | Type: String
122 |
123 |
124 |
125 | usernameCaseSensitive:
126 | Type: String
127 |
128 |
129 | dependsOn:
130 | Type: CommaDelimitedList
131 |
132 | Conditions:
133 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
134 |
135 | ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ]
136 |
137 |
138 | Resources:
139 |
140 |
141 | # BEGIN SNS ROLE RESOURCE
142 | SNSRole:
143 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
144 | Type: AWS::IAM::Role
145 | Properties:
146 | RoleName: !If [ShouldNotCreateEnvResources, 'cloudcd20aa567_sns-role', !Join ['',[ 'sns', 'd20aa567', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
147 | AssumeRolePolicyDocument:
148 | Version: "2012-10-17"
149 | Statement:
150 | - Sid: ""
151 | Effect: "Allow"
152 | Principal:
153 | Service: "cognito-idp.amazonaws.com"
154 | Action:
155 | - "sts:AssumeRole"
156 | Condition:
157 | StringEquals:
158 | sts:ExternalId: cloudcd20aa567_role_external_id
159 | Policies:
160 | -
161 | PolicyName: cloudcd20aa567-sns-policy
162 | PolicyDocument:
163 | Version: "2012-10-17"
164 | Statement:
165 | -
166 | Effect: "Allow"
167 | Action:
168 | - "sns:Publish"
169 | Resource: "*"
170 | # BEGIN USER POOL RESOURCES
171 | UserPool:
172 | # Created upon user selection
173 | # Depends on SNS Role for Arn if MFA is enabled
174 | Type: AWS::Cognito::UserPool
175 | UpdateReplacePolicy: Retain
176 | Properties:
177 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
178 |
179 |
180 | UsernameConfiguration:
181 | CaseSensitive: false
182 |
183 | Schema:
184 |
185 | -
186 | Name: email
187 | Required: true
188 | Mutable: true
189 |
190 |
191 |
192 |
193 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes
194 |
195 |
196 | EmailVerificationMessage: !Ref emailVerificationMessage
197 | EmailVerificationSubject: !Ref emailVerificationSubject
198 |
199 | Policies:
200 | PasswordPolicy:
201 | MinimumLength: !Ref passwordPolicyMinLength
202 | RequireLowercase: false
203 | RequireNumbers: false
204 | RequireSymbols: false
205 | RequireUppercase: false
206 |
207 | MfaConfiguration: !Ref mfaConfiguration
208 | SmsVerificationMessage: !Ref smsVerificationMessage
209 | SmsAuthenticationMessage: !Ref smsAuthenticationMessage
210 | SmsConfiguration:
211 | SnsCallerArn: !GetAtt SNSRole.Arn
212 | ExternalId: cloudcd20aa567_role_external_id
213 |
214 |
215 | UserPoolClientWeb:
216 | # Created provide application access to user pool
217 | # Depends on UserPool for ID reference
218 | Type: "AWS::Cognito::UserPoolClient"
219 | Properties:
220 | ClientName: cloudcd20aa567_app_clientWeb
221 |
222 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
223 | UserPoolId: !Ref UserPool
224 | DependsOn: UserPool
225 | UserPoolClient:
226 | # Created provide application access to user pool
227 | # Depends on UserPool for ID reference
228 | Type: "AWS::Cognito::UserPoolClient"
229 | Properties:
230 | ClientName: cloudcd20aa567_app_client
231 |
232 | GenerateSecret: !Ref userpoolClientGenerateSecret
233 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
234 | UserPoolId: !Ref UserPool
235 | DependsOn: UserPool
236 | # BEGIN USER POOL LAMBDA RESOURCES
237 | UserPoolClientRole:
238 | # Created to execute Lambda which gets userpool app client config values
239 | Type: 'AWS::IAM::Role'
240 | Properties:
241 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'd20aa567', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
242 | AssumeRolePolicyDocument:
243 | Version: '2012-10-17'
244 | Statement:
245 | - Effect: Allow
246 | Principal:
247 | Service:
248 | - lambda.amazonaws.com
249 | Action:
250 | - 'sts:AssumeRole'
251 | DependsOn: UserPoolClient
252 | UserPoolClientLambda:
253 | # Lambda which gets userpool app client config values
254 | # Depends on UserPool for id
255 | # Depends on UserPoolClientRole for role ARN
256 | Type: 'AWS::Lambda::Function'
257 | Properties:
258 | Code:
259 | ZipFile: !Join
260 | - |+
261 | - - 'const response = require(''cfn-response'');'
262 | - 'const aws = require(''aws-sdk'');'
263 | - 'const identity = new aws.CognitoIdentityServiceProvider();'
264 | - 'exports.handler = (event, context, callback) => {'
265 | - ' if (event.RequestType == ''Delete'') { '
266 | - ' response.send(event, context, response.SUCCESS, {})'
267 | - ' }'
268 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
269 | - ' const params = {'
270 | - ' ClientId: event.ResourceProperties.clientId,'
271 | - ' UserPoolId: event.ResourceProperties.userpoolId'
272 | - ' };'
273 | - ' identity.describeUserPoolClient(params).promise()'
274 | - ' .then((res) => {'
275 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
276 | - ' })'
277 | - ' .catch((err) => {'
278 | - ' response.send(event, context, response.FAILED, {err});'
279 | - ' });'
280 | - ' }'
281 | - '};'
282 | Handler: index.handler
283 | Runtime: nodejs12.x
284 | Timeout: '300'
285 | Role: !GetAtt
286 | - UserPoolClientRole
287 | - Arn
288 | DependsOn: UserPoolClientRole
289 | UserPoolClientLambdaPolicy:
290 | # Sets userpool policy for the role that executes the Userpool Client Lambda
291 | # Depends on UserPool for Arn
292 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
293 | Type: 'AWS::IAM::Policy'
294 | Properties:
295 | PolicyName: cloudcd20aa567_userpoolclient_lambda_iam_policy
296 | Roles:
297 | - !Ref UserPoolClientRole
298 | PolicyDocument:
299 | Version: '2012-10-17'
300 | Statement:
301 | - Effect: Allow
302 | Action:
303 | - 'cognito-idp:DescribeUserPoolClient'
304 | Resource: !GetAtt UserPool.Arn
305 | DependsOn: UserPoolClientLambda
306 | UserPoolClientLogPolicy:
307 | # Sets log policy for the role that executes the Userpool Client Lambda
308 | # Depends on UserPool for Arn
309 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
310 | Type: 'AWS::IAM::Policy'
311 | Properties:
312 | PolicyName: cloudcd20aa567_userpoolclient_lambda_log_policy
313 | Roles:
314 | - !Ref UserPoolClientRole
315 | PolicyDocument:
316 | Version: 2012-10-17
317 | Statement:
318 | - Effect: Allow
319 | Action:
320 | - 'logs:CreateLogGroup'
321 | - 'logs:CreateLogStream'
322 | - 'logs:PutLogEvents'
323 | Resource: !Sub
324 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
325 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
326 | DependsOn: UserPoolClientLambdaPolicy
327 | UserPoolClientInputs:
328 | # Values passed to Userpool client Lambda
329 | # Depends on UserPool for Id
330 | # Depends on UserPoolClient for Id
331 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
332 | Type: 'Custom::LambdaCallout'
333 | Properties:
334 | ServiceToken: !GetAtt UserPoolClientLambda.Arn
335 | clientId: !Ref UserPoolClient
336 | userpoolId: !Ref UserPool
337 | DependsOn: UserPoolClientLogPolicy
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 | # BEGIN IDENTITY POOL RESOURCES
346 |
347 |
348 | IdentityPool:
349 | # Always created
350 | Type: AWS::Cognito::IdentityPool
351 | Properties:
352 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'cloudchopperd20aa567_identitypool_d20aa567', !Join ['',['cloudchopperd20aa567_identitypool_d20aa567', '__', !Ref env]]]
353 |
354 | CognitoIdentityProviders:
355 | - ClientId: !Ref UserPoolClient
356 | ProviderName: !Sub
357 | - cognito-idp.${region}.amazonaws.com/${client}
358 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
359 | - ClientId: !Ref UserPoolClientWeb
360 | ProviderName: !Sub
361 | - cognito-idp.${region}.amazonaws.com/${client}
362 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
363 |
364 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
365 |
366 |
367 | DependsOn: UserPoolClientInputs
368 |
369 |
370 | IdentityPoolRoleMap:
371 | # Created to map Auth and Unauth roles to the identity pool
372 | # Depends on Identity Pool for ID ref
373 | Type: AWS::Cognito::IdentityPoolRoleAttachment
374 | Properties:
375 | IdentityPoolId: !Ref IdentityPool
376 | Roles:
377 | unauthenticated: !Ref unauthRoleArn
378 | authenticated: !Ref authRoleArn
379 | DependsOn: IdentityPool
380 |
381 |
382 | Outputs :
383 |
384 | IdentityPoolId:
385 | Value: !Ref 'IdentityPool'
386 | Description: Id for the identity pool
387 | IdentityPoolName:
388 | Value: !GetAtt IdentityPool.Name
389 |
390 |
391 |
392 |
393 | UserPoolId:
394 | Value: !Ref 'UserPool'
395 | Description: Id for the user pool
396 | UserPoolName:
397 | Value: !Ref userPoolName
398 | AppClientIDWeb:
399 | Value: !Ref 'UserPoolClientWeb'
400 | Description: The user pool app client id for web
401 | AppClientID:
402 | Value: !Ref 'UserPoolClient'
403 | Description: The user pool app client id
404 | AppClientSecret:
405 | Value: !GetAtt UserPoolClientInputs.appSecret
406 | Condition: ShouldOutputAppClientSecrets
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
--------------------------------------------------------------------------------
/amplify/backend/storage/S3chopperthao/s3-cloudformation-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "S3 resource stack creation using Amplify CLI",
4 | "Parameters": {
5 | "bucketName": {
6 | "Type": "String"
7 | },
8 | "authPolicyName": {
9 | "Type": "String"
10 | },
11 | "unauthPolicyName": {
12 | "Type": "String"
13 | },
14 | "authRoleName": {
15 | "Type": "String"
16 | },
17 | "unauthRoleName": {
18 | "Type": "String"
19 | },
20 | "s3PublicPolicy": {
21 | "Type": "String",
22 | "Default" : "NONE"
23 | },
24 | "s3PrivatePolicy": {
25 | "Type": "String",
26 | "Default" : "NONE"
27 | },
28 | "s3ProtectedPolicy": {
29 | "Type": "String",
30 | "Default" : "NONE"
31 | },
32 | "s3UploadsPolicy": {
33 | "Type": "String",
34 | "Default" : "NONE"
35 | },
36 | "s3ReadPolicy": {
37 | "Type": "String",
38 | "Default" : "NONE"
39 | },
40 | "s3PermissionsAuthenticatedPublic": {
41 | "Type": "String",
42 | "Default" : "DISALLOW"
43 | },
44 | "s3PermissionsAuthenticatedProtected": {
45 | "Type": "String",
46 | "Default" : "DISALLOW"
47 | },
48 | "s3PermissionsAuthenticatedPrivate": {
49 | "Type": "String",
50 | "Default" : "DISALLOW"
51 | },
52 | "s3PermissionsAuthenticatedUploads": {
53 | "Type": "String",
54 | "Default" : "DISALLOW"
55 | },
56 | "s3PermissionsGuestPublic": {
57 | "Type": "String",
58 | "Default" : "DISALLOW"
59 | },
60 | "s3PermissionsGuestUploads": {
61 | "Type": "String",
62 | "Default" : "DISALLOW" },
63 | "AuthenticatedAllowList": {
64 | "Type": "String",
65 | "Default" : "DISALLOW"
66 | },
67 | "GuestAllowList": {
68 | "Type": "String",
69 | "Default" : "DISALLOW"
70 | },
71 | "selectedGuestPermissions": {
72 | "Type": "CommaDelimitedList",
73 | "Default" : "NONE"
74 | },
75 | "selectedAuthenticatedPermissions": {
76 | "Type": "CommaDelimitedList",
77 | "Default" : "NONE"
78 | },
79 | "env": {
80 | "Type": "String"
81 | },
82 | "triggerFunction": {
83 | "Type": "String"
84 | }
85 |
86 |
87 | },
88 | "Conditions": {
89 | "ShouldNotCreateEnvResources": {
90 | "Fn::Equals": [
91 | {
92 | "Ref": "env"
93 | },
94 | "NONE"
95 | ]
96 | },
97 | "CreateAuthPublic": {
98 | "Fn::Not" : [{
99 | "Fn::Equals" : [
100 | {"Ref" : "s3PermissionsAuthenticatedPublic"},
101 | "DISALLOW"
102 | ]
103 | }]
104 | },
105 | "CreateAuthProtected": {
106 | "Fn::Not" : [{
107 | "Fn::Equals" : [
108 | {"Ref" : "s3PermissionsAuthenticatedProtected"},
109 | "DISALLOW"
110 | ]
111 | }]
112 | },
113 | "CreateAuthPrivate": {
114 | "Fn::Not" : [{
115 | "Fn::Equals" : [
116 | {"Ref" : "s3PermissionsAuthenticatedPrivate"},
117 | "DISALLOW"
118 | ]
119 | }]
120 | },
121 | "CreateAuthUploads": {
122 | "Fn::Not" : [{
123 | "Fn::Equals" : [
124 | {"Ref" : "s3PermissionsAuthenticatedUploads"},
125 | "DISALLOW"
126 | ]
127 | }]
128 | },
129 | "CreateGuestPublic": {
130 | "Fn::Not" : [{
131 | "Fn::Equals" : [
132 | {"Ref" : "s3PermissionsGuestPublic"},
133 | "DISALLOW"
134 | ]
135 | }]
136 | },
137 | "CreateGuestUploads": {
138 | "Fn::Not" : [{
139 | "Fn::Equals" : [
140 | {"Ref" : "s3PermissionsGuestUploads"},
141 | "DISALLOW"
142 | ]
143 | }]
144 | },
145 | "AuthReadAndList": {
146 | "Fn::Not" : [{
147 | "Fn::Equals" : [
148 | {"Ref" : "AuthenticatedAllowList"},
149 | "DISALLOW"
150 | ]
151 | }]
152 | },
153 | "GuestReadAndList": {
154 | "Fn::Not" : [{
155 | "Fn::Equals" : [
156 | {"Ref" : "GuestAllowList"},
157 | "DISALLOW"
158 | ]
159 | }]
160 | }
161 | },
162 | "Resources": {
163 | "S3Bucket": {
164 | "Type": "AWS::S3::Bucket",
165 |
166 | "DeletionPolicy" : "Retain",
167 | "Properties": {
168 | "BucketName": {
169 | "Fn::If": [
170 | "ShouldNotCreateEnvResources",
171 | {
172 | "Ref": "bucketName"
173 | },
174 | {
175 | "Fn::Join": [
176 | "",
177 | [
178 | {
179 | "Ref": "bucketName"
180 | },
181 | {
182 | "Fn::Select": [
183 | 3,
184 | {
185 | "Fn::Split": [
186 | "-",
187 | {
188 | "Ref": "AWS::StackName"
189 | }
190 | ]
191 | }
192 | ]
193 | },
194 | "-",
195 | {
196 | "Ref": "env"
197 | }
198 | ]
199 | ]
200 | }
201 | ]
202 | },
203 |
204 | "CorsConfiguration": {
205 | "CorsRules": [
206 | {
207 | "AllowedHeaders": [
208 | "*"
209 | ],
210 | "AllowedMethods": [
211 | "GET",
212 | "HEAD",
213 | "PUT",
214 | "POST",
215 | "DELETE"
216 | ],
217 | "AllowedOrigins": [
218 | "*"
219 | ],
220 | "ExposedHeaders": [
221 | "x-amz-server-side-encryption",
222 | "x-amz-request-id",
223 | "x-amz-id-2",
224 | "ETag"
225 | ],
226 | "Id": "S3CORSRuleId1",
227 | "MaxAge": "3000"
228 | }
229 | ]
230 | }
231 | }
232 | },
233 |
234 |
235 | "S3AuthPublicPolicy": {
236 | "DependsOn": [
237 | "S3Bucket"
238 | ],
239 | "Condition": "CreateAuthPublic",
240 | "Type": "AWS::IAM::Policy",
241 | "Properties": {
242 | "PolicyName": {
243 | "Ref": "s3PublicPolicy"
244 | },
245 | "Roles": [
246 | {
247 | "Ref": "authRoleName"
248 | }
249 | ],
250 | "PolicyDocument": {
251 | "Version": "2012-10-17",
252 | "Statement": [
253 | {
254 | "Effect": "Allow",
255 | "Action": {
256 | "Fn::Split" : [ "," , {
257 | "Ref": "s3PermissionsAuthenticatedPublic"
258 | } ]
259 | },
260 | "Resource": [
261 | {
262 | "Fn::Join": [
263 | "",
264 | [
265 | "arn:aws:s3:::",
266 | {
267 | "Ref": "S3Bucket"
268 | },
269 | "/public/*"
270 | ]
271 | ]
272 | }
273 | ]
274 | }
275 | ]
276 | }
277 | }
278 | },
279 | "S3AuthProtectedPolicy": {
280 | "DependsOn": [
281 | "S3Bucket"
282 | ],
283 | "Condition": "CreateAuthProtected",
284 | "Type": "AWS::IAM::Policy",
285 | "Properties": {
286 | "PolicyName": {
287 | "Ref": "s3ProtectedPolicy"
288 | },
289 | "Roles": [
290 | {
291 | "Ref": "authRoleName"
292 | }
293 | ],
294 | "PolicyDocument": {
295 | "Version": "2012-10-17",
296 | "Statement": [
297 | {
298 | "Effect": "Allow",
299 | "Action": {
300 | "Fn::Split" : [ "," , {
301 | "Ref": "s3PermissionsAuthenticatedProtected"
302 | } ]
303 | },
304 | "Resource": [
305 | {
306 | "Fn::Join": [
307 | "",
308 | [
309 | "arn:aws:s3:::",
310 | {
311 | "Ref": "S3Bucket"
312 | },
313 | "/protected/${cognito-identity.amazonaws.com:sub}/*"
314 | ]
315 | ]
316 | }
317 | ]
318 | }
319 | ]
320 | }
321 | }
322 | },
323 | "S3AuthPrivatePolicy": {
324 | "DependsOn": [
325 | "S3Bucket"
326 | ],
327 | "Condition": "CreateAuthPrivate",
328 | "Type": "AWS::IAM::Policy",
329 | "Properties": {
330 | "PolicyName": {
331 | "Ref": "s3PrivatePolicy"
332 | },
333 | "Roles": [
334 | {
335 | "Ref": "authRoleName"
336 | }
337 | ],
338 | "PolicyDocument": {
339 | "Version": "2012-10-17",
340 | "Statement": [
341 | {
342 | "Effect": "Allow",
343 | "Action": {
344 | "Fn::Split" : [ "," , {
345 | "Ref": "s3PermissionsAuthenticatedPrivate"
346 | } ]
347 | },
348 | "Resource": [
349 | {
350 | "Fn::Join": [
351 | "",
352 | [
353 | "arn:aws:s3:::",
354 | {
355 | "Ref": "S3Bucket"
356 | },
357 | "/private/${cognito-identity.amazonaws.com:sub}/*"
358 | ]
359 | ]
360 | }
361 | ]
362 | }
363 | ]
364 | }
365 | }
366 | },
367 | "S3AuthUploadPolicy": {
368 | "DependsOn": [
369 | "S3Bucket"
370 | ],
371 | "Condition": "CreateAuthUploads",
372 | "Type": "AWS::IAM::Policy",
373 | "Properties": {
374 | "PolicyName": {
375 | "Ref": "s3UploadsPolicy"
376 | },
377 | "Roles": [
378 | {
379 | "Ref": "authRoleName"
380 | }
381 | ],
382 | "PolicyDocument": {
383 | "Version": "2012-10-17",
384 | "Statement": [
385 | {
386 | "Effect": "Allow",
387 | "Action": {
388 | "Fn::Split" : [ "," , {
389 | "Ref": "s3PermissionsAuthenticatedUploads"
390 | } ]
391 | },
392 | "Resource": [
393 | {
394 | "Fn::Join": [
395 | "",
396 | [
397 | "arn:aws:s3:::",
398 | {
399 | "Ref": "S3Bucket"
400 | },
401 | "/uploads/*"
402 | ]
403 | ]
404 | }
405 | ]
406 | }
407 | ]
408 | }
409 | }
410 | },
411 | "S3AuthReadPolicy": {
412 | "DependsOn": [
413 | "S3Bucket"
414 | ],
415 | "Condition": "AuthReadAndList",
416 | "Type": "AWS::IAM::Policy",
417 | "Properties": {
418 | "PolicyName": {
419 | "Ref": "s3ReadPolicy"
420 | },
421 | "Roles": [
422 | {
423 | "Ref": "authRoleName"
424 | }
425 | ],
426 | "PolicyDocument": {
427 | "Version": "2012-10-17",
428 | "Statement": [
429 | {
430 | "Effect": "Allow",
431 | "Action": [
432 | "s3:GetObject"
433 | ],
434 | "Resource": [
435 | {
436 | "Fn::Join": [
437 | "",
438 | [
439 | "arn:aws:s3:::",
440 | {
441 | "Ref": "S3Bucket"
442 | },
443 | "/protected/*"
444 | ]
445 | ]
446 | }
447 | ]
448 | },
449 | {
450 | "Effect": "Allow",
451 | "Action": [
452 | "s3:ListBucket"
453 | ],
454 | "Resource": [
455 | {
456 | "Fn::Join": [
457 | "",
458 | [
459 | "arn:aws:s3:::",
460 | {
461 | "Ref": "S3Bucket"
462 | }
463 | ]
464 | ]
465 | }
466 | ],
467 | "Condition": {
468 | "StringLike": {
469 | "s3:prefix": [
470 | "public/",
471 | "public/*",
472 | "protected/",
473 | "protected/*",
474 | "private/${cognito-identity.amazonaws.com:sub}/",
475 | "private/${cognito-identity.amazonaws.com:sub}/*"
476 | ]
477 | }
478 | }
479 | }
480 | ]
481 | }
482 | }
483 | },
484 | "S3GuestPublicPolicy": {
485 | "DependsOn": [
486 | "S3Bucket"
487 | ],
488 | "Condition": "CreateGuestPublic",
489 | "Type": "AWS::IAM::Policy",
490 | "Properties": {
491 | "PolicyName": {
492 | "Ref": "s3PublicPolicy"
493 | },
494 | "Roles": [
495 | {
496 | "Ref": "unauthRoleName"
497 | }
498 | ],
499 | "PolicyDocument": {
500 | "Version": "2012-10-17",
501 | "Statement": [
502 | {
503 | "Effect": "Allow",
504 | "Action": {
505 | "Fn::Split" : [ "," , {
506 | "Ref": "s3PermissionsGuestPublic"
507 | } ]
508 | },
509 | "Resource": [
510 | {
511 | "Fn::Join": [
512 | "",
513 | [
514 | "arn:aws:s3:::",
515 | {
516 | "Ref": "S3Bucket"
517 | },
518 | "/public/*"
519 | ]
520 | ]
521 | }
522 | ]
523 | }
524 | ]
525 | }
526 | }
527 | },
528 | "S3GuestUploadPolicy": {
529 | "DependsOn": [
530 | "S3Bucket"
531 | ],
532 | "Condition": "CreateGuestUploads",
533 | "Type": "AWS::IAM::Policy",
534 | "Properties": {
535 | "PolicyName": {
536 | "Ref": "s3UploadsPolicy"
537 | },
538 | "Roles": [
539 | {
540 | "Ref": "unauthRoleName"
541 | }
542 | ],
543 | "PolicyDocument": {
544 | "Version": "2012-10-17",
545 | "Statement": [
546 | {
547 | "Effect": "Allow",
548 | "Action": {
549 | "Fn::Split" : [ "," , {
550 | "Ref": "s3PermissionsGuestUploads"
551 | } ]
552 | },
553 | "Resource": [
554 | {
555 | "Fn::Join": [
556 | "",
557 | [
558 | "arn:aws:s3:::",
559 | {
560 | "Ref": "S3Bucket"
561 | },
562 | "/uploads/*"
563 | ]
564 | ]
565 | }
566 | ]
567 | }
568 | ]
569 | }
570 | }
571 | },
572 | "S3GuestReadPolicy": {
573 | "DependsOn": [
574 | "S3Bucket"
575 | ],
576 | "Condition": "GuestReadAndList",
577 | "Type": "AWS::IAM::Policy",
578 | "Properties": {
579 | "PolicyName": {
580 | "Ref": "s3ReadPolicy"
581 | },
582 | "Roles": [
583 | {
584 | "Ref": "unauthRoleName"
585 | }
586 | ],
587 | "PolicyDocument": {
588 | "Version": "2012-10-17",
589 | "Statement": [
590 | {
591 | "Effect": "Allow",
592 | "Action": [
593 | "s3:GetObject"
594 | ],
595 | "Resource": [
596 | {
597 | "Fn::Join": [
598 | "",
599 | [
600 | "arn:aws:s3:::",
601 | {
602 | "Ref": "S3Bucket"
603 | },
604 | "/protected/*"
605 | ]
606 | ]
607 | }
608 | ]
609 | },
610 | {
611 | "Effect": "Allow",
612 | "Action": [
613 | "s3:ListBucket"
614 | ],
615 | "Resource": [
616 | {
617 | "Fn::Join": [
618 | "",
619 | [
620 | "arn:aws:s3:::",
621 | {
622 | "Ref": "S3Bucket"
623 | }
624 | ]
625 | ]
626 | }
627 | ],
628 | "Condition": {
629 | "StringLike": {
630 | "s3:prefix": [
631 | "public/",
632 | "public/*",
633 | "protected/",
634 | "protected/*"
635 | ]
636 | }
637 | }
638 | }
639 | ]
640 | }
641 | }
642 | }
643 | },
644 | "Outputs": {
645 | "BucketName": {
646 | "Value": {
647 | "Ref": "S3Bucket"
648 | },
649 | "Description": "Bucket name for the S3 bucket"
650 | },
651 | "Region": {
652 | "Value": {
653 | "Ref": "AWS::Region"
654 | }
655 | }
656 | }
657 | }
658 |
--------------------------------------------------------------------------------
/amplify/#current-cloud-backend/storage/S3chopperthao/s3-cloudformation-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "S3 resource stack creation using Amplify CLI",
4 | "Parameters": {
5 | "bucketName": {
6 | "Type": "String"
7 | },
8 | "authPolicyName": {
9 | "Type": "String"
10 | },
11 | "unauthPolicyName": {
12 | "Type": "String"
13 | },
14 | "authRoleName": {
15 | "Type": "String"
16 | },
17 | "unauthRoleName": {
18 | "Type": "String"
19 | },
20 | "s3PublicPolicy": {
21 | "Type": "String",
22 | "Default" : "NONE"
23 | },
24 | "s3PrivatePolicy": {
25 | "Type": "String",
26 | "Default" : "NONE"
27 | },
28 | "s3ProtectedPolicy": {
29 | "Type": "String",
30 | "Default" : "NONE"
31 | },
32 | "s3UploadsPolicy": {
33 | "Type": "String",
34 | "Default" : "NONE"
35 | },
36 | "s3ReadPolicy": {
37 | "Type": "String",
38 | "Default" : "NONE"
39 | },
40 | "s3PermissionsAuthenticatedPublic": {
41 | "Type": "String",
42 | "Default" : "DISALLOW"
43 | },
44 | "s3PermissionsAuthenticatedProtected": {
45 | "Type": "String",
46 | "Default" : "DISALLOW"
47 | },
48 | "s3PermissionsAuthenticatedPrivate": {
49 | "Type": "String",
50 | "Default" : "DISALLOW"
51 | },
52 | "s3PermissionsAuthenticatedUploads": {
53 | "Type": "String",
54 | "Default" : "DISALLOW"
55 | },
56 | "s3PermissionsGuestPublic": {
57 | "Type": "String",
58 | "Default" : "DISALLOW"
59 | },
60 | "s3PermissionsGuestUploads": {
61 | "Type": "String",
62 | "Default" : "DISALLOW" },
63 | "AuthenticatedAllowList": {
64 | "Type": "String",
65 | "Default" : "DISALLOW"
66 | },
67 | "GuestAllowList": {
68 | "Type": "String",
69 | "Default" : "DISALLOW"
70 | },
71 | "selectedGuestPermissions": {
72 | "Type": "CommaDelimitedList",
73 | "Default" : "NONE"
74 | },
75 | "selectedAuthenticatedPermissions": {
76 | "Type": "CommaDelimitedList",
77 | "Default" : "NONE"
78 | },
79 | "env": {
80 | "Type": "String"
81 | },
82 | "triggerFunction": {
83 | "Type": "String"
84 | }
85 |
86 |
87 | },
88 | "Conditions": {
89 | "ShouldNotCreateEnvResources": {
90 | "Fn::Equals": [
91 | {
92 | "Ref": "env"
93 | },
94 | "NONE"
95 | ]
96 | },
97 | "CreateAuthPublic": {
98 | "Fn::Not" : [{
99 | "Fn::Equals" : [
100 | {"Ref" : "s3PermissionsAuthenticatedPublic"},
101 | "DISALLOW"
102 | ]
103 | }]
104 | },
105 | "CreateAuthProtected": {
106 | "Fn::Not" : [{
107 | "Fn::Equals" : [
108 | {"Ref" : "s3PermissionsAuthenticatedProtected"},
109 | "DISALLOW"
110 | ]
111 | }]
112 | },
113 | "CreateAuthPrivate": {
114 | "Fn::Not" : [{
115 | "Fn::Equals" : [
116 | {"Ref" : "s3PermissionsAuthenticatedPrivate"},
117 | "DISALLOW"
118 | ]
119 | }]
120 | },
121 | "CreateAuthUploads": {
122 | "Fn::Not" : [{
123 | "Fn::Equals" : [
124 | {"Ref" : "s3PermissionsAuthenticatedUploads"},
125 | "DISALLOW"
126 | ]
127 | }]
128 | },
129 | "CreateGuestPublic": {
130 | "Fn::Not" : [{
131 | "Fn::Equals" : [
132 | {"Ref" : "s3PermissionsGuestPublic"},
133 | "DISALLOW"
134 | ]
135 | }]
136 | },
137 | "CreateGuestUploads": {
138 | "Fn::Not" : [{
139 | "Fn::Equals" : [
140 | {"Ref" : "s3PermissionsGuestUploads"},
141 | "DISALLOW"
142 | ]
143 | }]
144 | },
145 | "AuthReadAndList": {
146 | "Fn::Not" : [{
147 | "Fn::Equals" : [
148 | {"Ref" : "AuthenticatedAllowList"},
149 | "DISALLOW"
150 | ]
151 | }]
152 | },
153 | "GuestReadAndList": {
154 | "Fn::Not" : [{
155 | "Fn::Equals" : [
156 | {"Ref" : "GuestAllowList"},
157 | "DISALLOW"
158 | ]
159 | }]
160 | }
161 | },
162 | "Resources": {
163 | "S3Bucket": {
164 | "Type": "AWS::S3::Bucket",
165 |
166 | "DeletionPolicy" : "Retain",
167 | "Properties": {
168 | "BucketName": {
169 | "Fn::If": [
170 | "ShouldNotCreateEnvResources",
171 | {
172 | "Ref": "bucketName"
173 | },
174 | {
175 | "Fn::Join": [
176 | "",
177 | [
178 | {
179 | "Ref": "bucketName"
180 | },
181 | {
182 | "Fn::Select": [
183 | 3,
184 | {
185 | "Fn::Split": [
186 | "-",
187 | {
188 | "Ref": "AWS::StackName"
189 | }
190 | ]
191 | }
192 | ]
193 | },
194 | "-",
195 | {
196 | "Ref": "env"
197 | }
198 | ]
199 | ]
200 | }
201 | ]
202 | },
203 |
204 | "CorsConfiguration": {
205 | "CorsRules": [
206 | {
207 | "AllowedHeaders": [
208 | "*"
209 | ],
210 | "AllowedMethods": [
211 | "GET",
212 | "HEAD",
213 | "PUT",
214 | "POST",
215 | "DELETE"
216 | ],
217 | "AllowedOrigins": [
218 | "*"
219 | ],
220 | "ExposedHeaders": [
221 | "x-amz-server-side-encryption",
222 | "x-amz-request-id",
223 | "x-amz-id-2",
224 | "ETag"
225 | ],
226 | "Id": "S3CORSRuleId1",
227 | "MaxAge": "3000"
228 | }
229 | ]
230 | }
231 | }
232 | },
233 |
234 |
235 | "S3AuthPublicPolicy": {
236 | "DependsOn": [
237 | "S3Bucket"
238 | ],
239 | "Condition": "CreateAuthPublic",
240 | "Type": "AWS::IAM::Policy",
241 | "Properties": {
242 | "PolicyName": {
243 | "Ref": "s3PublicPolicy"
244 | },
245 | "Roles": [
246 | {
247 | "Ref": "authRoleName"
248 | }
249 | ],
250 | "PolicyDocument": {
251 | "Version": "2012-10-17",
252 | "Statement": [
253 | {
254 | "Effect": "Allow",
255 | "Action": {
256 | "Fn::Split" : [ "," , {
257 | "Ref": "s3PermissionsAuthenticatedPublic"
258 | } ]
259 | },
260 | "Resource": [
261 | {
262 | "Fn::Join": [
263 | "",
264 | [
265 | "arn:aws:s3:::",
266 | {
267 | "Ref": "S3Bucket"
268 | },
269 | "/public/*"
270 | ]
271 | ]
272 | }
273 | ]
274 | }
275 | ]
276 | }
277 | }
278 | },
279 | "S3AuthProtectedPolicy": {
280 | "DependsOn": [
281 | "S3Bucket"
282 | ],
283 | "Condition": "CreateAuthProtected",
284 | "Type": "AWS::IAM::Policy",
285 | "Properties": {
286 | "PolicyName": {
287 | "Ref": "s3ProtectedPolicy"
288 | },
289 | "Roles": [
290 | {
291 | "Ref": "authRoleName"
292 | }
293 | ],
294 | "PolicyDocument": {
295 | "Version": "2012-10-17",
296 | "Statement": [
297 | {
298 | "Effect": "Allow",
299 | "Action": {
300 | "Fn::Split" : [ "," , {
301 | "Ref": "s3PermissionsAuthenticatedProtected"
302 | } ]
303 | },
304 | "Resource": [
305 | {
306 | "Fn::Join": [
307 | "",
308 | [
309 | "arn:aws:s3:::",
310 | {
311 | "Ref": "S3Bucket"
312 | },
313 | "/protected/${cognito-identity.amazonaws.com:sub}/*"
314 | ]
315 | ]
316 | }
317 | ]
318 | }
319 | ]
320 | }
321 | }
322 | },
323 | "S3AuthPrivatePolicy": {
324 | "DependsOn": [
325 | "S3Bucket"
326 | ],
327 | "Condition": "CreateAuthPrivate",
328 | "Type": "AWS::IAM::Policy",
329 | "Properties": {
330 | "PolicyName": {
331 | "Ref": "s3PrivatePolicy"
332 | },
333 | "Roles": [
334 | {
335 | "Ref": "authRoleName"
336 | }
337 | ],
338 | "PolicyDocument": {
339 | "Version": "2012-10-17",
340 | "Statement": [
341 | {
342 | "Effect": "Allow",
343 | "Action": {
344 | "Fn::Split" : [ "," , {
345 | "Ref": "s3PermissionsAuthenticatedPrivate"
346 | } ]
347 | },
348 | "Resource": [
349 | {
350 | "Fn::Join": [
351 | "",
352 | [
353 | "arn:aws:s3:::",
354 | {
355 | "Ref": "S3Bucket"
356 | },
357 | "/private/${cognito-identity.amazonaws.com:sub}/*"
358 | ]
359 | ]
360 | }
361 | ]
362 | }
363 | ]
364 | }
365 | }
366 | },
367 | "S3AuthUploadPolicy": {
368 | "DependsOn": [
369 | "S3Bucket"
370 | ],
371 | "Condition": "CreateAuthUploads",
372 | "Type": "AWS::IAM::Policy",
373 | "Properties": {
374 | "PolicyName": {
375 | "Ref": "s3UploadsPolicy"
376 | },
377 | "Roles": [
378 | {
379 | "Ref": "authRoleName"
380 | }
381 | ],
382 | "PolicyDocument": {
383 | "Version": "2012-10-17",
384 | "Statement": [
385 | {
386 | "Effect": "Allow",
387 | "Action": {
388 | "Fn::Split" : [ "," , {
389 | "Ref": "s3PermissionsAuthenticatedUploads"
390 | } ]
391 | },
392 | "Resource": [
393 | {
394 | "Fn::Join": [
395 | "",
396 | [
397 | "arn:aws:s3:::",
398 | {
399 | "Ref": "S3Bucket"
400 | },
401 | "/uploads/*"
402 | ]
403 | ]
404 | }
405 | ]
406 | }
407 | ]
408 | }
409 | }
410 | },
411 | "S3AuthReadPolicy": {
412 | "DependsOn": [
413 | "S3Bucket"
414 | ],
415 | "Condition": "AuthReadAndList",
416 | "Type": "AWS::IAM::Policy",
417 | "Properties": {
418 | "PolicyName": {
419 | "Ref": "s3ReadPolicy"
420 | },
421 | "Roles": [
422 | {
423 | "Ref": "authRoleName"
424 | }
425 | ],
426 | "PolicyDocument": {
427 | "Version": "2012-10-17",
428 | "Statement": [
429 | {
430 | "Effect": "Allow",
431 | "Action": [
432 | "s3:GetObject"
433 | ],
434 | "Resource": [
435 | {
436 | "Fn::Join": [
437 | "",
438 | [
439 | "arn:aws:s3:::",
440 | {
441 | "Ref": "S3Bucket"
442 | },
443 | "/protected/*"
444 | ]
445 | ]
446 | }
447 | ]
448 | },
449 | {
450 | "Effect": "Allow",
451 | "Action": [
452 | "s3:ListBucket"
453 | ],
454 | "Resource": [
455 | {
456 | "Fn::Join": [
457 | "",
458 | [
459 | "arn:aws:s3:::",
460 | {
461 | "Ref": "S3Bucket"
462 | }
463 | ]
464 | ]
465 | }
466 | ],
467 | "Condition": {
468 | "StringLike": {
469 | "s3:prefix": [
470 | "public/",
471 | "public/*",
472 | "protected/",
473 | "protected/*",
474 | "private/${cognito-identity.amazonaws.com:sub}/",
475 | "private/${cognito-identity.amazonaws.com:sub}/*"
476 | ]
477 | }
478 | }
479 | }
480 | ]
481 | }
482 | }
483 | },
484 | "S3GuestPublicPolicy": {
485 | "DependsOn": [
486 | "S3Bucket"
487 | ],
488 | "Condition": "CreateGuestPublic",
489 | "Type": "AWS::IAM::Policy",
490 | "Properties": {
491 | "PolicyName": {
492 | "Ref": "s3PublicPolicy"
493 | },
494 | "Roles": [
495 | {
496 | "Ref": "unauthRoleName"
497 | }
498 | ],
499 | "PolicyDocument": {
500 | "Version": "2012-10-17",
501 | "Statement": [
502 | {
503 | "Effect": "Allow",
504 | "Action": {
505 | "Fn::Split" : [ "," , {
506 | "Ref": "s3PermissionsGuestPublic"
507 | } ]
508 | },
509 | "Resource": [
510 | {
511 | "Fn::Join": [
512 | "",
513 | [
514 | "arn:aws:s3:::",
515 | {
516 | "Ref": "S3Bucket"
517 | },
518 | "/public/*"
519 | ]
520 | ]
521 | }
522 | ]
523 | }
524 | ]
525 | }
526 | }
527 | },
528 | "S3GuestUploadPolicy": {
529 | "DependsOn": [
530 | "S3Bucket"
531 | ],
532 | "Condition": "CreateGuestUploads",
533 | "Type": "AWS::IAM::Policy",
534 | "Properties": {
535 | "PolicyName": {
536 | "Ref": "s3UploadsPolicy"
537 | },
538 | "Roles": [
539 | {
540 | "Ref": "unauthRoleName"
541 | }
542 | ],
543 | "PolicyDocument": {
544 | "Version": "2012-10-17",
545 | "Statement": [
546 | {
547 | "Effect": "Allow",
548 | "Action": {
549 | "Fn::Split" : [ "," , {
550 | "Ref": "s3PermissionsGuestUploads"
551 | } ]
552 | },
553 | "Resource": [
554 | {
555 | "Fn::Join": [
556 | "",
557 | [
558 | "arn:aws:s3:::",
559 | {
560 | "Ref": "S3Bucket"
561 | },
562 | "/uploads/*"
563 | ]
564 | ]
565 | }
566 | ]
567 | }
568 | ]
569 | }
570 | }
571 | },
572 | "S3GuestReadPolicy": {
573 | "DependsOn": [
574 | "S3Bucket"
575 | ],
576 | "Condition": "GuestReadAndList",
577 | "Type": "AWS::IAM::Policy",
578 | "Properties": {
579 | "PolicyName": {
580 | "Ref": "s3ReadPolicy"
581 | },
582 | "Roles": [
583 | {
584 | "Ref": "unauthRoleName"
585 | }
586 | ],
587 | "PolicyDocument": {
588 | "Version": "2012-10-17",
589 | "Statement": [
590 | {
591 | "Effect": "Allow",
592 | "Action": [
593 | "s3:GetObject"
594 | ],
595 | "Resource": [
596 | {
597 | "Fn::Join": [
598 | "",
599 | [
600 | "arn:aws:s3:::",
601 | {
602 | "Ref": "S3Bucket"
603 | },
604 | "/protected/*"
605 | ]
606 | ]
607 | }
608 | ]
609 | },
610 | {
611 | "Effect": "Allow",
612 | "Action": [
613 | "s3:ListBucket"
614 | ],
615 | "Resource": [
616 | {
617 | "Fn::Join": [
618 | "",
619 | [
620 | "arn:aws:s3:::",
621 | {
622 | "Ref": "S3Bucket"
623 | }
624 | ]
625 | ]
626 | }
627 | ],
628 | "Condition": {
629 | "StringLike": {
630 | "s3:prefix": [
631 | "public/",
632 | "public/*",
633 | "protected/",
634 | "protected/*"
635 | ]
636 | }
637 | }
638 | }
639 | ]
640 | }
641 | }
642 | }
643 | },
644 | "Outputs": {
645 | "BucketName": {
646 | "Value": {
647 | "Ref": "S3Bucket"
648 | },
649 | "Description": "Bucket name for the S3 bucket"
650 | },
651 | "Region": {
652 | "Value": {
653 | "Ref": "AWS::Region"
654 | }
655 | }
656 | }
657 | }
658 |
--------------------------------------------------------------------------------
/amplify/backend/awscloudformation/nested-cloudformation-stack.yml:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "Root Stack for AWS Amplify Console",
4 | "Parameters": {
5 | "DeploymentBucketName": {
6 | "Description": "Name of the common deployment bucket provided by the parent stack",
7 | "Type": "String",
8 | "Default": "DeploymentBucket"
9 | },
10 | "AuthRoleName": {
11 | "Type": "String",
12 | "Default": "AuthRoleName"
13 | },
14 | "UnauthRoleName": {
15 | "Type": "String",
16 | "Default": "UnauthRoleName"
17 | }
18 | },
19 | "Resources": {
20 | "DeploymentBucket": {
21 | "Type": "AWS::S3::Bucket",
22 | "DeletionPolicy": "Retain",
23 | "Properties": {
24 | "BucketName": {
25 | "Ref": "DeploymentBucketName"
26 | }
27 | }
28 | },
29 | "AuthRole": {
30 | "Type": "AWS::IAM::Role",
31 | "Properties": {
32 | "RoleName": {
33 | "Ref": "AuthRoleName"
34 | },
35 | "AssumeRolePolicyDocument": {
36 | "Version": "2012-10-17",
37 | "Statement": [
38 | {
39 | "Sid": "",
40 | "Effect": "Deny",
41 | "Principal": {
42 | "Federated": "cognito-identity.amazonaws.com"
43 | },
44 | "Action": "sts:AssumeRoleWithWebIdentity"
45 | }
46 | ]
47 | }
48 | }
49 | },
50 | "UnauthRole": {
51 | "Type": "AWS::IAM::Role",
52 | "Properties": {
53 | "RoleName": {
54 | "Ref": "UnauthRoleName"
55 | },
56 | "AssumeRolePolicyDocument": {
57 | "Version": "2012-10-17",
58 | "Statement": [
59 | {
60 | "Sid": "",
61 | "Effect": "Deny",
62 | "Principal": {
63 | "Federated": "cognito-identity.amazonaws.com"
64 | },
65 | "Action": "sts:AssumeRoleWithWebIdentity"
66 | }
67 | ]
68 | }
69 | }
70 | },
71 | "authcloudchopperd20aa567": {
72 | "Type": "AWS::CloudFormation::Stack",
73 | "Properties": {
74 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/auth/cloudchopperd20aa567-cloudformation-template.yml",
75 | "Parameters": {
76 | "identityPoolName": "cloudchopperd20aa567_identitypool_d20aa567",
77 | "allowUnauthenticatedIdentities": true,
78 | "resourceNameTruncated": "cloudcd20aa567",
79 | "userPoolName": "cloudchopperd20aa567_userpool_d20aa567",
80 | "autoVerifiedAttributes": "email",
81 | "mfaConfiguration": "OFF",
82 | "mfaTypes": "SMS Text Message",
83 | "smsAuthenticationMessage": "Your authentication code is {####}",
84 | "smsVerificationMessage": "Your verification code is {####}",
85 | "emailVerificationSubject": "Your verification code",
86 | "emailVerificationMessage": "Your verification code is {####}",
87 | "defaultPasswordPolicy": false,
88 | "passwordPolicyMinLength": 8,
89 | "passwordPolicyCharacters": "",
90 | "requiredAttributes": "email",
91 | "userpoolClientGenerateSecret": false,
92 | "userpoolClientRefreshTokenValidity": 30,
93 | "userpoolClientWriteAttributes": "email",
94 | "userpoolClientReadAttributes": "email",
95 | "userpoolClientLambdaRole": "cloudcd20aa567_userpoolclient_lambda_role",
96 | "userpoolClientSetAttributes": false,
97 | "sharedId": "d20aa567",
98 | "resourceName": "cloudchopperd20aa567",
99 | "authSelections": "identityPoolAndUserPool",
100 | "authRoleArn": {
101 | "Fn::GetAtt": [
102 | "AuthRole",
103 | "Arn"
104 | ]
105 | },
106 | "unauthRoleArn": {
107 | "Fn::GetAtt": [
108 | "UnauthRole",
109 | "Arn"
110 | ]
111 | },
112 | "useDefault": "default",
113 | "userPoolGroupList": "",
114 | "serviceName": "Cognito",
115 | "usernameCaseSensitive": false,
116 | "dependsOn": "",
117 | "env": "dev"
118 | }
119 | }
120 | },
121 | "storageS3chopperthao": {
122 | "Type": "AWS::CloudFormation::Stack",
123 | "Properties": {
124 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/storage/s3-cloudformation-template.json",
125 | "Parameters": {
126 | "bucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414",
127 | "authPolicyName": "s3_amplify_899f92fa",
128 | "unauthPolicyName": "s3_amplify_899f92fa",
129 | "authRoleName": {
130 | "Ref": "AuthRoleName"
131 | },
132 | "unauthRoleName": {
133 | "Ref": "UnauthRoleName"
134 | },
135 | "selectedGuestPermissions": "s3:PutObject,s3:GetObject,s3:ListBucket,s3:DeleteObject",
136 | "selectedAuthenticatedPermissions": "s3:PutObject,s3:GetObject,s3:ListBucket,s3:DeleteObject",
137 | "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
138 | "s3PublicPolicy": "Public_policy_7d6cabc6",
139 | "s3PermissionsAuthenticatedUploads": "s3:PutObject",
140 | "s3UploadsPolicy": "Uploads_policy_7d6cabc6",
141 | "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
142 | "s3ProtectedPolicy": "Protected_policy_5e148ded",
143 | "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
144 | "s3PrivatePolicy": "Private_policy_5e148ded",
145 | "AuthenticatedAllowList": "ALLOW",
146 | "s3ReadPolicy": "read_policy_7d6cabc6",
147 | "s3PermissionsGuestPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
148 | "s3PermissionsGuestUploads": "s3:PutObject",
149 | "GuestAllowList": "ALLOW",
150 | "triggerFunction": "NONE",
151 | "env": "dev"
152 | }
153 | }
154 | },
155 | "analyticscloudchopper": {
156 | "Type": "AWS::CloudFormation::Stack",
157 | "Properties": {
158 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/analytics/pinpoint-cloudformation-template.json",
159 | "Parameters": {
160 | "appName": "cloudchopper",
161 | "roleName": "pinpointLambdaRoleaaf79265",
162 | "cloudformationPolicyName": "cloudformationPolicyaaf79265",
163 | "cloudWatchPolicyName": "cloudWatchPolicyaaf79265",
164 | "pinpointPolicyName": "pinpointPolicyaaf79265",
165 | "authPolicyName": "pinpoint_amplify_aaf79265",
166 | "unauthPolicyName": "pinpoint_amplify_aaf79265",
167 | "authRoleName": {
168 | "Ref": "AuthRoleName"
169 | },
170 | "unauthRoleName": {
171 | "Ref": "UnauthRoleName"
172 | },
173 | "authRoleArn": {
174 | "Fn::GetAtt": [
175 | "AuthRole",
176 | "Arn"
177 | ]
178 | },
179 | "env": "dev"
180 | }
181 | }
182 | },
183 | "UpdateRolesWithIDPFunction": {
184 | "DependsOn": [
185 | "AuthRole",
186 | "UnauthRole",
187 | "authcloudchopperd20aa567"
188 | ],
189 | "Type": "AWS::Lambda::Function",
190 | "Properties": {
191 | "Code": {
192 | "ZipFile": {
193 | "Fn::Join": [
194 | "\n",
195 | [
196 | "const response = require('cfn-response');",
197 | "const aws = require('aws-sdk');",
198 | "let responseData = {};",
199 | "exports.handler = function(event, context) {",
200 | " try {",
201 | " let authRoleName = event.ResourceProperties.authRoleName;",
202 | " let unauthRoleName = event.ResourceProperties.unauthRoleName;",
203 | " let idpId = event.ResourceProperties.idpId;",
204 | " let promises = [];",
205 | " let authParamsJson = { 'Version': '2012-10-17','Statement': [{'Effect': 'Allow','Principal': {'Federated': 'cognito-identity.amazonaws.com'},'Action': 'sts:AssumeRoleWithWebIdentity','Condition': {'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'authenticated'}}}]};",
206 | " let unauthParamsJson = { 'Version': '2012-10-17','Statement': [{'Effect': 'Allow','Principal': {'Federated': 'cognito-identity.amazonaws.com'},'Action': 'sts:AssumeRoleWithWebIdentity','Condition': {'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'unauthenticated'}}}]};",
207 | " if (event.RequestType == 'Delete') {",
208 | " delete authParamsJson.Statement[0].Condition;",
209 | " delete unauthParamsJson.Statement[0].Condition;",
210 | " let authParams = { PolicyDocument: JSON.stringify(authParamsJson),RoleName: authRoleName};",
211 | " let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson),RoleName: unauthRoleName};",
212 | " const iam = new aws.IAM({ apiVersion: '2010-05-08', region: event.ResourceProperties.region});",
213 | " promises.push(iam.updateAssumeRolePolicy(authParams).promise());",
214 | " promises.push(iam.updateAssumeRolePolicy(unauthParams).promise());",
215 | " Promise.all(promises)",
216 | " .then((res) => {",
217 | " console.log(\"delete response data\" + JSON.stringify(res));",
218 | " response.send(event, context, response.SUCCESS, {});",
219 | " });",
220 | " }",
221 | " if (event.RequestType == 'Update' || event.RequestType == 'Create') {",
222 | " const iam = new aws.IAM({ apiVersion: '2010-05-08', region: event.ResourceProperties.region});",
223 | " let authParams = { PolicyDocument: JSON.stringify(authParamsJson),RoleName: authRoleName};",
224 | " let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson),RoleName: unauthRoleName};",
225 | " promises.push(iam.updateAssumeRolePolicy(authParams).promise());",
226 | " promises.push(iam.updateAssumeRolePolicy(unauthParams).promise());",
227 | " Promise.all(promises)",
228 | " .then((res) => {",
229 | " console.log(\"createORupdate\" + res);",
230 | " console.log(\"response data\" + JSON.stringify(res));",
231 | " response.send(event, context, response.SUCCESS, {});",
232 | " });",
233 | " }",
234 | " } catch(err) {",
235 | " console.log(err.stack);",
236 | " responseData = {Error: err};",
237 | " response.send(event, context, response.FAILED, responseData);",
238 | " throw err;",
239 | " }",
240 | "};"
241 | ]
242 | ]
243 | }
244 | },
245 | "Handler": "index.handler",
246 | "Runtime": "nodejs12.x",
247 | "Timeout": "300",
248 | "Role": {
249 | "Fn::GetAtt": [
250 | "UpdateRolesWithIDPFunctionRole",
251 | "Arn"
252 | ]
253 | }
254 | }
255 | },
256 | "UpdateRolesWithIDPFunctionOutputs": {
257 | "Type": "Custom::LambdaCallout",
258 | "Properties": {
259 | "ServiceToken": {
260 | "Fn::GetAtt": [
261 | "UpdateRolesWithIDPFunction",
262 | "Arn"
263 | ]
264 | },
265 | "region": {
266 | "Ref": "AWS::Region"
267 | },
268 | "idpId": {
269 | "Fn::GetAtt": [
270 | "authcloudchopperd20aa567",
271 | "Outputs.IdentityPoolId"
272 | ]
273 | },
274 | "authRoleName": {
275 | "Ref": "AuthRoleName"
276 | },
277 | "unauthRoleName": {
278 | "Ref": "UnauthRoleName"
279 | }
280 | }
281 | },
282 | "UpdateRolesWithIDPFunctionRole": {
283 | "Type": "AWS::IAM::Role",
284 | "Properties": {
285 | "RoleName": {
286 | "Fn::Join": [
287 | "",
288 | [
289 | {
290 | "Ref": "AuthRoleName"
291 | },
292 | "-idp"
293 | ]
294 | ]
295 | },
296 | "AssumeRolePolicyDocument": {
297 | "Version": "2012-10-17",
298 | "Statement": [
299 | {
300 | "Effect": "Allow",
301 | "Principal": {
302 | "Service": [
303 | "lambda.amazonaws.com"
304 | ]
305 | },
306 | "Action": [
307 | "sts:AssumeRole"
308 | ]
309 | }
310 | ]
311 | },
312 | "Policies": [
313 | {
314 | "PolicyName": "UpdateRolesWithIDPFunctionPolicy",
315 | "PolicyDocument": {
316 | "Version": "2012-10-17",
317 | "Statement": [
318 | {
319 | "Effect": "Allow",
320 | "Action": [
321 | "logs:CreateLogGroup",
322 | "logs:CreateLogStream",
323 | "logs:PutLogEvents"
324 | ],
325 | "Resource": "arn:aws:logs:*:*:*"
326 | },
327 | {
328 | "Effect": "Allow",
329 | "Action": "iam:UpdateAssumeRolePolicy",
330 | "Resource": {
331 | "Fn::GetAtt": [
332 | "AuthRole",
333 | "Arn"
334 | ]
335 | }
336 | },
337 | {
338 | "Effect": "Allow",
339 | "Action": "iam:UpdateAssumeRolePolicy",
340 | "Resource": {
341 | "Fn::GetAtt": [
342 | "UnauthRole",
343 | "Arn"
344 | ]
345 | }
346 | }
347 | ]
348 | }
349 | }
350 | ]
351 | }
352 | }
353 | },
354 | "Outputs": {
355 | "Region": {
356 | "Description": "CloudFormation provider root stack Region",
357 | "Value": {
358 | "Ref": "AWS::Region"
359 | },
360 | "Export": {
361 | "Name": {
362 | "Fn::Sub": "${AWS::StackName}-Region"
363 | }
364 | }
365 | },
366 | "StackName": {
367 | "Description": "CloudFormation provider root stack ID",
368 | "Value": {
369 | "Ref": "AWS::StackName"
370 | },
371 | "Export": {
372 | "Name": {
373 | "Fn::Sub": "${AWS::StackName}-StackName"
374 | }
375 | }
376 | },
377 | "StackId": {
378 | "Description": "CloudFormation provider root stack name",
379 | "Value": {
380 | "Ref": "AWS::StackId"
381 | },
382 | "Export": {
383 | "Name": {
384 | "Fn::Sub": "${AWS::StackName}-StackId"
385 | }
386 | }
387 | },
388 | "DeploymentBucketName": {
389 | "Description": "CloudFormation provider root stack deployment bucket name",
390 | "Value": {
391 | "Ref": "DeploymentBucketName"
392 | },
393 | "Export": {
394 | "Name": {
395 | "Fn::Sub": "${AWS::StackName}-DeploymentBucketName"
396 | }
397 | }
398 | },
399 | "AuthRoleArn": {
400 | "Value": {
401 | "Fn::GetAtt": [
402 | "AuthRole",
403 | "Arn"
404 | ]
405 | }
406 | },
407 | "UnauthRoleArn": {
408 | "Value": {
409 | "Fn::GetAtt": [
410 | "UnauthRole",
411 | "Arn"
412 | ]
413 | }
414 | },
415 | "AuthRoleName": {
416 | "Value": {
417 | "Ref": "AuthRole"
418 | }
419 | },
420 | "UnauthRoleName": {
421 | "Value": {
422 | "Ref": "UnauthRole"
423 | }
424 | }
425 | }
426 | }
--------------------------------------------------------------------------------
/amplify/backend/awscloudformation/build/awscloudformation/nested-cloudformation-stack.yml:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "Root Stack for AWS Amplify Console",
4 | "Parameters": {
5 | "DeploymentBucketName": {
6 | "Description": "Name of the common deployment bucket provided by the parent stack",
7 | "Type": "String",
8 | "Default": "DeploymentBucket"
9 | },
10 | "AuthRoleName": {
11 | "Type": "String",
12 | "Default": "AuthRoleName"
13 | },
14 | "UnauthRoleName": {
15 | "Type": "String",
16 | "Default": "UnauthRoleName"
17 | }
18 | },
19 | "Resources": {
20 | "DeploymentBucket": {
21 | "Type": "AWS::S3::Bucket",
22 | "DeletionPolicy": "Retain",
23 | "Properties": {
24 | "BucketName": {
25 | "Ref": "DeploymentBucketName"
26 | },
27 | "BucketEncryption": {
28 | "ServerSideEncryptionConfiguration": [
29 | {
30 | "ServerSideEncryptionByDefault": {
31 | "SSEAlgorithm": "AES256"
32 | }
33 | }
34 | ]
35 | }
36 | }
37 | },
38 | "AuthRole": {
39 | "Type": "AWS::IAM::Role",
40 | "Properties": {
41 | "RoleName": {
42 | "Ref": "AuthRoleName"
43 | },
44 | "AssumeRolePolicyDocument": {
45 | "Version": "2012-10-17",
46 | "Statement": [
47 | {
48 | "Sid": "",
49 | "Effect": "Deny",
50 | "Principal": {
51 | "Federated": "cognito-identity.amazonaws.com"
52 | },
53 | "Action": "sts:AssumeRoleWithWebIdentity"
54 | }
55 | ]
56 | }
57 | }
58 | },
59 | "UnauthRole": {
60 | "Type": "AWS::IAM::Role",
61 | "Properties": {
62 | "RoleName": {
63 | "Ref": "UnauthRoleName"
64 | },
65 | "AssumeRolePolicyDocument": {
66 | "Version": "2012-10-17",
67 | "Statement": [
68 | {
69 | "Sid": "",
70 | "Effect": "Deny",
71 | "Principal": {
72 | "Federated": "cognito-identity.amazonaws.com"
73 | },
74 | "Action": "sts:AssumeRoleWithWebIdentity"
75 | }
76 | ]
77 | }
78 | }
79 | },
80 | "authcloudchopperd20aa567": {
81 | "Type": "AWS::CloudFormation::Stack",
82 | "Properties": {
83 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/auth/cloudchopperd20aa567-cloudformation-template.yml",
84 | "Parameters": {
85 | "identityPoolName": "cloudchopperd20aa567_identitypool_d20aa567",
86 | "allowUnauthenticatedIdentities": true,
87 | "resourceNameTruncated": "cloudcd20aa567",
88 | "userPoolName": "cloudchopperd20aa567_userpool_d20aa567",
89 | "autoVerifiedAttributes": "email",
90 | "mfaConfiguration": "OFF",
91 | "mfaTypes": "SMS Text Message",
92 | "smsAuthenticationMessage": "Your authentication code is {####}",
93 | "smsVerificationMessage": "Your verification code is {####}",
94 | "emailVerificationSubject": "Your verification code",
95 | "emailVerificationMessage": "Your verification code is {####}",
96 | "defaultPasswordPolicy": false,
97 | "passwordPolicyMinLength": 8,
98 | "passwordPolicyCharacters": "",
99 | "requiredAttributes": "email",
100 | "userpoolClientGenerateSecret": false,
101 | "userpoolClientRefreshTokenValidity": 30,
102 | "userpoolClientWriteAttributes": "email",
103 | "userpoolClientReadAttributes": "email",
104 | "userpoolClientLambdaRole": "cloudcd20aa567_userpoolclient_lambda_role",
105 | "userpoolClientSetAttributes": false,
106 | "sharedId": "d20aa567",
107 | "resourceName": "cloudchopperd20aa567",
108 | "authSelections": "identityPoolAndUserPool",
109 | "authRoleArn": {
110 | "Fn::GetAtt": [
111 | "AuthRole",
112 | "Arn"
113 | ]
114 | },
115 | "unauthRoleArn": {
116 | "Fn::GetAtt": [
117 | "UnauthRole",
118 | "Arn"
119 | ]
120 | },
121 | "useDefault": "default",
122 | "userPoolGroupList": "",
123 | "serviceName": "Cognito",
124 | "usernameCaseSensitive": false,
125 | "dependsOn": "",
126 | "env": "dev"
127 | }
128 | }
129 | },
130 | "storageS3chopperthao": {
131 | "Type": "AWS::CloudFormation::Stack",
132 | "Properties": {
133 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/storage/s3-cloudformation-template.json",
134 | "Parameters": {
135 | "bucketName": "cloudchopper5de8d1549c594acca63ed06abae2d414",
136 | "authPolicyName": "s3_amplify_899f92fa",
137 | "unauthPolicyName": "s3_amplify_899f92fa",
138 | "authRoleName": {
139 | "Ref": "AuthRoleName"
140 | },
141 | "unauthRoleName": {
142 | "Ref": "UnauthRoleName"
143 | },
144 | "selectedGuestPermissions": "s3:PutObject,s3:GetObject,s3:ListBucket,s3:DeleteObject",
145 | "selectedAuthenticatedPermissions": "s3:PutObject,s3:GetObject,s3:ListBucket,s3:DeleteObject",
146 | "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
147 | "s3PublicPolicy": "Public_policy_7d6cabc6",
148 | "s3PermissionsAuthenticatedUploads": "s3:PutObject",
149 | "s3UploadsPolicy": "Uploads_policy_7d6cabc6",
150 | "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
151 | "s3ProtectedPolicy": "Protected_policy_5e148ded",
152 | "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
153 | "s3PrivatePolicy": "Private_policy_5e148ded",
154 | "AuthenticatedAllowList": "ALLOW",
155 | "s3ReadPolicy": "read_policy_7d6cabc6",
156 | "s3PermissionsGuestPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
157 | "s3PermissionsGuestUploads": "s3:PutObject",
158 | "GuestAllowList": "ALLOW",
159 | "triggerFunction": "NONE",
160 | "env": "dev"
161 | }
162 | }
163 | },
164 | "analyticscloudchopper": {
165 | "Type": "AWS::CloudFormation::Stack",
166 | "Properties": {
167 | "TemplateURL": "https://s3.amazonaws.com/amplify-cloudchopper-dev-204628-deployment/amplify-cfn-templates/analytics/pinpoint-cloudformation-template.json",
168 | "Parameters": {
169 | "appName": "cloudchopper",
170 | "roleName": "pinpointLambdaRoleaaf79265",
171 | "cloudformationPolicyName": "cloudformationPolicyaaf79265",
172 | "cloudWatchPolicyName": "cloudWatchPolicyaaf79265",
173 | "pinpointPolicyName": "pinpointPolicyaaf79265",
174 | "authPolicyName": "pinpoint_amplify_aaf79265",
175 | "unauthPolicyName": "pinpoint_amplify_aaf79265",
176 | "authRoleName": {
177 | "Ref": "AuthRoleName"
178 | },
179 | "unauthRoleName": {
180 | "Ref": "UnauthRoleName"
181 | },
182 | "authRoleArn": {
183 | "Fn::GetAtt": [
184 | "AuthRole",
185 | "Arn"
186 | ]
187 | },
188 | "env": "dev"
189 | }
190 | }
191 | },
192 | "UpdateRolesWithIDPFunction": {
193 | "DependsOn": [
194 | "AuthRole",
195 | "UnauthRole",
196 | "authcloudchopperd20aa567"
197 | ],
198 | "Type": "AWS::Lambda::Function",
199 | "Properties": {
200 | "Code": {
201 | "ZipFile": {
202 | "Fn::Join": [
203 | "\n",
204 | [
205 | "const response = require('cfn-response');",
206 | "const aws = require('aws-sdk');",
207 | "let responseData = {};",
208 | "exports.handler = function(event, context) {",
209 | " try {",
210 | " let authRoleName = event.ResourceProperties.authRoleName;",
211 | " let unauthRoleName = event.ResourceProperties.unauthRoleName;",
212 | " let idpId = event.ResourceProperties.idpId;",
213 | " let promises = [];",
214 | " let authParamsJson = { 'Version': '2012-10-17','Statement': [{'Effect': 'Allow','Principal': {'Federated': 'cognito-identity.amazonaws.com'},'Action': 'sts:AssumeRoleWithWebIdentity','Condition': {'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'authenticated'}}}]};",
215 | " let unauthParamsJson = { 'Version': '2012-10-17','Statement': [{'Effect': 'Allow','Principal': {'Federated': 'cognito-identity.amazonaws.com'},'Action': 'sts:AssumeRoleWithWebIdentity','Condition': {'StringEquals': {'cognito-identity.amazonaws.com:aud': idpId},'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'unauthenticated'}}}]};",
216 | " if (event.RequestType == 'Delete') {",
217 | " delete authParamsJson.Statement[0].Condition;",
218 | " delete unauthParamsJson.Statement[0].Condition;",
219 | " let authParams = { PolicyDocument: JSON.stringify(authParamsJson),RoleName: authRoleName};",
220 | " let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson),RoleName: unauthRoleName};",
221 | " const iam = new aws.IAM({ apiVersion: '2010-05-08', region: event.ResourceProperties.region});",
222 | " promises.push(iam.updateAssumeRolePolicy(authParams).promise());",
223 | " promises.push(iam.updateAssumeRolePolicy(unauthParams).promise());",
224 | " Promise.all(promises)",
225 | " .then((res) => {",
226 | " console.log(\"delete response data\" + JSON.stringify(res));",
227 | " response.send(event, context, response.SUCCESS, {});",
228 | " });",
229 | " }",
230 | " if (event.RequestType == 'Update' || event.RequestType == 'Create') {",
231 | " const iam = new aws.IAM({ apiVersion: '2010-05-08', region: event.ResourceProperties.region});",
232 | " let authParams = { PolicyDocument: JSON.stringify(authParamsJson),RoleName: authRoleName};",
233 | " let unauthParams = {PolicyDocument: JSON.stringify(unauthParamsJson),RoleName: unauthRoleName};",
234 | " promises.push(iam.updateAssumeRolePolicy(authParams).promise());",
235 | " promises.push(iam.updateAssumeRolePolicy(unauthParams).promise());",
236 | " Promise.all(promises)",
237 | " .then((res) => {",
238 | " console.log(\"createORupdate\" + res);",
239 | " console.log(\"response data\" + JSON.stringify(res));",
240 | " response.send(event, context, response.SUCCESS, {});",
241 | " });",
242 | " }",
243 | " } catch(err) {",
244 | " console.log(err.stack);",
245 | " responseData = {Error: err};",
246 | " response.send(event, context, response.FAILED, responseData);",
247 | " throw err;",
248 | " }",
249 | "};"
250 | ]
251 | ]
252 | }
253 | },
254 | "Handler": "index.handler",
255 | "Runtime": "nodejs12.x",
256 | "Timeout": "300",
257 | "Role": {
258 | "Fn::GetAtt": [
259 | "UpdateRolesWithIDPFunctionRole",
260 | "Arn"
261 | ]
262 | }
263 | }
264 | },
265 | "UpdateRolesWithIDPFunctionOutputs": {
266 | "Type": "Custom::LambdaCallout",
267 | "Properties": {
268 | "ServiceToken": {
269 | "Fn::GetAtt": [
270 | "UpdateRolesWithIDPFunction",
271 | "Arn"
272 | ]
273 | },
274 | "region": {
275 | "Ref": "AWS::Region"
276 | },
277 | "idpId": {
278 | "Fn::GetAtt": [
279 | "authcloudchopperd20aa567",
280 | "Outputs.IdentityPoolId"
281 | ]
282 | },
283 | "authRoleName": {
284 | "Ref": "AuthRoleName"
285 | },
286 | "unauthRoleName": {
287 | "Ref": "UnauthRoleName"
288 | }
289 | }
290 | },
291 | "UpdateRolesWithIDPFunctionRole": {
292 | "Type": "AWS::IAM::Role",
293 | "Properties": {
294 | "RoleName": {
295 | "Fn::Join": [
296 | "",
297 | [
298 | {
299 | "Ref": "AuthRoleName"
300 | },
301 | "-idp"
302 | ]
303 | ]
304 | },
305 | "AssumeRolePolicyDocument": {
306 | "Version": "2012-10-17",
307 | "Statement": [
308 | {
309 | "Effect": "Allow",
310 | "Principal": {
311 | "Service": [
312 | "lambda.amazonaws.com"
313 | ]
314 | },
315 | "Action": [
316 | "sts:AssumeRole"
317 | ]
318 | }
319 | ]
320 | },
321 | "Policies": [
322 | {
323 | "PolicyName": "UpdateRolesWithIDPFunctionPolicy",
324 | "PolicyDocument": {
325 | "Version": "2012-10-17",
326 | "Statement": [
327 | {
328 | "Effect": "Allow",
329 | "Action": [
330 | "logs:CreateLogGroup",
331 | "logs:CreateLogStream",
332 | "logs:PutLogEvents"
333 | ],
334 | "Resource": "arn:aws:logs:*:*:*"
335 | },
336 | {
337 | "Effect": "Allow",
338 | "Action": "iam:UpdateAssumeRolePolicy",
339 | "Resource": {
340 | "Fn::GetAtt": [
341 | "AuthRole",
342 | "Arn"
343 | ]
344 | }
345 | },
346 | {
347 | "Effect": "Allow",
348 | "Action": "iam:UpdateAssumeRolePolicy",
349 | "Resource": {
350 | "Fn::GetAtt": [
351 | "UnauthRole",
352 | "Arn"
353 | ]
354 | }
355 | }
356 | ]
357 | }
358 | }
359 | ]
360 | }
361 | }
362 | },
363 | "Outputs": {
364 | "Region": {
365 | "Description": "CloudFormation provider root stack Region",
366 | "Value": {
367 | "Ref": "AWS::Region"
368 | },
369 | "Export": {
370 | "Name": {
371 | "Fn::Sub": "${AWS::StackName}-Region"
372 | }
373 | }
374 | },
375 | "StackName": {
376 | "Description": "CloudFormation provider root stack ID",
377 | "Value": {
378 | "Ref": "AWS::StackName"
379 | },
380 | "Export": {
381 | "Name": {
382 | "Fn::Sub": "${AWS::StackName}-StackName"
383 | }
384 | }
385 | },
386 | "StackId": {
387 | "Description": "CloudFormation provider root stack name",
388 | "Value": {
389 | "Ref": "AWS::StackId"
390 | },
391 | "Export": {
392 | "Name": {
393 | "Fn::Sub": "${AWS::StackName}-StackId"
394 | }
395 | }
396 | },
397 | "DeploymentBucketName": {
398 | "Description": "CloudFormation provider root stack deployment bucket name",
399 | "Value": {
400 | "Ref": "DeploymentBucketName"
401 | },
402 | "Export": {
403 | "Name": {
404 | "Fn::Sub": "${AWS::StackName}-DeploymentBucketName"
405 | }
406 | }
407 | },
408 | "AuthRoleArn": {
409 | "Value": {
410 | "Fn::GetAtt": [
411 | "AuthRole",
412 | "Arn"
413 | ]
414 | }
415 | },
416 | "UnauthRoleArn": {
417 | "Value": {
418 | "Fn::GetAtt": [
419 | "UnauthRole",
420 | "Arn"
421 | ]
422 | }
423 | },
424 | "AuthRoleName": {
425 | "Value": {
426 | "Ref": "AuthRole"
427 | }
428 | },
429 | "UnauthRoleName": {
430 | "Value": {
431 | "Ref": "UnauthRole"
432 | }
433 | }
434 | }
435 | }
--------------------------------------------------------------------------------
/amplify/backend/analytics/cloudchopper/pinpoint-cloudformation-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "Pinpoint resource stack creation using Amplify CLI",
4 | "Parameters": {
5 | "appName": {
6 | "Type": "String"
7 | },
8 | "appId": {
9 | "Type": "String",
10 | "Default": "NONE"
11 | },
12 | "roleName": {
13 | "Type": "String"
14 | },
15 | "cloudformationPolicyName": {
16 | "Type": "String"
17 | },
18 | "cloudWatchPolicyName": {
19 | "Type": "String"
20 | },
21 | "pinpointPolicyName": {
22 | "Type": "String"
23 | },
24 | "authPolicyName": {
25 | "Type": "String"
26 | },
27 | "unauthPolicyName": {
28 | "Type": "String"
29 | },
30 | "authRoleName": {
31 | "Type": "String"
32 | },
33 | "unauthRoleName": {
34 | "Type": "String"
35 | },
36 | "authRoleArn": {
37 | "Type": "String"
38 | },
39 | "env": {
40 | "Type": "String"
41 | }
42 | },
43 | "Metadata": {
44 | "AWS::CloudFormation::Interface": {
45 | "ParameterGroups": [
46 | {
47 | "Label": {
48 | "default": "Creating pinpoint app"
49 | },
50 | "Parameters": [
51 | "appName"
52 | ]
53 | }
54 | ]
55 | }
56 | },
57 | "Conditions": {
58 | "ShouldCreatePinpointApp": {
59 | "Fn::Equals": [
60 | {
61 | "Ref": "appId"
62 | },
63 | "NONE"
64 | ]
65 | },
66 | "ShouldNotCreateEnvResources": {
67 | "Fn::Equals": [
68 | {
69 | "Ref": "env"
70 | },
71 | "NONE"
72 | ]
73 | }
74 | },
75 | "Resources": {
76 | "LambdaExecutionRole": {
77 | "Condition": "ShouldCreatePinpointApp",
78 | "Type": "AWS::IAM::Role",
79 | "Properties": {
80 | "RoleName": {
81 | "Fn::If": [
82 | "ShouldNotCreateEnvResources",
83 | {
84 | "Ref": "roleName"
85 | },
86 | {
87 | "Fn::Join": [
88 | "",
89 | [
90 | {
91 | "Ref": "roleName"
92 | },
93 | "-",
94 | {
95 | "Ref": "env"
96 | }
97 | ]
98 | ]
99 | }
100 | ]
101 | },
102 | "AssumeRolePolicyDocument": {
103 | "Version": "2012-10-17",
104 | "Statement": [
105 | {
106 | "Effect": "Allow",
107 | "Principal": {
108 | "Service": [
109 | "lambda.amazonaws.com"
110 | ]
111 | },
112 | "Action": [
113 | "sts:AssumeRole"
114 | ]
115 | }
116 | ]
117 | },
118 | "Policies": [
119 | {
120 | "PolicyName": {
121 | "Ref": "cloudWatchPolicyName"
122 | },
123 | "PolicyDocument": {
124 | "Version": "2012-10-17",
125 | "Statement": [
126 | {
127 | "Effect": "Allow",
128 | "Action": [
129 | "logs:CreateLogGroup",
130 | "logs:CreateLogStream",
131 | "logs:PutLogEvents"
132 | ],
133 | "Resource": "arn:aws:logs:*:*:*"
134 | }
135 | ]
136 | }
137 | },
138 | {
139 | "PolicyName": {
140 | "Ref": "pinpointPolicyName"
141 | },
142 | "PolicyDocument": {
143 | "Version": "2012-10-17",
144 | "Statement": [
145 | {
146 | "Effect": "Allow",
147 | "Action": [
148 | "mobileanalytics:*",
149 | "mobiletargeting:*"
150 | ],
151 | "Resource": "*"
152 | }
153 | ]
154 | }
155 | },
156 | {
157 | "PolicyName": {
158 | "Ref": "cloudformationPolicyName"
159 | },
160 | "PolicyDocument": {
161 | "Version": "2012-10-17",
162 | "Statement": [
163 | {
164 | "Effect": "Allow",
165 | "Action": [
166 | "cloudformation:*"
167 | ],
168 | "Resource": "*"
169 | }
170 | ]
171 | }
172 | }
173 | ]
174 | }
175 | },
176 | "PinpointFunction": {
177 | "Type": "AWS::Lambda::Function",
178 | "Condition": "ShouldCreatePinpointApp",
179 | "Properties": {
180 | "Code": {
181 | "ZipFile": {
182 | "Fn::Join": [
183 | "\n",
184 | [
185 | "const response = require('cfn-response');",
186 | "const aws = require('aws-sdk');",
187 | "exports.handler = function(event, context) {",
188 | " if (event.RequestType == 'Delete') {",
189 | " const stackID = event.StackId;",
190 | " const cloudFormationClient = new aws.CloudFormation({ apiVersion: '2016-12-01', region: event.ResourceProperties.region });",
191 | " cloudFormationClient.describeStacks({ StackName: stackID }).promise()",
192 | " .then(describeStacksOutput => {",
193 | " let appId;",
194 | " if (describeStacksOutput.Stacks && describeStacksOutput.Stacks.length > 0) {",
195 | " const { Outputs } = describeStacksOutput.Stacks[0];",
196 | " const appIdOutput = Outputs.find((output)=>{ return output.OutputKey === 'Id'});",
197 | " appId = appIdOutput ? appIdOutput.OutputValue : undefined; ",
198 | " }",
199 | " return appId;",
200 | " })",
201 | " .then(appId => {",
202 | " if (appId) {",
203 | " const pinpointClient = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
204 | " const params = {",
205 | " ApplicationId: appId,",
206 | " };",
207 | " pinpointClient.deleteApp(params).promise();",
208 | " }",
209 | " })",
210 | " .then(()=>{",
211 | " response.send(event, context, response.SUCCESS, {'message': `Successfully deleted pinpoint project`});",
212 | " })",
213 | " .catch(e=>{",
214 | " response.send(event, context, response.FAILED, {'message': `Failed to deleted Pinpoint project`, 'exception': e});",
215 | " }); ",
216 | " }",
217 | " if (event.RequestType == 'Update') {",
218 | " response.send(event, context, response.SUCCESS);",
219 | " return;",
220 | " }",
221 | " if (event.RequestType == 'Create') {",
222 | " const appName = event.ResourceProperties.appName;",
223 | " let responseData = {};",
224 | " const params = {",
225 | " CreateApplicationRequest: {",
226 | " Name: appName",
227 | " }",
228 | " };",
229 | " const pinpoint = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
230 | " pinpoint.createApp(params).promise()",
231 | " .then((res) => {",
232 | " responseData = res.ApplicationResponse;",
233 | " response.send(event, context, response.SUCCESS, responseData);",
234 | " }).catch((err) => {",
235 | " console.log(err.stack);",
236 | " responseData = {Error: err};",
237 | " response.send(event, context, response.FAILED, responseData);",
238 | " throw err;",
239 | " });",
240 | " }",
241 | "};"
242 | ]
243 | ]
244 | }
245 | },
246 | "Handler": "index.handler",
247 | "Runtime": "nodejs12.x",
248 | "Timeout": "300",
249 | "Role": {
250 | "Fn::GetAtt": [
251 | "LambdaExecutionRole",
252 | "Arn"
253 | ]
254 | }
255 | }
256 | },
257 | "PinpointFunctionOutputs": {
258 | "Type": "Custom::LambdaCallout",
259 | "Condition": "ShouldCreatePinpointApp",
260 | "Properties": {
261 | "ServiceToken": {
262 | "Fn::GetAtt": [
263 | "PinpointFunction",
264 | "Arn"
265 | ]
266 | },
267 | "region": {
268 | "Ref": "AWS::Region"
269 | },
270 | "pingPointRegion": {
271 | "Fn::FindInMap": [
272 | "RegionMapping",
273 | {
274 | "Ref": "AWS::Region"
275 | },
276 | "pinpointRegion"
277 | ]
278 | },
279 | "appName": {
280 | "Fn::If": [
281 | "ShouldNotCreateEnvResources",
282 | {
283 | "Ref": "appName"
284 | },
285 | {
286 | "Fn::Join": [
287 | "",
288 | [
289 | {
290 | "Ref": "appName"
291 | },
292 | "-",
293 | {
294 | "Ref": "env"
295 | }
296 | ]
297 | ]
298 | }
299 | ]
300 | }
301 | },
302 | "DependsOn": "PinpointFunction"
303 | },
304 | "CognitoUnauthPolicy": {
305 | "Type": "AWS::IAM::Policy",
306 | "Condition": "ShouldCreatePinpointApp",
307 | "Properties": {
308 | "PolicyName": {
309 | "Ref": "unauthPolicyName"
310 | },
311 | "Roles": [
312 | {
313 | "Ref": "unauthRoleName"
314 | }
315 | ],
316 | "PolicyDocument": {
317 | "Version": "2012-10-17",
318 | "Statement": [
319 | {
320 | "Effect": "Allow",
321 | "Action": [
322 | "mobiletargeting:PutEvents",
323 | "mobiletargeting:UpdateEndpoint"
324 | ],
325 | "Resource": [
326 | {
327 | "Fn::If": [
328 | "ShouldCreatePinpointApp",
329 | {
330 | "Fn::Join": [
331 | "",
332 | [
333 | "arn:aws:mobiletargeting:*:",
334 | {
335 | "Fn::Select": [
336 | "4",
337 | {
338 | "Fn::Split": [
339 | ":",
340 | {
341 | "Ref": "authRoleArn"
342 | }
343 | ]
344 | }
345 | ]
346 | },
347 | ":apps/",
348 | {
349 | "Fn::GetAtt": [
350 | "PinpointFunctionOutputs",
351 | "Id"
352 | ]
353 | },
354 | "*"
355 | ]
356 | ]
357 | },
358 | {
359 | "Fn::Join": [
360 | "",
361 | [
362 | "arn:aws:mobiletargeting:*:",
363 | {
364 | "Fn::Select": [
365 | "4",
366 | {
367 | "Fn::Split": [
368 | ":",
369 | {
370 | "Ref": "authRoleArn"
371 | }
372 | ]
373 | }
374 | ]
375 | },
376 | ":apps/",
377 | {
378 | "Ref": "appId"
379 | },
380 | "*"
381 | ]
382 | ]
383 | }
384 | ]
385 | }
386 | ]
387 | }
388 | ]
389 | }
390 | }
391 | },
392 | "CognitoAuthPolicy": {
393 | "Type": "AWS::IAM::Policy",
394 | "Condition": "ShouldCreatePinpointApp",
395 | "Properties": {
396 | "PolicyName": {
397 | "Ref": "authPolicyName"
398 | },
399 | "Roles": [
400 | {
401 | "Ref": "authRoleName"
402 | }
403 | ],
404 | "PolicyDocument": {
405 | "Version": "2012-10-17",
406 | "Statement": [
407 | {
408 | "Effect": "Allow",
409 | "Action": [
410 | "mobiletargeting:PutEvents",
411 | "mobiletargeting:UpdateEndpoint"
412 | ],
413 | "Resource": [
414 | {
415 | "Fn::If": [
416 | "ShouldCreatePinpointApp",
417 | {
418 | "Fn::Join": [
419 | "",
420 | [
421 | "arn:aws:mobiletargeting:*:",
422 | {
423 | "Fn::Select": [
424 | "4",
425 | {
426 | "Fn::Split": [
427 | ":",
428 | {
429 | "Ref": "authRoleArn"
430 | }
431 | ]
432 | }
433 | ]
434 | },
435 | ":apps/",
436 | {
437 | "Fn::GetAtt": [
438 | "PinpointFunctionOutputs",
439 | "Id"
440 | ]
441 | },
442 | "*"
443 | ]
444 | ]
445 | },
446 | {
447 | "Fn::Join": [
448 | "",
449 | [
450 | "arn:aws:mobiletargeting:*:",
451 | {
452 | "Fn::Select": [
453 | "4",
454 | {
455 | "Fn::Split": [
456 | ":",
457 | {
458 | "Ref": "authRoleArn"
459 | }
460 | ]
461 | }
462 | ]
463 | },
464 | ":apps/",
465 | {
466 | "Ref": "appId"
467 | },
468 | "*"
469 | ]
470 | ]
471 | }
472 | ]
473 | }
474 | ]
475 | }
476 | ]
477 | }
478 | }
479 | }
480 | },
481 | "Outputs": {
482 | "Region": {
483 | "Value": {
484 | "Fn::FindInMap": [
485 | "RegionMapping",
486 | {
487 | "Ref": "AWS::Region"
488 | },
489 | "pinpointRegion"
490 | ]
491 | }
492 | },
493 | "Id": {
494 | "Value": {
495 | "Fn::If": [
496 | "ShouldCreatePinpointApp",
497 | {
498 | "Fn::GetAtt": [
499 | "PinpointFunctionOutputs",
500 | "Id"
501 | ]
502 | },
503 | {
504 | "Ref": "appId"
505 | }
506 | ]
507 | }
508 | },
509 | "appName": {
510 | "Value": {
511 | "Fn::If": [
512 | "ShouldCreatePinpointApp",
513 | {
514 | "Fn::GetAtt": [
515 | "PinpointFunctionOutputs",
516 | "Name"
517 | ]
518 | },
519 | {
520 | "Ref": "appName"
521 | }
522 | ]
523 | }
524 | }
525 | },
526 | "Mappings": {
527 | "RegionMapping": {
528 | "us-east-1": {
529 | "pinpointRegion": "us-east-1"
530 | },
531 | "us-east-2": {
532 | "pinpointRegion": "us-east-1"
533 | },
534 | "sa-east-1": {
535 | "pinpointRegion": "us-east-1"
536 | },
537 | "ca-central-1": {
538 | "pinpointRegion": "us-east-1"
539 | },
540 | "us-west-1": {
541 | "pinpointRegion": "us-west-2"
542 | },
543 | "us-west-2": {
544 | "pinpointRegion": "us-west-2"
545 | },
546 | "cn-north-1": {
547 | "pinpointRegion": "us-west-2"
548 | },
549 | "cn-northwest-1": {
550 | "pinpointRegion": "us-west-2"
551 | },
552 | "ap-south-1": {
553 | "pinpointRegion": "us-west-2"
554 | },
555 | "ap-northeast-3": {
556 | "pinpointRegion": "us-west-2"
557 | },
558 | "ap-northeast-2": {
559 | "pinpointRegion": "us-west-2"
560 | },
561 | "ap-southeast-1": {
562 | "pinpointRegion": "us-west-2"
563 | },
564 | "ap-southeast-2": {
565 | "pinpointRegion": "us-west-2"
566 | },
567 | "ap-northeast-1": {
568 | "pinpointRegion": "us-west-2"
569 | },
570 | "eu-central-1": {
571 | "pinpointRegion": "eu-central-1"
572 | },
573 | "eu-west-1": {
574 | "pinpointRegion": "eu-west-1"
575 | },
576 | "eu-west-2": {
577 | "pinpointRegion": "eu-west-1"
578 | },
579 | "eu-west-3": {
580 | "pinpointRegion": "eu-west-1"
581 | }
582 | }
583 | }
584 | }
--------------------------------------------------------------------------------