diff --git a/amplify/backend/backend-config.json b/amplify/backend/backend-config.json index 2a3bc71..6f6535a 100644 --- a/amplify/backend/backend-config.json +++ b/amplify/backend/backend-config.json @@ -11,5 +11,11 @@ "providerPlugin": "awscloudformation", "dependsOn": [] } + }, + "storage": { + "hpiotuserstorage": { + "service": "S3", + "providerPlugin": "awscloudformation" + } } } \ No newline at end of file diff --git a/amplify/backend/storage/hpiotuserstorage/parameters.json b/amplify/backend/storage/hpiotuserstorage/parameters.json new file mode 100644 index 0000000..82fc310 --- /dev/null +++ b/amplify/backend/storage/hpiotuserstorage/parameters.json @@ -0,0 +1,34 @@ +{ + "bucketName": "hpiotuserstorage", + "authPolicyName": "s3_amplify_ba83ba82", + "unauthPolicyName": "s3_amplify_ba83ba82", + "authRoleName": { + "Ref": "AuthRoleName" + }, + "unauthRoleName": { + "Ref": "UnauthRoleName" + }, + "selectedGuestPermissions": [ + "s3:GetObject", + "s3:ListBucket" + ], + "selectedAuthenticatedPermissions": [ + "s3:PutObject", + "s3:GetObject", + "s3:ListBucket" + ], + "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject", + "s3PublicPolicy": "Public_policy_4ff86870", + "s3PermissionsAuthenticatedUploads": "s3:PutObject", + "s3UploadsPolicy": "Uploads_policy_4ff86870", + "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject", + "s3ProtectedPolicy": "Protected_policy_4ff86870", + "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject", + "s3PrivatePolicy": "Private_policy_4ff86870", + "AuthenticatedAllowList": "ALLOW", + "s3ReadPolicy": "read_policy_4ff86870", + "s3PermissionsGuestPublic": "DISALLOW", + "s3PermissionsGuestUploads": "DISALLOW", + "GuestAllowList": "DISALLOW", + "triggerFunction": "NONE" +} \ No newline at end of file diff --git a/amplify/backend/storage/hpiotuserstorage/s3-cloudformation-template.json b/amplify/backend/storage/hpiotuserstorage/s3-cloudformation-template.json new file mode 100644 index 0000000..73848eb --- /dev/null +++ b/amplify/backend/storage/hpiotuserstorage/s3-cloudformation-template.json @@ -0,0 +1,631 @@ +{ + "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" + }, + "s3PrivatePolicy": { + "Type": "String" + }, + "s3ProtectedPolicy": { + "Type": "String" + }, + "s3UploadsPolicy": { + "Type": "String" + }, + "s3ReadPolicy": { + "Type": "String" + }, + "s3PermissionsAuthenticatedPublic": { + "Type": "String" + }, + "s3PermissionsAuthenticatedProtected": { + "Type": "String" + }, + "s3PermissionsAuthenticatedPrivate": { + "Type": "String" + }, + "s3PermissionsAuthenticatedUploads": { + "Type": "String" + }, + "s3PermissionsGuestPublic": { + "Type": "String", + "Default" : "DISALLOW" + }, + "s3PermissionsGuestUploads": { + "Type": "String", + "Default" : "DISALLOW" }, + "AuthenticatedAllowList": { + "Type": "String" + }, + "GuestAllowList": { + "Type": "String", + "Default" : "DISALLOW" + }, + "selectedGuestPermissions": { + "Type": "CommaDelimitedList" + }, + "selectedAuthenticatedPermissions": { + "Type": "CommaDelimitedList" + }, + "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" + }, + "-", + { + "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" + } + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d7708fd..fa72323 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7335,6 +7335,14 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "ngx-gauge": { + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/ngx-gauge/-/ngx-gauge-1.0.0-beta.11.tgz", + "integrity": "sha512-/o+4DBujl5bUWfOvjbbZqqbuTwZNmFzP+JKxoCviNZbY3VowQWxCiQLSBB+j/Zc4M/MY4ecgJz+uxSLO06OQCA==", + "requires": { + "tslib": "^1.9.0" + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", diff --git a/package.json b/package.json index 308108f..edbdcdd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@angular/service-worker": "~8.2.0", "aws-amplify": "^1.2.2", "hammerjs": "^2.0.8", + "ngx-gauge": "^1.0.0-beta.11", "rxjs": "~6.4.0", "tslib": "^1.10.0", "zone.js": "~0.9.1" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b8b8fb1..ef0c201 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -18,7 +18,7 @@ import { SignUpComponent } from './auth/sign-up/sign-up.component'; import { ConfirmCodeComponent } from './auth/confirm-code/confirm-code.component'; import { ProfileComponent } from './auth/profile/profile.component'; import { AvatarComponent } from './auth/profile/avatar/avatar.component'; - +import { NgxGaugeModule} from 'ngx-gauge'; @NgModule({ declarations: [ AppComponent, @@ -40,7 +40,8 @@ import { AvatarComponent } from './auth/profile/avatar/avatar.component'; MaterialModule, ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), ReactiveFormsModule, - FormsModule + FormsModule, + NgxGaugeModule ], providers: [], bootstrap: [AppComponent], diff --git a/src/app/auth/profile/avatar/avatar.component.ts b/src/app/auth/profile/avatar/avatar.component.ts index a2d6679..48ce659 100644 --- a/src/app/auth/profile/avatar/avatar.component.ts +++ b/src/app/auth/profile/avatar/avatar.component.ts @@ -157,4 +157,4 @@ export class AvatarComponent { this.errorMessage = err.message || err; } -} \ No newline at end of file +} diff --git a/src/app/auth/profile/profile.component.ts b/src/app/auth/profile/profile.component.ts index 680725e..761650a 100644 --- a/src/app/auth/profile/profile.component.ts +++ b/src/app/auth/profile/profile.component.ts @@ -89,7 +89,7 @@ export class ProfileComponent implements OnInit { if (this.avatar) { attributes['profile'] = this.avatar; } - await Auth.updateUserAttributes(this.user,attributes); + await Auth.updateUserAttributes(this.user, attributes); if (!this.avatar && this.deleteAvatar) { this.user.deleteAttributes(["profile"],(error) => { if (error) console.log(error); diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 0e3f8ed..bb0db52 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,12 +1,22 @@