diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index b40952a..46d458c 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -7,11 +7,11 @@
-
+
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 28966ce..dca0bdc 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -26,6 +26,9 @@
+
+
+
diff --git a/amplify/.config/project-config.json b/amplify/.config/project-config.json
index 8119c68..900607a 100644
--- a/amplify/.config/project-config.json
+++ b/amplify/.config/project-config.json
@@ -1,13 +1,13 @@
{
- "projectName": "thrifty",
+ "providers": [
+ "awscloudformation"
+ ],
+ "projectName": "thrifty2",
"version": "3.1",
"frontend": "android",
"android": {
"config": {
"ResDir": "app/src/main/res"
}
- },
- "providers": [
- "awscloudformation"
- ]
+ }
}
\ No newline at end of file
diff --git a/amplify/README.md b/amplify/README.md
deleted file mode 100644
index 7c0a9e2..0000000
--- a/amplify/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Getting Started with Amplify CLI
-This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli).
-
-Helpful resources:
-- Amplify documentation: https://docs.amplify.aws
-- Amplify CLI documentation: https://docs.amplify.aws/cli
-- More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files
-- Join Amplify's community: https://amplify.aws/community/
diff --git a/amplify/backend/api/thrifty/.migration-backup/schema.graphql b/amplify/backend/api/thrifty/.migration-backup/schema.graphql
deleted file mode 100644
index edc9ad0..0000000
--- a/amplify/backend/api/thrifty/.migration-backup/schema.graphql
+++ /dev/null
@@ -1,28 +0,0 @@
-type Product @model @auth(rules: [{allow: public}]) @key(name: "byCategory", fields: ["categoryID"]) {
- id: ID!
- title: String!
- description: String!
- price: String!
- size: String!
- color: String!
- image: String!
- categoryID: ID
-}
-
-type Favorite @model @auth(rules: [{allow: public}]) @key(name: "byUser", fields: ["userID"]) {
- id: ID!
- userID: ID
- Product: Product @connection
-}
-
-type Category @model @auth(rules: [{allow: public}]) {
- id: ID!
- name: String!
- Products: [Product] @connection(keyName: "byCategory", fields: ["id"])
-}
-
-type User @model @auth(rules: [{allow: public}]) {
- id: ID!
- email: String!
- Favorites: [Favorite] @connection(keyName: "byUser", fields: ["id"])
-}
diff --git a/amplify/backend/api/thrifty/parameters.json b/amplify/backend/api/thrifty/parameters.json
deleted file mode 100644
index 2b477e2..0000000
--- a/amplify/backend/api/thrifty/parameters.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "AppSyncApiName": "thrifty",
- "DynamoDBBillingMode": "PAY_PER_REQUEST",
- "DynamoDBEnableServerSideEncryption": false
-}
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty/cli-inputs.json b/amplify/backend/api/thrifty2/cli-inputs.json
similarity index 52%
rename from amplify/backend/api/thrifty/cli-inputs.json
rename to amplify/backend/api/thrifty2/cli-inputs.json
index 7f9c285..a956ae3 100644
--- a/amplify/backend/api/thrifty/cli-inputs.json
+++ b/amplify/backend/api/thrifty2/cli-inputs.json
@@ -1,23 +1,24 @@
{
"version": 1,
"serviceConfiguration": {
- "apiName": "thrifty",
"serviceName": "AppSync",
- "gqlSchemaPath": "/tmp/amplify-2e97eeff-bfb1-4790-87ca-b286e0a41ce2/amplify/backend/api/thrifty/schema.graphql",
"defaultAuthType": {
"mode": "API_KEY",
- "keyDescription": "api key description",
- "expirationTime": 30
+ "expirationTime": 35,
+ "apiKeyExpirationDate": "2022-01-06T02:02:46.260Z",
+ "keyDescription": "ssdmh"
},
- "additionalAuthTypes": [
- {
- "mode": "AWS_IAM"
- }
- ],
"conflictResolution": {
"defaultResolutionStrategy": {
"type": "AUTOMERGE"
}
- }
+ },
+ "apiName": "thrifty2",
+ "gqlSchemaPath": "/mnt/c/Users/STUDENT/AndroidStudioProjects/thrifty/amplify/backend/api/thrifty2/schema.graphql",
+ "additionalAuthTypes": [
+ {
+ "mode": "AWS_IAM"
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty2/parameters.json b/amplify/backend/api/thrifty2/parameters.json
new file mode 100644
index 0000000..254946c
--- /dev/null
+++ b/amplify/backend/api/thrifty2/parameters.json
@@ -0,0 +1,12 @@
+{
+ "AppSyncApiName": "thrifty2",
+ "DynamoDBBillingMode": "PAY_PER_REQUEST",
+ "DynamoDBEnableServerSideEncryption": false,
+ "AuthCognitoUserPoolId": {
+ "Fn::GetAtt": [
+ "auththrifty23c488d7e",
+ "Outputs.UserPoolId"
+ ]
+ },
+ "AuthModeLastUpdated": "2021-12-01T23:40:42.562Z"
+}
\ No newline at end of file
diff --git a/amplify/backend/api/thrifty/resolvers/README.md b/amplify/backend/api/thrifty2/resolvers/README.md
similarity index 100%
rename from amplify/backend/api/thrifty/resolvers/README.md
rename to amplify/backend/api/thrifty2/resolvers/README.md
diff --git a/amplify/backend/api/thrifty/schema.graphql b/amplify/backend/api/thrifty2/schema.graphql
similarity index 100%
rename from amplify/backend/api/thrifty/schema.graphql
rename to amplify/backend/api/thrifty2/schema.graphql
diff --git a/amplify/backend/api/thrifty/stacks/CustomResources.json b/amplify/backend/api/thrifty2/stacks/CustomResources.json
similarity index 100%
rename from amplify/backend/api/thrifty/stacks/CustomResources.json
rename to amplify/backend/api/thrifty2/stacks/CustomResources.json
diff --git a/amplify/backend/api/thrifty/transform.conf.json b/amplify/backend/api/thrifty2/transform.conf.json
similarity index 100%
rename from amplify/backend/api/thrifty/transform.conf.json
rename to amplify/backend/api/thrifty2/transform.conf.json
diff --git a/amplify/backend/auth/thrifty880b2640/cli-inputs.json b/amplify/backend/auth/thrifty23c488d7e/parameters.json
similarity index 59%
rename from amplify/backend/auth/thrifty880b2640/cli-inputs.json
rename to amplify/backend/auth/thrifty23c488d7e/parameters.json
index 3132851..a91ddc4 100644
--- a/amplify/backend/auth/thrifty880b2640/cli-inputs.json
+++ b/amplify/backend/auth/thrifty23c488d7e/parameters.json
@@ -1,16 +1,14 @@
{
- "version": "1",
- "cognitoConfig": {
- "identityPoolName": "thrifty880b2640_identitypool_880b2640",
- "allowUnauthenticatedIdentities": true,
- "resourceNameTruncated": "thrift880b2640",
- "userPoolName": "thrifty880b2640_userpool_880b2640",
+ "identityPoolName": "thrifty23c488d7e_identitypool_3c488d7e",
+ "allowUnauthenticatedIdentities": false,
+ "resourceNameTruncated": "thrift3c488d7e",
+ "userPoolName": "thrifty23c488d7e_userpool_3c488d7e",
"autoVerifiedAttributes": [
- "email"
+ "email"
],
"mfaConfiguration": "OFF",
"mfaTypes": [
- "SMS Text Message"
+ "SMS Text Message"
],
"smsAuthenticationMessage": "Your authentication code is {####}",
"smsVerificationMessage": "Your verification code is {####}",
@@ -20,42 +18,40 @@
"passwordPolicyMinLength": 8,
"passwordPolicyCharacters": [],
"requiredAttributes": [
- "email"
+ "email"
],
"aliasAttributes": [],
"userpoolClientGenerateSecret": false,
"userpoolClientRefreshTokenValidity": 30,
"userpoolClientWriteAttributes": [
- "email"
+ "email"
],
"userpoolClientReadAttributes": [
- "email"
+ "email"
],
- "userpoolClientLambdaRole": "thrift880b2640_userpoolclient_lambda_role",
+ "userpoolClientLambdaRole": "thrift3c488d7e_userpoolclient_lambda_role",
"userpoolClientSetAttributes": false,
- "sharedId": "880b2640",
- "resourceName": "thrifty880b2640",
+ "sharedId": "3c488d7e",
+ "resourceName": "thrifty23c488d7e",
"authSelections": "identityPoolAndUserPool",
+ "authRoleArn": {
+ "Fn::GetAtt": [
+ "AuthRole",
+ "Arn"
+ ]
+ },
+ "unauthRoleArn": {
+ "Fn::GetAtt": [
+ "UnauthRole",
+ "Arn"
+ ]
+ },
"useDefault": "default",
"usernameAttributes": [
- "email"
+ "email"
],
"userPoolGroupList": [],
"serviceName": "Cognito",
- "useEnabledMfas": false,
- "authRoleArn": {
- "Fn::GetAtt": [
- "AuthRole",
- "Arn"
- ]
- },
- "unauthRoleArn": {
- "Fn::GetAtt": [
- "UnauthRole",
- "Arn"
- ]
- },
- "breakCircularDependency": false,
+ "usernameCaseSensitive": false,
"dependsOn": []
- }
}
\ No newline at end of file
diff --git a/amplify/backend/auth/thrifty23c488d7e/thrifty23c488d7e-cloudformation-template.yml b/amplify/backend/auth/thrifty23c488d7e/thrifty23c488d7e-cloudformation-template.yml
new file mode 100644
index 0000000..cc8fd58
--- /dev/null
+++ b/amplify/backend/auth/thrifty23c488d7e/thrifty23c488d7e-cloudformation-template.yml
@@ -0,0 +1,433 @@
+
+AWSTemplateFormatVersion: 2010-09-09
+
+Parameters:
+ env:
+ Type: String
+ authRoleArn:
+ Type: String
+ unauthRoleArn:
+ Type: String
+
+
+
+
+ identityPoolName:
+ Type: String
+
+
+
+ allowUnauthenticatedIdentities:
+ Type: String
+
+ resourceNameTruncated:
+ Type: String
+
+
+ userPoolName:
+ Type: String
+
+
+
+ autoVerifiedAttributes:
+ Type: CommaDelimitedList
+
+ mfaConfiguration:
+ Type: String
+
+
+
+ mfaTypes:
+ Type: CommaDelimitedList
+
+ smsAuthenticationMessage:
+ Type: String
+
+
+ smsVerificationMessage:
+ Type: String
+
+
+ emailVerificationSubject:
+ Type: String
+
+
+ emailVerificationMessage:
+ Type: String
+
+
+
+ defaultPasswordPolicy:
+ Type: String
+
+
+ passwordPolicyMinLength:
+ Type: Number
+
+
+ passwordPolicyCharacters:
+ Type: CommaDelimitedList
+
+
+ requiredAttributes:
+ Type: CommaDelimitedList
+
+
+ aliasAttributes:
+ Type: CommaDelimitedList
+
+
+ userpoolClientGenerateSecret:
+ Type: String
+
+
+ userpoolClientRefreshTokenValidity:
+ Type: Number
+
+
+ userpoolClientWriteAttributes:
+ Type: CommaDelimitedList
+
+
+ userpoolClientReadAttributes:
+ Type: CommaDelimitedList
+
+ userpoolClientLambdaRole:
+ Type: String
+
+
+
+ userpoolClientSetAttributes:
+ Type: String
+
+ sharedId:
+ Type: String
+
+
+ resourceName:
+ Type: String
+
+
+ authSelections:
+ Type: String
+
+
+
+
+ useDefault:
+ Type: String
+
+
+
+ usernameAttributes:
+ Type: CommaDelimitedList
+
+
+ userPoolGroupList:
+ Type: CommaDelimitedList
+
+
+ serviceName:
+ Type: String
+
+
+
+ usernameCaseSensitive:
+ Type: String
+
+
+ dependsOn:
+ Type: CommaDelimitedList
+
+Conditions:
+ ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
+
+ ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ]
+
+
+Resources:
+
+
+ # BEGIN SNS ROLE RESOURCE
+ SNSRole:
+ # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
+ Type: AWS::IAM::Role
+ Properties:
+ RoleName: !If [ShouldNotCreateEnvResources, 'thrift3c488d7e_sns-role', !Join ['',[ 'sns', '3c488d7e', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
+ AssumeRolePolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ - Sid: ""
+ Effect: "Allow"
+ Principal:
+ Service: "cognito-idp.amazonaws.com"
+ Action:
+ - "sts:AssumeRole"
+ Condition:
+ StringEquals:
+ sts:ExternalId: thrift3c488d7e_role_external_id
+ Policies:
+ -
+ PolicyName: thrift3c488d7e-sns-policy
+ PolicyDocument:
+ Version: "2012-10-17"
+ Statement:
+ -
+ Effect: "Allow"
+ Action:
+ - "sns:Publish"
+ Resource: "*"
+ # BEGIN USER POOL RESOURCES
+ UserPool:
+ # Created upon user selection
+ # Depends on SNS Role for Arn if MFA is enabled
+ Type: AWS::Cognito::UserPool
+ UpdateReplacePolicy: Retain
+ Properties:
+ UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
+
+
+ UsernameConfiguration:
+ CaseSensitive: false
+
+ Schema:
+
+ -
+ Name: email
+ Required: true
+ Mutable: true
+
+
+
+
+ AutoVerifiedAttributes:
+
+ - email
+
+
+
+ EmailVerificationMessage: !Ref emailVerificationMessage
+ EmailVerificationSubject: !Ref emailVerificationSubject
+
+ Policies:
+ PasswordPolicy:
+ MinimumLength: !Ref passwordPolicyMinLength
+ RequireLowercase: false
+ RequireNumbers: false
+ RequireSymbols: false
+ RequireUppercase: false
+
+ UsernameAttributes: !Ref usernameAttributes
+
+
+ MfaConfiguration: !Ref mfaConfiguration
+ SmsVerificationMessage: !Ref smsVerificationMessage
+ SmsAuthenticationMessage: !Ref smsAuthenticationMessage
+ SmsConfiguration:
+ SnsCallerArn: !GetAtt SNSRole.Arn
+ ExternalId: thrift3c488d7e_role_external_id
+
+
+ UserPoolClientWeb:
+ # Created provide application access to user pool
+ # Depends on UserPool for ID reference
+ Type: "AWS::Cognito::UserPoolClient"
+ Properties:
+ ClientName: thrift3c488d7e_app_clientWeb
+
+ RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
+ UserPoolId: !Ref UserPool
+ DependsOn: UserPool
+ UserPoolClient:
+ # Created provide application access to user pool
+ # Depends on UserPool for ID reference
+ Type: "AWS::Cognito::UserPoolClient"
+ Properties:
+ ClientName: thrift3c488d7e_app_client
+
+ GenerateSecret: !Ref userpoolClientGenerateSecret
+ RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
+ UserPoolId: !Ref UserPool
+ DependsOn: UserPool
+ # BEGIN USER POOL LAMBDA RESOURCES
+ UserPoolClientRole:
+ # Created to execute Lambda which gets userpool app client config values
+ Type: 'AWS::IAM::Role'
+ Properties:
+ RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', '3c488d7e', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
+ AssumeRolePolicyDocument:
+ Version: '2012-10-17'
+ Statement:
+ - Effect: Allow
+ Principal:
+ Service:
+ - lambda.amazonaws.com
+ Action:
+ - 'sts:AssumeRole'
+ DependsOn: UserPoolClient
+ UserPoolClientLambda:
+ # Lambda which gets userpool app client config values
+ # Depends on UserPool for id
+ # Depends on UserPoolClientRole for role ARN
+ Type: 'AWS::Lambda::Function'
+ Properties:
+ Code:
+ ZipFile: !Join
+ - |+
+ - - 'const response = require(''cfn-response'');'
+ - 'const aws = require(''aws-sdk'');'
+ - 'const identity = new aws.CognitoIdentityServiceProvider();'
+ - 'exports.handler = (event, context, callback) => {'
+ - ' if (event.RequestType == ''Delete'') { '
+ - ' response.send(event, context, response.SUCCESS, {})'
+ - ' }'
+ - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
+ - ' const params = {'
+ - ' ClientId: event.ResourceProperties.clientId,'
+ - ' UserPoolId: event.ResourceProperties.userpoolId'
+ - ' };'
+ - ' identity.describeUserPoolClient(params).promise()'
+ - ' .then((res) => {'
+ - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
+ - ' })'
+ - ' .catch((err) => {'
+ - ' response.send(event, context, response.FAILED, {err});'
+ - ' });'
+ - ' }'
+ - '};'
+ Handler: index.handler
+ Runtime: nodejs12.x
+ Timeout: 300
+ Role: !GetAtt
+ - UserPoolClientRole
+ - Arn
+ DependsOn: UserPoolClientRole
+ UserPoolClientLambdaPolicy:
+ # Sets userpool policy for the role that executes the Userpool Client Lambda
+ # Depends on UserPool for Arn
+ # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
+ Type: 'AWS::IAM::Policy'
+ Properties:
+ PolicyName: thrift3c488d7e_userpoolclient_lambda_iam_policy
+ Roles:
+ - !Ref UserPoolClientRole
+ PolicyDocument:
+ Version: '2012-10-17'
+ Statement:
+ - Effect: Allow
+ Action:
+ - 'cognito-idp:DescribeUserPoolClient'
+ Resource: !GetAtt UserPool.Arn
+ DependsOn: UserPoolClientLambda
+ UserPoolClientLogPolicy:
+ # Sets log policy for the role that executes the Userpool Client Lambda
+ # Depends on UserPool for Arn
+ # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
+ Type: 'AWS::IAM::Policy'
+ Properties:
+ PolicyName: thrift3c488d7e_userpoolclient_lambda_log_policy
+ Roles:
+ - !Ref UserPoolClientRole
+ PolicyDocument:
+ Version: 2012-10-17
+ Statement:
+ - Effect: Allow
+ Action:
+ - 'logs:CreateLogGroup'
+ - 'logs:CreateLogStream'
+ - 'logs:PutLogEvents'
+ Resource: !Sub
+ - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
+ - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
+ DependsOn: UserPoolClientLambdaPolicy
+ UserPoolClientInputs:
+ # Values passed to Userpool client Lambda
+ # Depends on UserPool for Id
+ # Depends on UserPoolClient for Id
+ # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
+ Type: 'Custom::LambdaCallout'
+ Properties:
+ ServiceToken: !GetAtt UserPoolClientLambda.Arn
+ clientId: !Ref UserPoolClient
+ userpoolId: !Ref UserPool
+ DependsOn: UserPoolClientLogPolicy
+
+
+
+
+
+
+
+ # BEGIN IDENTITY POOL RESOURCES
+
+
+ IdentityPool:
+ # Always created
+ Type: AWS::Cognito::IdentityPool
+ Properties:
+ IdentityPoolName: !If [ShouldNotCreateEnvResources, 'thrifty23c488d7e_identitypool_3c488d7e', !Join ['',['thrifty23c488d7e_identitypool_3c488d7e', '__', !Ref env]]]
+
+ CognitoIdentityProviders:
+ - ClientId: !Ref UserPoolClient
+ ProviderName: !Sub
+ - cognito-idp.${region}.amazonaws.com/${client}
+ - { region: !Ref "AWS::Region", client: !Ref UserPool}
+ - ClientId: !Ref UserPoolClientWeb
+ ProviderName: !Sub
+ - cognito-idp.${region}.amazonaws.com/${client}
+ - { region: !Ref "AWS::Region", client: !Ref UserPool}
+
+ AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
+
+
+ DependsOn: UserPoolClientInputs
+
+
+ IdentityPoolRoleMap:
+ # Created to map Auth and Unauth roles to the identity pool
+ # Depends on Identity Pool for ID ref
+ Type: AWS::Cognito::IdentityPoolRoleAttachment
+ Properties:
+ IdentityPoolId: !Ref IdentityPool
+ Roles:
+ unauthenticated: !Ref unauthRoleArn
+ authenticated: !Ref authRoleArn
+ DependsOn: IdentityPool
+
+
+Outputs :
+
+ IdentityPoolId:
+ Value: !Ref 'IdentityPool'
+ Description: Id for the identity pool
+ IdentityPoolName:
+ Value: !GetAtt IdentityPool.Name
+
+
+
+
+ UserPoolId:
+ Value: !Ref 'UserPool'
+ Description: Id for the user pool
+ UserPoolArn:
+ Value: !GetAtt UserPool.Arn
+ Description: Arn for the user pool
+ UserPoolName:
+ Value: !Ref userPoolName
+ AppClientIDWeb:
+ Value: !Ref 'UserPoolClientWeb'
+ Description: The user pool app client id for web
+ AppClientID:
+ Value: !Ref 'UserPoolClient'
+ Description: The user pool app client id
+ AppClientSecret:
+ Value: !GetAtt UserPoolClientInputs.appSecret
+ Condition: ShouldOutputAppClientSecrets
+
+
+
+
+
+
+
+
diff --git a/amplify/backend/backend-config.json b/amplify/backend/backend-config.json
index b97b80b..1c24ae3 100644
--- a/amplify/backend/backend-config.json
+++ b/amplify/backend/backend-config.json
@@ -1,18 +1,24 @@
{
"api": {
- "thrifty": {
+ "thrifty2": {
"service": "AppSync",
"providerPlugin": "awscloudformation",
"output": {
"authConfig": {
"defaultAuthentication": {
- "authenticationType": "API_KEY",
- "apiKeyConfig": {
- "apiKeyExpirationDays": 30,
- "description": "api key description"
+ "authenticationType": "AMAZON_COGNITO_USER_POOLS",
+ "userPoolConfig": {
+ "userPoolId": "auththrifty23c488d7e"
}
},
"additionalAuthenticationProviders": [
+ {
+ "authenticationType": "API_KEY",
+ "apiKeyConfig": {
+ "apiKeyExpirationDays": 30,
+ "description": "api key description"
+ }
+ },
{
"authenticationType": "AWS_IAM"
}
@@ -22,14 +28,13 @@
}
},
"auth": {
- "thrifty880b2640": {
+ "thrifty23c488d7e": {
"service": "Cognito",
"providerPlugin": "awscloudformation",
"dependsOn": [],
"customAuth": false,
"frontendAuthConfig": {
- "socialProviders": [],
- "usernameAttributes": [
+ "loginMechanisms": [
"EMAIL"
],
"signupAttributes": [
@@ -50,10 +55,9 @@
}
},
"storage": {
- "s3729634dc": {
+ "s370dc9769": {
"service": "S3",
- "providerPlugin": "awscloudformation",
- "dependsOn": []
+ "providerPlugin": "awscloudformation"
}
}
}
\ No newline at end of file
diff --git a/amplify/backend/storage/s370dc9769/parameters.json b/amplify/backend/storage/s370dc9769/parameters.json
new file mode 100644
index 0000000..3c516e2
--- /dev/null
+++ b/amplify/backend/storage/s370dc9769/parameters.json
@@ -0,0 +1,35 @@
+{
+ "bucketName": "thrifty247548cdc463d4e43b8b9b7d31a4af078",
+ "authPolicyName": "s3_amplify_70dc9769",
+ "unauthPolicyName": "s3_amplify_70dc9769",
+ "authRoleName": {
+ "Ref": "AuthRoleName"
+ },
+ "unauthRoleName": {
+ "Ref": "UnauthRoleName"
+ },
+ "selectedGuestPermissions": [
+ "s3:GetObject",
+ "s3:ListBucket"
+ ],
+ "selectedAuthenticatedPermissions": [
+ "s3:PutObject",
+ "s3:GetObject",
+ "s3:ListBucket",
+ "s3:DeleteObject"
+ ],
+ "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
+ "s3PublicPolicy": "Public_policy_1ea55534",
+ "s3PermissionsAuthenticatedUploads": "s3:PutObject",
+ "s3UploadsPolicy": "Uploads_policy_1ea55534",
+ "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
+ "s3ProtectedPolicy": "Protected_policy_1ea55534",
+ "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
+ "s3PrivatePolicy": "Private_policy_1ea55534",
+ "AuthenticatedAllowList": "ALLOW",
+ "s3ReadPolicy": "read_policy_1ea55534",
+ "s3PermissionsGuestPublic": "DISALLOW",
+ "s3PermissionsGuestUploads": "DISALLOW",
+ "GuestAllowList": "DISALLOW",
+ "triggerFunction": "NONE"
+}
\ No newline at end of file
diff --git a/amplify/backend/storage/s370dc9769/s3-cloudformation-template.json b/amplify/backend/storage/s370dc9769/s3-cloudformation-template.json
new file mode 100644
index 0000000..112e432
--- /dev/null
+++ b/amplify/backend/storage/s370dc9769/s3-cloudformation-template.json
@@ -0,0 +1,657 @@
+{
+ "AWSTemplateFormatVersion": "2010-09-09",
+ "Description": "S3 resource stack creation using Amplify CLI",
+ "Parameters": {
+ "bucketName": {
+ "Type": "String"
+ },
+ "authPolicyName": {
+ "Type": "String"
+ },
+ "unauthPolicyName": {
+ "Type": "String"
+ },
+ "authRoleName": {
+ "Type": "String"
+ },
+ "unauthRoleName": {
+ "Type": "String"
+ },
+ "s3PublicPolicy": {
+ "Type": "String",
+ "Default" : "NONE"
+ },
+ "s3PrivatePolicy": {
+ "Type": "String",
+ "Default" : "NONE"
+ },
+ "s3ProtectedPolicy": {
+ "Type": "String",
+ "Default" : "NONE"
+ },
+ "s3UploadsPolicy": {
+ "Type": "String",
+ "Default" : "NONE"
+ },
+ "s3ReadPolicy": {
+ "Type": "String",
+ "Default" : "NONE"
+ },
+ "s3PermissionsAuthenticatedPublic": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "s3PermissionsAuthenticatedProtected": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "s3PermissionsAuthenticatedPrivate": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "s3PermissionsAuthenticatedUploads": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "s3PermissionsGuestPublic": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "s3PermissionsGuestUploads": {
+ "Type": "String",
+ "Default" : "DISALLOW" },
+ "AuthenticatedAllowList": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "GuestAllowList": {
+ "Type": "String",
+ "Default" : "DISALLOW"
+ },
+ "selectedGuestPermissions": {
+ "Type": "CommaDelimitedList",
+ "Default" : "NONE"
+ },
+ "selectedAuthenticatedPermissions": {
+ "Type": "CommaDelimitedList",
+ "Default" : "NONE"
+ },
+ "env": {
+ "Type": "String"
+ },
+ "triggerFunction": {
+ "Type": "String"
+ }
+
+
+ },
+ "Conditions": {
+ "ShouldNotCreateEnvResources": {
+ "Fn::Equals": [
+ {
+ "Ref": "env"
+ },
+ "NONE"
+ ]
+ },
+ "CreateAuthPublic": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsAuthenticatedPublic"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "CreateAuthProtected": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsAuthenticatedProtected"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "CreateAuthPrivate": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsAuthenticatedPrivate"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "CreateAuthUploads": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsAuthenticatedUploads"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "CreateGuestPublic": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsGuestPublic"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "CreateGuestUploads": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "s3PermissionsGuestUploads"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "AuthReadAndList": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "AuthenticatedAllowList"},
+ "DISALLOW"
+ ]
+ }]
+ },
+ "GuestReadAndList": {
+ "Fn::Not" : [{
+ "Fn::Equals" : [
+ {"Ref" : "GuestAllowList"},
+ "DISALLOW"
+ ]
+ }]
+ }
+ },
+ "Resources": {
+ "S3Bucket": {
+ "Type": "AWS::S3::Bucket",
+
+ "DeletionPolicy" : "Retain",
+ "Properties": {
+ "BucketName": {
+ "Fn::If": [
+ "ShouldNotCreateEnvResources",
+ {
+ "Ref": "bucketName"
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Ref": "bucketName"
+ },
+ {
+ "Fn::Select": [
+ 3,
+ {
+ "Fn::Split": [
+ "-",
+ {
+ "Ref": "AWS::StackName"
+ }
+ ]
+ }
+ ]
+ },
+ "-",
+ {
+ "Ref": "env"
+ }
+ ]
+ ]
+ }
+ ]
+ },
+
+ "CorsConfiguration": {
+ "CorsRules": [
+ {
+ "AllowedHeaders": [
+ "*"
+ ],
+ "AllowedMethods": [
+ "GET",
+ "HEAD",
+ "PUT",
+ "POST",
+ "DELETE"
+ ],
+ "AllowedOrigins": [
+ "*"
+ ],
+ "ExposedHeaders": [
+ "x-amz-server-side-encryption",
+ "x-amz-request-id",
+ "x-amz-id-2",
+ "ETag"
+ ],
+ "Id": "S3CORSRuleId1",
+ "MaxAge": "3000"
+ }
+ ]
+ }
+ }
+ },
+
+
+ "S3AuthPublicPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateAuthPublic",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3PublicPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "authRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsAuthenticatedPublic"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/public/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3AuthProtectedPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateAuthProtected",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3ProtectedPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "authRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsAuthenticatedProtected"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/protected/${cognito-identity.amazonaws.com:sub}/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3AuthPrivatePolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateAuthPrivate",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3PrivatePolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "authRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsAuthenticatedPrivate"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/private/${cognito-identity.amazonaws.com:sub}/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3AuthUploadPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateAuthUploads",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3UploadsPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "authRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsAuthenticatedUploads"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/uploads/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3AuthReadPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "AuthReadAndList",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3ReadPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "authRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:GetObject"
+ ],
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/protected/*"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:ListBucket"
+ ],
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ }
+ ]
+ ]
+ }
+ ],
+ "Condition": {
+ "StringLike": {
+ "s3:prefix": [
+ "public/",
+ "public/*",
+ "protected/",
+ "protected/*",
+ "private/${cognito-identity.amazonaws.com:sub}/",
+ "private/${cognito-identity.amazonaws.com:sub}/*"
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+ },
+ "S3GuestPublicPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateGuestPublic",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3PublicPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "unauthRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsGuestPublic"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/public/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3GuestUploadPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "CreateGuestUploads",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3UploadsPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "unauthRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": {
+ "Fn::Split" : [ "," , {
+ "Ref": "s3PermissionsGuestUploads"
+ } ]
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/uploads/*"
+ ]
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "S3GuestReadPolicy": {
+ "DependsOn": [
+ "S3Bucket"
+ ],
+ "Condition": "GuestReadAndList",
+ "Type": "AWS::IAM::Policy",
+ "Properties": {
+ "PolicyName": {
+ "Ref": "s3ReadPolicy"
+ },
+ "Roles": [
+ {
+ "Ref": "unauthRoleName"
+ }
+ ],
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:GetObject"
+ ],
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ },
+ "/protected/*"
+ ]
+ ]
+ }
+ ]
+ },
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:ListBucket"
+ ],
+ "Resource": [
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:s3:::",
+ {
+ "Ref": "S3Bucket"
+ }
+ ]
+ ]
+ }
+ ],
+ "Condition": {
+ "StringLike": {
+ "s3:prefix": [
+ "public/",
+ "public/*",
+ "protected/",
+ "protected/*"
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "Outputs": {
+ "BucketName": {
+ "Value": {
+ "Ref": "S3Bucket"
+ },
+ "Description": "Bucket name for the S3 bucket"
+ },
+ "Region": {
+ "Value": {
+ "Ref": "AWS::Region"
+ }
+ }
+ }
+}
diff --git a/amplify/backend/storage/s370dc9769/storage-params.json b/amplify/backend/storage/s370dc9769/storage-params.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/amplify/backend/storage/s370dc9769/storage-params.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/amplify/backend/storage/s3729634dc/cli-inputs.json b/amplify/backend/storage/s3729634dc/cli-inputs.json
deleted file mode 100644
index dca860a..0000000
--- a/amplify/backend/storage/s3729634dc/cli-inputs.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "resourceName": "s3729634dc",
- "policyUUID": "729634dc",
- "bucketName": "thriftyd7168981e1464cb390e147a4f72cb3f5",
- "storageAccess": "authAndGuest",
- "guestAccess": [
- "CREATE_AND_UPDATE",
- "READ",
- "DELETE"
- ],
- "authAccess": [
- "CREATE_AND_UPDATE",
- "READ",
- "DELETE"
- ],
- "triggerFunction": "NONE",
- "groupAccess": {}
-}
\ No newline at end of file
diff --git a/amplify/backend/types/amplify-dependent-resources-ref.d.ts b/amplify/backend/types/amplify-dependent-resources-ref.d.ts
index e460eb9..ed6ad2d 100644
--- a/amplify/backend/types/amplify-dependent-resources-ref.d.ts
+++ b/amplify/backend/types/amplify-dependent-resources-ref.d.ts
@@ -1,25 +1,23 @@
export type AmplifyDependentResourcesAttributes = {
"api": {
- "thrifty": {
- "GraphQLAPIKeyOutput": "string",
+ "thrifty2": {
"GraphQLAPIIdOutput": "string",
"GraphQLAPIEndpointOutput": "string"
}
},
"auth": {
- "thrifty880b2640": {
+ "thrifty23c488d7e": {
"IdentityPoolId": "string",
"IdentityPoolName": "string",
"UserPoolId": "string",
"UserPoolArn": "string",
"UserPoolName": "string",
"AppClientIDWeb": "string",
- "AppClientID": "string",
- "CreatedSNSRole": "string"
+ "AppClientID": "string"
}
},
"storage": {
- "s3729634dc": {
+ "s370dc9769": {
"BucketName": "string",
"Region": "string"
}
diff --git a/amplify/cli.json b/amplify/cli.json
index a2b57f6..1b1a4f5 100644
--- a/amplify/cli.json
+++ b/amplify/cli.json
@@ -1,51 +1,48 @@
{
- "features": {
- "graphqltransformer": {
- "addmissingownerfields": false,
- "improvepluralization": false,
- "validatetypenamereservedwords": true,
- "useexperimentalpipelinedtransformer": true,
- "enableiterativegsiupdates": false,
- "secondarykeyasgsi": false,
- "skipoverridemutationinputtypes": false,
- "transformerversion": 2,
- "suppressschemamigrationprompt": true
- },
- "frontend-ios": {
- "enablexcodeintegration": false
- },
- "auth": {
- "enablecaseinsensitivity": false,
- "useinclusiveterminology": false,
- "breakcirculardependency": false,
- "forcealiasattributes": false,
- "useenabledmfas": false
- },
- "codegen": {
- "useappsyncmodelgenplugin": false,
- "usedocsgeneratorplugin": false,
- "usetypesgeneratorplugin": false,
- "cleangeneratedmodelsdirectory": false,
- "retaincasestyle": false,
- "addtimestampfields": false,
- "handlelistnullabilitytransparently": false,
- "emitauthprovider": false,
- "generateindexrules": false,
- "enabledartnullsafety": false
- },
- "appsync": {
- "generategraphqlpermissions": false
- },
- "latestregionsupport": {
- "pinpoint": 0,
- "translate": 0,
- "transcribe": 0,
- "rekognition": 0,
- "textract": 0,
- "comprehend": 0
- },
- "project": {
- "overrides": true
+ "features": {
+ "graphqltransformer": {
+ "addmissingownerfields": true,
+ "improvepluralization": false,
+ "validatetypenamereservedwords": true,
+ "useexperimentalpipelinedtransformer": false,
+ "enableiterativegsiupdates": true,
+ "secondarykeyasgsi": true,
+ "skipoverridemutationinputtypes": true
+ },
+ "frontend-ios": {
+ "enablexcodeintegration": true
+ },
+ "auth": {
+ "enablecaseinsensitivity": true,
+ "useinclusiveterminology": true,
+ "breakcirculardependency": true,
+ "forcealiasattributes": false
+ },
+ "codegen": {
+ "useappsyncmodelgenplugin": true,
+ "usedocsgeneratorplugin": true,
+ "usetypesgeneratorplugin": true,
+ "cleangeneratedmodelsdirectory": true,
+ "retaincasestyle": true,
+ "addtimestampfields": true,
+ "handlelistnullabilitytransparently": true,
+ "emitauthprovider": true,
+ "generateindexrules": true,
+ "enabledartnullsafety": true
+ },
+ "appsync": {
+ "generategraphqlpermissions": true
+ },
+ "latestregionsupport": {
+ "pinpoint": 1,
+ "translate": 1,
+ "transcribe": 1,
+ "rekognition": 1,
+ "textract": 1,
+ "comprehend": 1
+ },
+ "project": {
+ "overrides": true
+ }
}
- }
}
\ No newline at end of file
diff --git a/amplify/team-provider-info.json b/amplify/team-provider-info.json
index d233e91..63268b5 100644
--- a/amplify/team-provider-info.json
+++ b/amplify/team-provider-info.json
@@ -1,20 +1,19 @@
{
- "dev": {
+ "app": {
"awscloudformation": {
- "AuthRoleName": "amplify-thrifty-dev-121359-authRole",
- "UnauthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty-dev-121359-unauthRole",
- "AuthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty-dev-121359-authRole",
+ "AuthRoleName": "amplify-thrifty2-app-11615-authRole",
+ "UnauthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty2-app-11615-unauthRole",
+ "AuthRoleArn": "arn:aws:iam::459760485083:role/amplify-thrifty2-app-11615-authRole",
"Region": "eu-central-1",
- "DeploymentBucketName": "amplify-thrifty-dev-121359-deployment",
- "UnauthRoleName": "amplify-thrifty-dev-121359-unauthRole",
- "StackName": "amplify-thrifty-dev-121359",
- "StackId": "arn:aws:cloudformation:eu-central-1:459760485083:stack/amplify-thrifty-dev-121359/6a2ae600-528f-11ec-802c-0258f60c3dac",
- "AmplifyAppId": "d1168v675m5389"
+ "DeploymentBucketName": "amplify-thrifty2-app-11615-deployment",
+ "UnauthRoleName": "amplify-thrifty2-app-11615-unauthRole",
+ "StackName": "amplify-thrifty2-app-11615",
+ "StackId": "arn:aws:cloudformation:eu-central-1:459760485083:stack/amplify-thrifty2-app-11615/b0f400e0-52fc-11ec-b5ff-0a4e79c28f7a",
+ "AmplifyAppId": "d5gnyjf8rb4i4"
},
"categories": {
"auth": {
- "thrifty880b2640": {},
- "true": {}
+ "thrifty23c488d7e": {}
}
}
}
diff --git a/app/build.gradle b/app/build.gradle
index a5e0539..550a404 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -97,6 +97,13 @@ dependencies {
// location
implementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'com.google.android.gms:play-services-maps:18.0.0'
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support.constraint:constraint-layout:2.0.4'
+ implementation 'com.google.firebase:firebase-database:20.0.3'
+ implementation 'com.google.firebase:firebase-auth:21.0.1'
+ implementation 'com.google.android.gms:play-services-maps:18.0.0'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
apply plugin: 'com.google.gms.google-services'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e829941..40b52ce 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -66,6 +83,15 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/amplifyframework/datastore/generated/model/AmplifyModelProvider.java b/app/src/main/java/com/amplifyframework/datastore/generated/model/AmplifyModelProvider.java
index 350f6e7..c5569f5 100644
--- a/app/src/main/java/com/amplifyframework/datastore/generated/model/AmplifyModelProvider.java
+++ b/app/src/main/java/com/amplifyframework/datastore/generated/model/AmplifyModelProvider.java
@@ -13,7 +13,7 @@
*/
public final class AmplifyModelProvider implements ModelProvider {
- private static final String AMPLIFY_MODEL_VERSION = "60f05c329e96e718a1c603e8ce306b24";
+ private static final String AMPLIFY_MODEL_VERSION = "52523adac5d643063a009102021f267d";
private static AmplifyModelProvider amplifyGeneratedModelInstance;
private AmplifyModelProvider() {
@@ -34,7 +34,7 @@ public static AmplifyModelProvider getInstance() {
@Override
public Set> models() {
final Set> modifiableSet = new HashSet<>(
- Arrays.>asList(Product.class, UserCart.class, User.class, Favourites.class, Category.class)
+ Arrays.>asList(Favorite.class, User.class, Category.class, Product.class)
);
return Immutable.of(modifiableSet);
diff --git a/app/src/main/java/com/amplifyframework/datastore/generated/model/Category.java b/app/src/main/java/com/amplifyframework/datastore/generated/model/Category.java
index 41adec4..534b2a4 100644
--- a/app/src/main/java/com/amplifyframework/datastore/generated/model/Category.java
+++ b/app/src/main/java/com/amplifyframework/datastore/generated/model/Category.java
@@ -1,5 +1,6 @@
package com.amplifyframework.datastore.generated.model;
+import com.amplifyframework.core.model.temporal.Temporal;
import java.util.List;
import java.util.UUID;
@@ -21,13 +22,15 @@
/** This is an auto generated class representing the Category type in your schema. */
@SuppressWarnings("all")
@ModelConfig(pluralName = "Categories", authRules = {
- @AuthRule(allow = AuthStrategy.PUBLIC, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
+ @AuthRule(allow = AuthStrategy.PRIVATE, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
})
public final class Category implements Model {
- public static final QueryField ID = field("id");
- public static final QueryField NAME = field("name");
+ public static final QueryField ID = field("Category", "id");
+ public static final QueryField NAME = field("Category", "name");
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="String", isRequired = true) String name;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime createdAt;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime updatedAt;
public String getId() {
return id;
}
@@ -36,6 +39,14 @@ public String getName() {
return name;
}
+ public Temporal.DateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public Temporal.DateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
private Category(String id, String name) {
this.id = id;
this.name = name;
@@ -50,7 +61,9 @@ public boolean equals(Object obj) {
} else {
Category category = (Category) obj;
return ObjectsCompat.equals(getId(), category.getId()) &&
- ObjectsCompat.equals(getName(), category.getName());
+ ObjectsCompat.equals(getName(), category.getName()) &&
+ ObjectsCompat.equals(getCreatedAt(), category.getCreatedAt()) &&
+ ObjectsCompat.equals(getUpdatedAt(), category.getUpdatedAt());
}
}
@@ -59,6 +72,8 @@ public int hashCode() {
return new StringBuilder()
.append(getId())
.append(getName())
+ .append(getCreatedAt())
+ .append(getUpdatedAt())
.toString()
.hashCode();
}
@@ -68,7 +83,9 @@ public String toString() {
return new StringBuilder()
.append("Category {")
.append("id=" + String.valueOf(getId()) + ", ")
- .append("name=" + String.valueOf(getName()))
+ .append("name=" + String.valueOf(getName()) + ", ")
+ .append("createdAt=" + String.valueOf(getCreatedAt()) + ", ")
+ .append("updatedAt=" + String.valueOf(getUpdatedAt()))
.append("}")
.toString();
}
@@ -84,18 +101,8 @@ public static NameStep builder() {
* in a relationship.
* @param id the id of the existing item this instance will represent
* @return an instance of this model with only ID populated
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
public static Category justId(String id) {
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException(
- "Model IDs must be unique in the format of UUID. This method is for creating instances " +
- "of an existing object with only its ID field for sending as a mutation parameter. When " +
- "creating a new object, use the standard builder method and leave the ID field blank."
- );
- }
return new Category(
id,
null
@@ -113,7 +120,7 @@ public interface NameStep {
public interface BuildStep {
Category build();
- BuildStep id(String id) throws IllegalArgumentException;
+ BuildStep id(String id);
}
@@ -137,22 +144,11 @@ public BuildStep name(String name) {
}
/**
- * WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
- * This should only be set when referring to an already existing object.
* @param id id
* @return Current Builder instance, for fluent method chaining
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
- public BuildStep id(String id) throws IllegalArgumentException {
+ public BuildStep id(String id) {
this.id = id;
-
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
- exception);
- }
-
return this;
}
}
diff --git a/app/src/main/java/com/amplifyframework/datastore/generated/model/Favorite.java b/app/src/main/java/com/amplifyframework/datastore/generated/model/Favorite.java
index 2eafb21..58c2d7b 100644
--- a/app/src/main/java/com/amplifyframework/datastore/generated/model/Favorite.java
+++ b/app/src/main/java/com/amplifyframework/datastore/generated/model/Favorite.java
@@ -1,5 +1,6 @@
package com.amplifyframework.datastore.generated.model;
+import com.amplifyframework.core.model.temporal.Temporal;
import java.util.List;
import java.util.UUID;
@@ -21,23 +22,69 @@
/** This is an auto generated class representing the Favorite type in your schema. */
@SuppressWarnings("all")
@ModelConfig(pluralName = "Favorites", authRules = {
- @AuthRule(allow = AuthStrategy.PUBLIC, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
+ @AuthRule(allow = AuthStrategy.PRIVATE, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
})
+@Index(name = "byUser", fields = {"userID"})
public final class Favorite implements Model {
- public static final QueryField ID = field("id");
- public static final QueryField USER_ID = field("userID");
+ public static final QueryField ID = field("Favorite", "id");
+ public static final QueryField TITLE_FAV = field("Favorite", "titleFav");
+ public static final QueryField IMAGE_FAV = field("Favorite", "imageFav");
+ public static final QueryField PRICE_FAV = field("Favorite", "priceFav");
+ public static final QueryField SIZE_FAV = field("Favorite", "sizeFav");
+ public static final QueryField CATEGORY_FAV = field("Favorite", "categoryFav");
+ public static final QueryField USER_ID = field("Favorite", "userID");
private final @ModelField(targetType="ID", isRequired = true) String id;
+ private final @ModelField(targetType="String", isRequired = true) String titleFav;
+ private final @ModelField(targetType="String", isRequired = true) String imageFav;
+ private final @ModelField(targetType="String", isRequired = true) String priceFav;
+ private final @ModelField(targetType="String", isRequired = true) String sizeFav;
+ private final @ModelField(targetType="String", isRequired = true) String categoryFav;
private final @ModelField(targetType="ID") String userID;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime createdAt;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime updatedAt;
public String getId() {
return id;
}
+ public String getTitleFav() {
+ return titleFav;
+ }
+
+ public String getImageFav() {
+ return imageFav;
+ }
+
+ public String getPriceFav() {
+ return priceFav;
+ }
+
+ public String getSizeFav() {
+ return sizeFav;
+ }
+
+ public String getCategoryFav() {
+ return categoryFav;
+ }
+
public String getUserId() {
return userID;
}
- private Favorite(String id, String userID) {
+ public Temporal.DateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public Temporal.DateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
+ private Favorite(String id, String titleFav, String imageFav, String priceFav, String sizeFav, String categoryFav, String userID) {
this.id = id;
+ this.titleFav = titleFav;
+ this.imageFav = imageFav;
+ this.priceFav = priceFav;
+ this.sizeFav = sizeFav;
+ this.categoryFav = categoryFav;
this.userID = userID;
}
@@ -50,7 +97,14 @@ public boolean equals(Object obj) {
} else {
Favorite favorite = (Favorite) obj;
return ObjectsCompat.equals(getId(), favorite.getId()) &&
- ObjectsCompat.equals(getUserId(), favorite.getUserId());
+ ObjectsCompat.equals(getTitleFav(), favorite.getTitleFav()) &&
+ ObjectsCompat.equals(getImageFav(), favorite.getImageFav()) &&
+ ObjectsCompat.equals(getPriceFav(), favorite.getPriceFav()) &&
+ ObjectsCompat.equals(getSizeFav(), favorite.getSizeFav()) &&
+ ObjectsCompat.equals(getCategoryFav(), favorite.getCategoryFav()) &&
+ ObjectsCompat.equals(getUserId(), favorite.getUserId()) &&
+ ObjectsCompat.equals(getCreatedAt(), favorite.getCreatedAt()) &&
+ ObjectsCompat.equals(getUpdatedAt(), favorite.getUpdatedAt());
}
}
@@ -58,7 +112,14 @@ public boolean equals(Object obj) {
public int hashCode() {
return new StringBuilder()
.append(getId())
+ .append(getTitleFav())
+ .append(getImageFav())
+ .append(getPriceFav())
+ .append(getSizeFav())
+ .append(getCategoryFav())
.append(getUserId())
+ .append(getCreatedAt())
+ .append(getUpdatedAt())
.toString()
.hashCode();
}
@@ -68,12 +129,19 @@ public String toString() {
return new StringBuilder()
.append("Favorite {")
.append("id=" + String.valueOf(getId()) + ", ")
- .append("userID=" + String.valueOf(getUserId()))
+ .append("titleFav=" + String.valueOf(getTitleFav()) + ", ")
+ .append("imageFav=" + String.valueOf(getImageFav()) + ", ")
+ .append("priceFav=" + String.valueOf(getPriceFav()) + ", ")
+ .append("sizeFav=" + String.valueOf(getSizeFav()) + ", ")
+ .append("categoryFav=" + String.valueOf(getCategoryFav()) + ", ")
+ .append("userID=" + String.valueOf(getUserId()) + ", ")
+ .append("createdAt=" + String.valueOf(getCreatedAt()) + ", ")
+ .append("updatedAt=" + String.valueOf(getUpdatedAt()))
.append("}")
.toString();
}
- public static BuildStep builder() {
+ public static TitleFavStep builder() {
return new Builder();
}
@@ -84,37 +152,67 @@ public static BuildStep builder() {
* in a relationship.
* @param id the id of the existing item this instance will represent
* @return an instance of this model with only ID populated
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
public static Favorite justId(String id) {
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException(
- "Model IDs must be unique in the format of UUID. This method is for creating instances " +
- "of an existing object with only its ID field for sending as a mutation parameter. When " +
- "creating a new object, use the standard builder method and leave the ID field blank."
- );
- }
return new Favorite(
id,
+ null,
+ null,
+ null,
+ null,
+ null,
null
);
}
public CopyOfBuilder copyOfBuilder() {
return new CopyOfBuilder(id,
+ titleFav,
+ imageFav,
+ priceFav,
+ sizeFav,
+ categoryFav,
userID);
}
+ public interface TitleFavStep {
+ ImageFavStep titleFav(String titleFav);
+ }
+
+
+ public interface ImageFavStep {
+ PriceFavStep imageFav(String imageFav);
+ }
+
+
+ public interface PriceFavStep {
+ SizeFavStep priceFav(String priceFav);
+ }
+
+
+ public interface SizeFavStep {
+ CategoryFavStep sizeFav(String sizeFav);
+ }
+
+
+ public interface CategoryFavStep {
+ BuildStep categoryFav(String categoryFav);
+ }
+
+
public interface BuildStep {
Favorite build();
- BuildStep id(String id) throws IllegalArgumentException;
+ BuildStep id(String id);
BuildStep userId(String userId);
}
- public static class Builder implements BuildStep {
+ public static class Builder implements TitleFavStep, ImageFavStep, PriceFavStep, SizeFavStep, CategoryFavStep, BuildStep {
private String id;
+ private String titleFav;
+ private String imageFav;
+ private String priceFav;
+ private String sizeFav;
+ private String categoryFav;
private String userID;
@Override
public Favorite build() {
@@ -122,9 +220,49 @@ public Favorite build() {
return new Favorite(
id,
+ titleFav,
+ imageFav,
+ priceFav,
+ sizeFav,
+ categoryFav,
userID);
}
+ @Override
+ public ImageFavStep titleFav(String titleFav) {
+ Objects.requireNonNull(titleFav);
+ this.titleFav = titleFav;
+ return this;
+ }
+
+ @Override
+ public PriceFavStep imageFav(String imageFav) {
+ Objects.requireNonNull(imageFav);
+ this.imageFav = imageFav;
+ return this;
+ }
+
+ @Override
+ public SizeFavStep priceFav(String priceFav) {
+ Objects.requireNonNull(priceFav);
+ this.priceFav = priceFav;
+ return this;
+ }
+
+ @Override
+ public CategoryFavStep sizeFav(String sizeFav) {
+ Objects.requireNonNull(sizeFav);
+ this.sizeFav = sizeFav;
+ return this;
+ }
+
+ @Override
+ public BuildStep categoryFav(String categoryFav) {
+ Objects.requireNonNull(categoryFav);
+ this.categoryFav = categoryFav;
+ return this;
+ }
+
@Override
public BuildStep userId(String userId) {
this.userID = userId;
@@ -132,31 +270,50 @@ public BuildStep userId(String userId) {
}
/**
- * WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
- * This should only be set when referring to an already existing object.
* @param id id
* @return Current Builder instance, for fluent method chaining
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
- public BuildStep id(String id) throws IllegalArgumentException {
+ public BuildStep id(String id) {
this.id = id;
-
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
- exception);
- }
-
return this;
}
}
public final class CopyOfBuilder extends Builder {
- private CopyOfBuilder(String id, String userId) {
+ private CopyOfBuilder(String id, String titleFav, String imageFav, String priceFav, String sizeFav, String categoryFav, String userId) {
super.id(id);
- super.userId(userId);
+ super.titleFav(titleFav)
+ .imageFav(imageFav)
+ .priceFav(priceFav)
+ .sizeFav(sizeFav)
+ .categoryFav(categoryFav)
+ .userId(userId);
+ }
+
+ @Override
+ public CopyOfBuilder titleFav(String titleFav) {
+ return (CopyOfBuilder) super.titleFav(titleFav);
+ }
+
+ @Override
+ public CopyOfBuilder imageFav(String imageFav) {
+ return (CopyOfBuilder) super.imageFav(imageFav);
+ }
+
+ @Override
+ public CopyOfBuilder priceFav(String priceFav) {
+ return (CopyOfBuilder) super.priceFav(priceFav);
+ }
+
+ @Override
+ public CopyOfBuilder sizeFav(String sizeFav) {
+ return (CopyOfBuilder) super.sizeFav(sizeFav);
+ }
+
+ @Override
+ public CopyOfBuilder categoryFav(String categoryFav) {
+ return (CopyOfBuilder) super.categoryFav(categoryFav);
}
@Override
diff --git a/app/src/main/java/com/amplifyframework/datastore/generated/model/Product.java b/app/src/main/java/com/amplifyframework/datastore/generated/model/Product.java
index 3eb4d4e..0cc6a03 100644
--- a/app/src/main/java/com/amplifyframework/datastore/generated/model/Product.java
+++ b/app/src/main/java/com/amplifyframework/datastore/generated/model/Product.java
@@ -1,5 +1,6 @@
package com.amplifyframework.datastore.generated.model;
+import com.amplifyframework.core.model.temporal.Temporal;
import java.util.List;
import java.util.UUID;
@@ -21,25 +22,28 @@
/** This is an auto generated class representing the Product type in your schema. */
@SuppressWarnings("all")
@ModelConfig(pluralName = "Products", authRules = {
- @AuthRule(allow = AuthStrategy.PUBLIC, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
+ @AuthRule(allow = AuthStrategy.PRIVATE, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
})
+@Index(name = "byCategory", fields = {"categoryID"})
public final class Product implements Model {
- public static final QueryField ID = field("id");
- public static final QueryField TITLE = field("title");
- public static final QueryField DESCRIPTION = field("description");
- public static final QueryField PRICE = field("price");
- public static final QueryField SIZE = field("size");
- public static final QueryField COLOR = field("color");
- public static final QueryField IMAGE = field("image");
- public static final QueryField CATEGORY_ID = field("categoryID");
+ public static final QueryField ID = field("Product", "id");
+ public static final QueryField TITLE = field("Product", "title");
+ public static final QueryField DESCRIPTION = field("Product", "description");
+ public static final QueryField PRICE = field("Product", "price");
+ public static final QueryField SIZE = field("Product", "size");
+ public static final QueryField COLOR = field("Product", "color");
+ public static final QueryField CATEGORY_ID = field("Product", "categoryID");
+ public static final QueryField IMAGE = field("Product", "image");
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="String", isRequired = true) String title;
private final @ModelField(targetType="String", isRequired = true) String description;
private final @ModelField(targetType="String", isRequired = true) String price;
private final @ModelField(targetType="String", isRequired = true) String size;
private final @ModelField(targetType="String", isRequired = true) String color;
- private final @ModelField(targetType="String", isRequired = true) String image;
private final @ModelField(targetType="ID") String categoryID;
+ private final @ModelField(targetType="String", isRequired = true) String image;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime createdAt;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime updatedAt;
public String getId() {
return id;
}
@@ -64,23 +68,31 @@ public String getColor() {
return color;
}
+ public String getCategoryId() {
+ return categoryID;
+ }
+
public String getImage() {
return image;
}
- public String getCategoryId() {
- return categoryID;
+ public Temporal.DateTime getCreatedAt() {
+ return createdAt;
}
- private Product(String id, String title, String description, String price, String size, String color, String image, String categoryID) {
+ public Temporal.DateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
+ private Product(String id, String title, String description, String price, String size, String color, String categoryID, String image) {
this.id = id;
this.title = title;
this.description = description;
this.price = price;
this.size = size;
this.color = color;
- this.image = image;
this.categoryID = categoryID;
+ this.image = image;
}
@Override
@@ -97,8 +109,10 @@ public boolean equals(Object obj) {
ObjectsCompat.equals(getPrice(), product.getPrice()) &&
ObjectsCompat.equals(getSize(), product.getSize()) &&
ObjectsCompat.equals(getColor(), product.getColor()) &&
+ ObjectsCompat.equals(getCategoryId(), product.getCategoryId()) &&
ObjectsCompat.equals(getImage(), product.getImage()) &&
- ObjectsCompat.equals(getCategoryId(), product.getCategoryId());
+ ObjectsCompat.equals(getCreatedAt(), product.getCreatedAt()) &&
+ ObjectsCompat.equals(getUpdatedAt(), product.getUpdatedAt());
}
}
@@ -111,8 +125,10 @@ public int hashCode() {
.append(getPrice())
.append(getSize())
.append(getColor())
- .append(getImage())
.append(getCategoryId())
+ .append(getImage())
+ .append(getCreatedAt())
+ .append(getUpdatedAt())
.toString()
.hashCode();
}
@@ -127,8 +143,10 @@ public String toString() {
.append("price=" + String.valueOf(getPrice()) + ", ")
.append("size=" + String.valueOf(getSize()) + ", ")
.append("color=" + String.valueOf(getColor()) + ", ")
+ .append("categoryID=" + String.valueOf(getCategoryId()) + ", ")
.append("image=" + String.valueOf(getImage()) + ", ")
- .append("categoryID=" + String.valueOf(getCategoryId()))
+ .append("createdAt=" + String.valueOf(getCreatedAt()) + ", ")
+ .append("updatedAt=" + String.valueOf(getUpdatedAt()))
.append("}")
.toString();
}
@@ -144,18 +162,8 @@ public static TitleStep builder() {
* in a relationship.
* @param id the id of the existing item this instance will represent
* @return an instance of this model with only ID populated
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
public static Product justId(String id) {
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException(
- "Model IDs must be unique in the format of UUID. This method is for creating instances " +
- "of an existing object with only its ID field for sending as a mutation parameter. When " +
- "creating a new object, use the standard builder method and leave the ID field blank."
- );
- }
return new Product(
id,
null,
@@ -175,8 +183,8 @@ public CopyOfBuilder copyOfBuilder() {
price,
size,
color,
- image,
- categoryID);
+ categoryID,
+ image);
}
public interface TitleStep {
DescriptionStep title(String title);
@@ -210,7 +218,7 @@ public interface ImageStep {
public interface BuildStep {
Product build();
- BuildStep id(String id) throws IllegalArgumentException;
+ BuildStep id(String id);
BuildStep categoryId(String categoryId);
}
@@ -235,8 +243,8 @@ public Product build() {
price,
size,
color,
- image,
- categoryID);
+ categoryID,
+ image);
}
@Override
@@ -288,29 +296,18 @@ public BuildStep categoryId(String categoryId) {
}
/**
- * WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
- * This should only be set when referring to an already existing object.
* @param id id
* @return Current Builder instance, for fluent method chaining
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
- public BuildStep id(String id) throws IllegalArgumentException {
+ public BuildStep id(String id) {
this.id = id;
-
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
- exception);
- }
-
return this;
}
}
public final class CopyOfBuilder extends Builder {
- private CopyOfBuilder(String id, String title, String description, String price, String size, String color, String image, String categoryId) {
+ private CopyOfBuilder(String id, String title, String description, String price, String size, String color, String categoryId, String image) {
super.id(id);
super.title(title)
.description(description)
diff --git a/app/src/main/java/com/amplifyframework/datastore/generated/model/User.java b/app/src/main/java/com/amplifyframework/datastore/generated/model/User.java
index 521cbfe..1b7bb0b 100644
--- a/app/src/main/java/com/amplifyframework/datastore/generated/model/User.java
+++ b/app/src/main/java/com/amplifyframework/datastore/generated/model/User.java
@@ -1,5 +1,6 @@
package com.amplifyframework.datastore.generated.model;
+import com.amplifyframework.core.model.temporal.Temporal;
import java.util.List;
import java.util.UUID;
@@ -21,13 +22,15 @@
/** This is an auto generated class representing the User type in your schema. */
@SuppressWarnings("all")
@ModelConfig(pluralName = "Users", authRules = {
- @AuthRule(allow = AuthStrategy.PUBLIC, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
+ @AuthRule(allow = AuthStrategy.PRIVATE, operations = { ModelOperation.CREATE, ModelOperation.UPDATE, ModelOperation.DELETE, ModelOperation.READ })
})
public final class User implements Model {
- public static final QueryField ID = field("id");
- public static final QueryField EMAIL = field("email");
+ public static final QueryField ID = field("User", "id");
+ public static final QueryField EMAIL = field("User", "email");
private final @ModelField(targetType="ID", isRequired = true) String id;
private final @ModelField(targetType="String", isRequired = true) String email;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime createdAt;
+ private @ModelField(targetType="AWSDateTime", isReadOnly = true) Temporal.DateTime updatedAt;
public String getId() {
return id;
}
@@ -36,6 +39,14 @@ public String getEmail() {
return email;
}
+ public Temporal.DateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public Temporal.DateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
private User(String id, String email) {
this.id = id;
this.email = email;
@@ -50,7 +61,9 @@ public boolean equals(Object obj) {
} else {
User user = (User) obj;
return ObjectsCompat.equals(getId(), user.getId()) &&
- ObjectsCompat.equals(getEmail(), user.getEmail());
+ ObjectsCompat.equals(getEmail(), user.getEmail()) &&
+ ObjectsCompat.equals(getCreatedAt(), user.getCreatedAt()) &&
+ ObjectsCompat.equals(getUpdatedAt(), user.getUpdatedAt());
}
}
@@ -59,6 +72,8 @@ public int hashCode() {
return new StringBuilder()
.append(getId())
.append(getEmail())
+ .append(getCreatedAt())
+ .append(getUpdatedAt())
.toString()
.hashCode();
}
@@ -68,7 +83,9 @@ public String toString() {
return new StringBuilder()
.append("User {")
.append("id=" + String.valueOf(getId()) + ", ")
- .append("email=" + String.valueOf(getEmail()))
+ .append("email=" + String.valueOf(getEmail()) + ", ")
+ .append("createdAt=" + String.valueOf(getCreatedAt()) + ", ")
+ .append("updatedAt=" + String.valueOf(getUpdatedAt()))
.append("}")
.toString();
}
@@ -84,18 +101,8 @@ public static EmailStep builder() {
* in a relationship.
* @param id the id of the existing item this instance will represent
* @return an instance of this model with only ID populated
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
public static User justId(String id) {
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException(
- "Model IDs must be unique in the format of UUID. This method is for creating instances " +
- "of an existing object with only its ID field for sending as a mutation parameter. When " +
- "creating a new object, use the standard builder method and leave the ID field blank."
- );
- }
return new User(
id,
null
@@ -113,7 +120,7 @@ public interface EmailStep {
public interface BuildStep {
User build();
- BuildStep id(String id) throws IllegalArgumentException;
+ BuildStep id(String id);
}
@@ -137,22 +144,11 @@ public BuildStep email(String email) {
}
/**
- * WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
- * This should only be set when referring to an already existing object.
* @param id id
* @return Current Builder instance, for fluent method chaining
- * @throws IllegalArgumentException Checks that ID is in the proper format
*/
- public BuildStep id(String id) throws IllegalArgumentException {
+ public BuildStep id(String id) {
this.id = id;
-
- try {
- UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
- } catch (Exception exception) {
- throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
- exception);
- }
-
return this;
}
}
diff --git a/app/src/main/java/com/example/thrifty/GPSTracker.java b/app/src/main/java/com/example/thrifty/GPSTracker.java
new file mode 100644
index 0000000..b00cfdb
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/GPSTracker.java
@@ -0,0 +1,188 @@
+package com.example.thrifty;
+
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.app.Service;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.provider.Settings;
+
+/**
+ * Created by tulsi on 4/7/2018.
+ */
+public class GPSTracker extends Service implements LocationListener {
+
+ private final Context mContext;
+
+ // flag for GPS status
+ boolean isGPSEnabled = false;
+ // flag for GPS status
+ boolean canGetLocation = false;
+ Location location; // location
+ double latitude; // latitude
+ double longitude; // longitude
+
+ // The minimum distance to change Updates in meters
+ private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
+
+ // The minimum time between updates in milliseconds
+ private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
+
+ // Declaring a Location Manager
+ protected LocationManager locationManager;
+
+ public GPSTracker(Context context) {
+ this.mContext = context;
+ getLocation();
+ }
+
+ @SuppressLint("MissingPermission")
+ public Location getLocation() {
+ try {
+ locationManager = (LocationManager) mContext
+ .getSystemService(LOCATION_SERVICE);
+ // getting GPS status
+ isGPSEnabled = locationManager
+ .isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ // if GPS Enabled get lat/long using GPS Services
+ if (isGPSEnabled) {
+ this.canGetLocation = true;
+ if (location == null) {
+ locationManager.requestLocationUpdates(
+ LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES,
+ MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+ if (locationManager != null) {
+ location = locationManager
+ .getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (location != null) {
+ latitude = location.getLatitude();
+ longitude = location.getLongitude();
+ }
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return location;
+ }
+
+ /**
+ * Stop using GPS listener Calling this function will stop using GPS in your
+ * app
+ * */
+ public void stopUsingGPS() {
+ if (locationManager != null) {
+ locationManager.removeUpdates(GPSTracker.this);
+ }
+ }
+
+ /**
+ * Function to get latitude
+ * */
+ public double getLatitude() {
+ if (location != null) {
+ latitude = location.getLatitude();
+ }
+
+ // return latitude
+ return latitude;
+ }
+
+ /**
+ * Function to get longitude
+ * */
+ public double getLongitude() {
+ if (location != null) {
+ longitude = location.getLongitude();
+ }
+
+ // return longitude
+ return longitude;
+ }
+
+ /**
+ * Function to check GPS/wifi enabled
+ *
+ * @return boolean
+ * */
+ public boolean canGetLocation() {
+ return this.canGetLocation;
+ }
+
+ /**
+ * Function to show settings alert dialog On pressing Settings button will
+ * lauch Settings Options
+ * */
+ public void showSettingsAlert() {
+ AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
+
+ // Setting Dialog Title
+ alertDialog.setTitle("GPS is settings");
+
+ // Setting Dialog Message
+ alertDialog
+ .setMessage("GPS is not enabled. Do you want to go to settings menu?");
+
+ // On pressing Settings button
+ alertDialog.setPositiveButton("Settings",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = new Intent(
+ Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ mContext.startActivity(intent);
+ }
+ });
+
+ // on pressing cancel button
+ alertDialog.setNegativeButton("Cancel",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ // Showing Alert Message
+ alertDialog.show();
+ }
+
+ @Override
+ public void onLocationChanged(Location arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderDisabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onProviderEnabled(String arg0) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/thrifty/MainActivity.java b/app/src/main/java/com/example/thrifty/MainActivity.java
index 03cfcde..47e5cde 100644
--- a/app/src/main/java/com/example/thrifty/MainActivity.java
+++ b/app/src/main/java/com/example/thrifty/MainActivity.java
@@ -93,6 +93,13 @@ public void onClick(View view) {
startActivity(intent);
}
});
+// findViewById(R.id.map).setOnClickListener(new View.OnClickListener() {
+// @Override
+// public void onClick(View view) {
+// Intent intent = new Intent(MainActivity.this, Tracking.class);
+// startActivity(intent);
+// }
+// });
}
diff --git a/app/src/main/java/com/example/thrifty/MapsActivity.java b/app/src/main/java/com/example/thrifty/MapsActivity.java
new file mode 100644
index 0000000..55ba192
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/MapsActivity.java
@@ -0,0 +1,62 @@
+package com.example.thrifty;
+
+import android.os.Bundle;
+
+import androidx.fragment.app.FragmentActivity;
+
+import com.google.android.gms.maps.CameraUpdate;
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.OnMapReadyCallback;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.BitmapDescriptorFactory;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.MarkerOptions;
+
+public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
+
+ private GoogleMap mMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maps);
+ // Obtain the SupportMapFragment and get notified when the map is ready to be used.
+ SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.map);
+ mapFragment.getMapAsync(this);
+ }
+
+
+ /**
+ * Manipulates the map once available.
+ * This callback is triggered when the map is ready to be used.
+ * This is where we can add markers or lines, add listeners or move the camera. In this case,
+ * we just add a marker near Sydney, Australia.
+ * If Google Play services is not installed on the device, the user will be prompted to install
+ * it inside the SupportMapFragment. This method will only be triggered once the user has
+ * installed Google Play services and returned to the app.
+ */
+ @Override
+ public void onMapReady(GoogleMap googleMap) {
+ mMap = googleMap;
+
+ // Add a marker in Sydney and move the camera
+ LatLng sydney = new LatLng(37.391219,-121.930);
+ MarkerOptions marker = new MarkerOptions().position(sydney).title("Anuradha Rajashekar");
+ marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.userplaceholder));
+ mMap.addMarker(marker);
+ // mMap.addMarker(new MarkerOptions().position(sydney).title("Anuradha's location"));
+ mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
+ mMap.animateCamera(CameraUpdateFactory.zoomTo(17.0f));
+
+ /* LatLng location2 = new LatLng(37.402276,-121.942161);
+ mMap.addMarker(new MarkerOptions().position(location2).title("Anuradha's new location"));
+ mMap.moveCamera(CameraUpdateFactory.newLatLng(location2));*/
+
+ //zoom into a particular position
+ CameraUpdate zoom = CameraUpdateFactory.zoomTo(12);
+ mMap.moveCamera(zoom);
+ mMap.animateCamera(zoom);
+ }
+}
diff --git a/app/src/main/java/com/example/thrifty/ProductView.java b/app/src/main/java/com/example/thrifty/ProductView.java
index 178663e..63f7057 100644
--- a/app/src/main/java/com/example/thrifty/ProductView.java
+++ b/app/src/main/java/com/example/thrifty/ProductView.java
@@ -1,11 +1,19 @@
package com.example.thrifty;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.content.FileProvider;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Toast;
import android.widget.Toolbar;
import com.amplifyframework.AmplifyException;
@@ -15,6 +23,9 @@
import com.amplifyframework.datastore.AWSDataStorePlugin;
import com.amplifyframework.storage.s3.AWSS3StoragePlugin;
+import java.io.File;
+import java.io.FileOutputStream;
+
public class ProductView extends AppCompatActivity {
@Override
@@ -51,7 +62,59 @@ protected void onCreate(Bundle savedInstanceState) {
textView.setText(title);
priceTxt.setText(price);
categoryTxt.setText(category);
+ Button share = findViewById(R.id.share);
+ ImageView imageView = findViewById(R.id.itemImage);
+
+ // initialising text field where we will enter data
+ share.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Now share image function will be called
+ // here we will be passing the text to share
+ // Getting drawable value from image
+ BitmapDrawable bitmapDrawable = (BitmapDrawable) imageView.getDrawable();
+ Bitmap bitmap = bitmapDrawable.getBitmap();
+ shareImageandText(bitmap);
+ }
+ });
+
+
+ }
+ private void shareImageandText(Bitmap bitmap) {
+ Uri uri = getmageToShare(bitmap);
+ Intent intent = new Intent(Intent.ACTION_SEND);
+
+ // putting uri of image to be shared
+ intent.putExtra(Intent.EXTRA_STREAM, uri);
+ // adding text to share
+ intent.putExtra(Intent.EXTRA_TEXT, "Sharing Image");
+ // Add subject Here
+ intent.putExtra(Intent.EXTRA_SUBJECT, "Subject Here");
+
+ // setting type to image
+ intent.setType("image/png");
+
+ // calling startactivity() to share
+ startActivity(Intent.createChooser(intent, "Share Via"));
+ }
+
+ // Retrieving the url to share
+ private Uri getmageToShare(Bitmap bitmap) {
+ File imagefolder = new File(getCacheDir(), "images");
+ Uri uri = null;
+ try {
+ imagefolder.mkdirs();
+ File file = new File(imagefolder, "shared_image.png");
+ FileOutputStream outputStream = new FileOutputStream(file);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
+ outputStream.flush();
+ outputStream.close();
+ uri = FileProvider.getUriForFile(this, "com.anni.shareimage.fileprovider", file);
+ } catch (Exception e) {
+ Toast.makeText(this, "" + e.getMessage(), Toast.LENGTH_LONG).show();
+ }
+ return uri;
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/thrifty/Tracking.java b/app/src/main/java/com/example/thrifty/Tracking.java
new file mode 100644
index 0000000..ac5fea2
--- /dev/null
+++ b/app/src/main/java/com/example/thrifty/Tracking.java
@@ -0,0 +1,68 @@
+package com.example.thrifty;
+
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
+import com.google.firebase.database.DatabaseReference;
+import com.google.firebase.database.FirebaseDatabase;
+
+public class Tracking extends AppCompatActivity {
+
+ private Button btnShowLocation,btnshowMap;
+ FirebaseDatabase database;
+ DatabaseReference myRef;
+
+ private static final int REQUEST_CODE_PERMISSION =2;
+ String mPermission = android.Manifest.permission.ACCESS_FINE_LOCATION;
+ GPSTracker gps;
+ TextView location;
+ String value =null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_tracking);
+
+ try{
+ if (ActivityCompat.checkSelfPermission(this,mPermission)!= PackageManager.PERMISSION_GRANTED){
+ ActivityCompat.requestPermissions(this,new String[]{mPermission},REQUEST_CODE_PERMISSION);
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ btnShowLocation=(Button)findViewById(R.id.button);
+ btnshowMap=(Button)findViewById(R.id.button2);
+ btnShowLocation.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ gps = new GPSTracker(Tracking.this);
+ location=(TextView)findViewById(R.id.Location);
+ if (gps.canGetLocation()){
+ double latitude = gps.getLatitude();
+ double longitude = gps.getLongitude();
+ database = FirebaseDatabase.getInstance();
+ location.setText(latitude+""+longitude);
+ myRef = database.getReference("Location");
+ myRef.setValue(latitude+","+longitude);
+ }else{
+ gps.showSettingsAlert();
+ }
+ }
+
+ });
+ }
+
+ public void Map(View view){
+
+
+ Intent intent=new Intent(getApplicationContext(),MapsActivity.class);
+ startActivity(intent);
+ }
+}
diff --git a/app/src/main/res/drawable-v24/userplaceholder.png b/app/src/main/res/drawable-v24/userplaceholder.png
new file mode 100644
index 0000000..62ad490
Binary files /dev/null and b/app/src/main/res/drawable-v24/userplaceholder.png differ
diff --git a/app/src/main/res/drawable/image1.png b/app/src/main/res/drawable/image1.png
new file mode 100644
index 0000000..4a0fa16
Binary files /dev/null and b/app/src/main/res/drawable/image1.png differ
diff --git a/app/src/main/res/drawable/userplaceholder.png b/app/src/main/res/drawable/userplaceholder.png
new file mode 100644
index 0000000..62ad490
Binary files /dev/null and b/app/src/main/res/drawable/userplaceholder.png differ
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 2ae910d..e18e687 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -90,6 +90,9 @@
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp" />
+
+
+
@@ -136,4 +139,14 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.975" />
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_maps.xml b/app/src/main/res/layout/activity_maps.xml
new file mode 100644
index 0000000..39c3086
--- /dev/null
+++ b/app/src/main/res/layout/activity_maps.xml
@@ -0,0 +1,7 @@
+
diff --git a/app/src/main/res/layout/activity_product_view.xml b/app/src/main/res/layout/activity_product_view.xml
index 7a42762..d90128f 100644
--- a/app/src/main/res/layout/activity_product_view.xml
+++ b/app/src/main/res/layout/activity_product_view.xml
@@ -42,10 +42,10 @@
android:layout_below="@+id/addToCart"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
+ android:layout_marginBottom="10dp"
android:elevation="5dp"
android:padding="10dp"
- android:text="Add To Wishlist"
- android:layout_marginBottom="10dp"/>
+ android:text="Add To Wishlist" />
+ android:layout_marginTop="10dp"
+ android:src="@drawable/image1"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2d3b0cb..487a620 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -22,5 +22,6 @@
Hello blank fragment
+ Click here to Share
\ No newline at end of file
diff --git a/app/src/main/res/xml/paths.xml b/app/src/main/res/xml/paths.xml
new file mode 100644
index 0000000..3c0e1a8
--- /dev/null
+++ b/app/src/main/res/xml/paths.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 1ea9c4f..5345fe0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,5 +17,5 @@ buildscript {
task clean(type: Delete) {
delete rootProject.buildDir
}
-apply plugin: 'com.amplifyframework.amplifytools'
+//apply plugin: 'com.amplifyframework.amplifytools'