├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── amplify ├── .config │ └── project-config.json └── backend │ ├── auth │ └── cognitocf0c6096 │ │ ├── cognitocf0c6096-cloudformation-template.yml │ │ └── parameters.json │ └── backend-config.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── images ├── amplify-pull.mov ├── amplifyconsole-cra.gif ├── auth.gif └── import-backend.gif ├── index.css ├── index.js ├── logo.svg └── serviceWorker.js /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | \#current-cloud-backend 3 | src/aws-exports.js 4 | amplify/backend/awscloudformation/ 5 | amplify/backend/amplify-meta.json 6 | 7 | # dependencies 8 | /node_modules 9 | 10 | # testing 11 | /coverage 12 | 13 | # production 14 | /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | 28 | amplify/\#current-cloud-backend 29 | amplify/.config/local-* 30 | amplify/backend/amplify-meta.json 31 | aws-exports.js 32 | awsconfiguration.json 33 | 34 | #amplify 35 | amplify/\#current-cloud-backend 36 | amplify/.config/local-* 37 | amplify/backend/amplify-meta.json 38 | aws-exports.js 39 | awsconfiguration.json -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/aws-samples/create-react-app-auth-amplify/issues), or [recently closed](https://github.com/aws-samples/create-react-app-auth-amplify/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-samples/create-react-app-auth-amplify/labels/help%20wanted) issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](https://github.com/aws-samples/create-react-app-auth-amplify/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Create-react-app with AWS Amplify Auth (Archived) 2 | 3 | This auth starter implements withAuthenticator HOC to provide a basic authentication flow for signing up signing in users as well as protected client side routing using AWS Amplify. Auth features: User sign up, User sign in, Multi-factor Authentication, User sign-out. 4 | 5 | [View Demo](https://master.d2ka7y7551sk8n.amplifyapp.com/) 6 | 7 | ![Amplify Auth](src/images/auth.gif) 8 | 9 | ## Deploy with the AWS Amplify Console 10 | 11 | The AWS Amplify Console provides hosting for fullstack serverless web apps. [Learn more](https://console.amplify.aws). Deploy this app to your AWS account with a single click: 12 | 13 | [![amplifybutton](https://oneclick.amplifyapp.com/button.svg)](https://console.aws.amazon.com/amplify/home#/deploy?repo=https://github.com/aws-samples/create-react-app-auth-amplify) 14 | 15 | The Amplify Console will fork this repo in your GitHub account, and then build and deploy your backend and frontend in a single workflow. Your app will be available at `https://master.appid.amplifyapp.com`. 16 | 17 | ## Run locally with the Amplify CLI 18 | 19 | 1. Clone the repo that was just forked in your account 20 | 21 | ``` 22 | git clone git@github.com:/create-react-app-auth-amplify.git 23 | 24 | cd create-react-app-auth-amplify && npm install 25 | ``` 26 | 27 | 2. Import the backend environment deployed by the Amplify Console to your repo (the `amplify/team-provider.json` file contains information on all backend environments in your AWS account). The GIF below shows how you to copy the `amplify env import` command from the Amplify Console. 28 | 29 | 30 | 31 | 3. Paste this command into your terminal at the root of your repo. You should see the `amplify/team-provider.json` updated with a backend named `amplify`. 32 | 33 | ``` 34 | amplify pull 35 | ``` 36 | 37 | ![img](src/images/amplify-pull.mov) 38 | 39 | 4. Run locally 40 | 41 | ``` 42 | npm start 43 | ``` 44 | 45 | Checkout Nader Dabit's [Complete Guide to User Authentication](https://dev.to/dabit3/the-complete-guide-to-user-authentication-with-the-amplify-framework-2inh). 46 | -------------------------------------------------------------------------------- /amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "authcra", 3 | "version": "1.0", 4 | "frontend": "javascript", 5 | "javascript": { 6 | "framework": "react", 7 | "config": { 8 | "SourceDir": "src", 9 | "DistributionDir": "build", 10 | "BuildCommand": "npm run-script build", 11 | "StartCommand": "npm run-script start" 12 | } 13 | }, 14 | "providers": [ 15 | "awscloudformation" 16 | ] 17 | } -------------------------------------------------------------------------------- /amplify/backend/auth/cognitocf0c6096/cognitocf0c6096-cloudformation-template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Parameters: 4 | env: 5 | Type: String 6 | authRoleName: 7 | Type: String 8 | unauthRoleName: 9 | Type: String 10 | authRoleArn: 11 | Type: String 12 | unauthRoleArn: 13 | Type: String 14 | 15 | 16 | identityPoolName: 17 | Type: String 18 | 19 | allowUnauthenticatedIdentities: 20 | Type: String 21 | 22 | thirdPartyAuth: 23 | Type: String 24 | 25 | lambdaLogPolicy: 26 | Type: String 27 | 28 | openIdLambdaRoleName: 29 | Type: String 30 | 31 | openIdRolePolicy: 32 | Type: String 33 | 34 | openIdLambdaIAMPolicy: 35 | Type: String 36 | 37 | openIdLogPolicy: 38 | Type: String 39 | 40 | userPoolName: 41 | Type: String 42 | 43 | autoVerifiedAttributes: 44 | Type: CommaDelimitedList 45 | 46 | mfaConfiguration: 47 | Type: String 48 | 49 | mfaTypes: 50 | Type: CommaDelimitedList 51 | 52 | roleName: 53 | Type: String 54 | 55 | roleExternalId: 56 | Type: String 57 | 58 | policyName: 59 | Type: String 60 | 61 | smsAuthenticationMessage: 62 | Type: String 63 | 64 | smsVerificationMessage: 65 | Type: String 66 | 67 | emailVerificationSubject: 68 | Type: String 69 | 70 | emailVerificationMessage: 71 | Type: String 72 | 73 | defaultPasswordPolicy: 74 | Type: String 75 | 76 | passwordPolicyMinLength: 77 | Type: Number 78 | 79 | passwordPolicyCharacters: 80 | Type: CommaDelimitedList 81 | 82 | requiredAttributes: 83 | Type: CommaDelimitedList 84 | 85 | userpoolClientName: 86 | Type: String 87 | 88 | userpoolClientGenerateSecret: 89 | Type: String 90 | 91 | userpoolClientRefreshTokenValidity: 92 | Type: Number 93 | 94 | userpoolClientReadAttributes: 95 | Type: CommaDelimitedList 96 | 97 | mfaLambdaRole: 98 | Type: String 99 | 100 | mfaLambdaLogPolicy: 101 | Type: String 102 | 103 | mfaPassRolePolicy: 104 | Type: String 105 | 106 | mfaLambdaIAMPolicy: 107 | Type: String 108 | 109 | userpoolClientLambdaRole: 110 | Type: String 111 | 112 | userpoolClientLogPolicy: 113 | Type: String 114 | 115 | userpoolClientLambdaPolicy: 116 | Type: String 117 | 118 | userpoolClientSetAttributes: 119 | Type: String 120 | 121 | useDefault: 122 | Type: String 123 | 124 | resourceName: 125 | Type: String 126 | 127 | authSelections: 128 | Type: String 129 | 130 | Conditions: 131 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] 132 | 133 | Resources: 134 | 135 | # BEGIN SNS ROLE RESOURCE 136 | SNSRole: 137 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process 138 | Type: AWS::IAM::Role 139 | Properties: 140 | RoleName: !If [ShouldNotCreateEnvResources, !Ref roleName, !Join ['',[!Ref roleName, '-', !Ref env]]] 141 | AssumeRolePolicyDocument: 142 | Version: "2012-10-17" 143 | Statement: 144 | - Sid: "" 145 | Effect: "Allow" 146 | Principal: 147 | Service: "cognito-idp.amazonaws.com" 148 | Action: 149 | - "sts:AssumeRole" 150 | Condition: 151 | StringEquals: 152 | sts:ExternalId: !Ref roleExternalId 153 | Policies: 154 | - 155 | PolicyName: !Ref policyName 156 | PolicyDocument: 157 | Version: "2012-10-17" 158 | Statement: 159 | - 160 | Effect: "Allow" 161 | Action: 162 | - "sns:Publish" 163 | Resource: "*" 164 | # BEGIN USER POOL RESOURCES 165 | UserPool: 166 | # Created upon user selection 167 | # Depends on SNS Role for Arn if MFA is enabled 168 | Type: AWS::Cognito::UserPool 169 | Properties: 170 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] 171 | Schema: 172 | 173 | - 174 | Name: email 175 | Required: true 176 | Mutable: true 177 | 178 | 179 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes 180 | 181 | 182 | EmailVerificationMessage: !Ref emailVerificationMessage 183 | EmailVerificationSubject: !Ref emailVerificationSubject 184 | 185 | Policies: 186 | PasswordPolicy: 187 | MinimumLength: !Ref passwordPolicyMinLength 188 | RequireLowercase: true 189 | RequireNumbers: true 190 | RequireSymbols: true 191 | RequireUppercase: true 192 | MfaConfiguration: !Ref mfaConfiguration 193 | SmsVerificationMessage: !Ref smsVerificationMessage 194 | SmsConfiguration: 195 | SnsCallerArn: !GetAtt SNSRole.Arn 196 | ExternalId: !Ref roleExternalId 197 | 198 | UserPoolClientWeb: 199 | # Created provide application access to user pool 200 | # Depends on UserPool for ID reference 201 | Type: "AWS::Cognito::UserPoolClient" 202 | Properties: 203 | ClientName: cognitocf0c6096_app_clientWeb 204 | 205 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 206 | UserPoolId: !Ref UserPool 207 | DependsOn: UserPool 208 | UserPoolClient: 209 | # Created provide application access to user pool 210 | # Depends on UserPool for ID reference 211 | Type: "AWS::Cognito::UserPoolClient" 212 | Properties: 213 | ClientName: !Ref userpoolClientName 214 | 215 | GenerateSecret: !Ref userpoolClientGenerateSecret 216 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 217 | UserPoolId: !Ref UserPool 218 | DependsOn: UserPool 219 | # BEGIN USER POOL LAMBDA RESOURCES 220 | UserPoolClientRole: 221 | # Created to execute Lambda which gets userpool app client config values 222 | Type: 'AWS::IAM::Role' 223 | Properties: 224 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 225 | AssumeRolePolicyDocument: 226 | Version: '2012-10-17' 227 | Statement: 228 | - Effect: Allow 229 | Principal: 230 | Service: 231 | - lambda.amazonaws.com 232 | Action: 233 | - 'sts:AssumeRole' 234 | DependsOn: UserPoolClient 235 | UserPoolClientLambda: 236 | # Lambda which gets userpool app client config values 237 | # Depends on UserPool for id 238 | # Depends on UserPoolClientRole for role ARN 239 | Type: 'AWS::Lambda::Function' 240 | Properties: 241 | Code: 242 | ZipFile: !Join 243 | - |+ 244 | - - 'const response = require(''cfn-response'');' 245 | - 'const aws = require(''aws-sdk'');' 246 | - 'const identity = new aws.CognitoIdentityServiceProvider();' 247 | - 'exports.handler = (event, context, callback) => {' 248 | - ' if (event.RequestType == ''Delete'') { ' 249 | - ' response.send(event, context, response.SUCCESS, {})' 250 | - ' }' 251 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' 252 | - ' const params = {' 253 | - ' ClientId: event.ResourceProperties.clientId,' 254 | - ' UserPoolId: event.ResourceProperties.userpoolId' 255 | - ' };' 256 | - ' identity.describeUserPoolClient(params).promise()' 257 | - ' .then((res) => {' 258 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' 259 | - ' })' 260 | - ' .catch((err) => {' 261 | - ' response.send(event, context, response.FAILURE, {err});' 262 | - ' });' 263 | - ' }' 264 | - '};' 265 | Handler: index.handler 266 | Runtime: nodejs12.x 267 | Timeout: '300' 268 | Role: !GetAtt 269 | - UserPoolClientRole 270 | - Arn 271 | DependsOn: UserPoolClientRole 272 | UserPoolClientLambdaPolicy: 273 | # Sets userpool policy for the role that executes the Userpool Client Lambda 274 | # Depends on UserPool for Arn 275 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing 276 | Type: 'AWS::IAM::Policy' 277 | Properties: 278 | PolicyName: !Ref userpoolClientLambdaPolicy 279 | Roles: 280 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 281 | PolicyDocument: 282 | Version: '2012-10-17' 283 | Statement: 284 | - Effect: Allow 285 | Action: 286 | - 'cognito-idp:DescribeUserPoolClient' 287 | Resource: !GetAtt UserPool.Arn 288 | DependsOn: UserPoolClientLambda 289 | UserPoolClientLogPolicy: 290 | # Sets log policy for the role that executes the Userpool Client Lambda 291 | # Depends on UserPool for Arn 292 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 293 | Type: 'AWS::IAM::Policy' 294 | Properties: 295 | PolicyName: !Ref userpoolClientLogPolicy 296 | Roles: 297 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 298 | PolicyDocument: 299 | Version: 2012-10-17 300 | Statement: 301 | - Effect: Allow 302 | Action: 303 | - 'logs:CreateLogGroup' 304 | - 'logs:CreateLogStream' 305 | - 'logs:PutLogEvents' 306 | Resource: !Sub 307 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* 308 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} 309 | DependsOn: UserPoolClientLambdaPolicy 310 | UserPoolClientInputs: 311 | # Values passed to Userpool client Lambda 312 | # Depends on UserPool for Id 313 | # Depends on UserPoolClient for Id 314 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 315 | Type: 'Custom::LambdaCallout' 316 | Properties: 317 | ServiceToken: !GetAtt UserPoolClientLambda.Arn 318 | clientId: !Ref UserPoolClient 319 | userpoolId: !Ref UserPool 320 | DependsOn: UserPoolClientLogPolicy 321 | 322 | 323 | # BEGIN IDENTITY POOL RESOURCES 324 | 325 | 326 | IdentityPool: 327 | # Always created 328 | Type: AWS::Cognito::IdentityPool 329 | Properties: 330 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'cognitocf0c6096_identitypool_cf0c6096', !Join ['',['cognitocf0c6096_identitypool_cf0c6096', '__', !Ref env]]] 331 | 332 | CognitoIdentityProviders: 333 | - ClientId: !Ref UserPoolClient 334 | ProviderName: !Sub 335 | - cognito-idp.${region}.amazonaws.com/${client} 336 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 337 | - ClientId: !Ref UserPoolClientWeb 338 | ProviderName: !Sub 339 | - cognito-idp.${region}.amazonaws.com/${client} 340 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 341 | 342 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities 343 | 344 | 345 | DependsOn: UserPoolClientInputs 346 | 347 | 348 | IdentityPoolRoleMap: 349 | # Created to map Auth and Unauth roles to the identity pool 350 | # Depends on Identity Pool for ID ref 351 | Type: AWS::Cognito::IdentityPoolRoleAttachment 352 | Properties: 353 | IdentityPoolId: !Ref IdentityPool 354 | Roles: 355 | unauthenticated: !Ref unauthRoleArn 356 | authenticated: !Ref authRoleArn 357 | DependsOn: IdentityPool 358 | 359 | 360 | Outputs : 361 | 362 | IdentityPoolId: 363 | Value: !Ref 'IdentityPool' 364 | Description: Id for the identity pool 365 | IdentityPoolName: 366 | Value: !GetAtt IdentityPool.Name 367 | 368 | 369 | UserPoolId: 370 | Value: !Ref 'UserPool' 371 | Description: Id for the user pool 372 | UserPoolName: 373 | Value: !Ref userPoolName 374 | AppClientIDWeb: 375 | Value: !Ref 'UserPoolClientWeb' 376 | Description: The user pool app client id for web 377 | AppClientID: 378 | Value: !Ref 'UserPoolClient' 379 | Description: The user pool app client id 380 | AppClientSecret: 381 | Value: !GetAtt UserPoolClientInputs.appSecret 382 | 383 | 384 | 385 | 386 | 387 | 388 | -------------------------------------------------------------------------------- /amplify/backend/auth/cognitocf0c6096/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "identityPoolName": "cognitocf0c6096_identitypool_cf0c6096", 3 | "allowUnauthenticatedIdentities": false, 4 | "thirdPartyAuth": false, 5 | "lambdaLogPolicy": "cognitocf0c6096_lambda_log_policy", 6 | "openIdLambdaRoleName": "cognitocf0c6096_openid_lambda_role", 7 | "openIdRolePolicy": "cognitocf0c6096_openid_pass_role_policy", 8 | "openIdLambdaIAMPolicy": "cognitocf0c6096_openid_lambda_iam_policy", 9 | "openIdLogPolicy": "cognitocf0c6096_openid_lambda_log_policy", 10 | "userPoolName": "cognitocf0c6096_userpool_cf0c6096", 11 | "autoVerifiedAttributes": [ 12 | "email" 13 | ], 14 | "mfaConfiguration": "OFF", 15 | "mfaTypes": [ 16 | "SMS Text Message" 17 | ], 18 | "roleName": "cognitocf0c6096_sns-role", 19 | "roleExternalId": "cognitocf0c6096_role_external_id", 20 | "policyName": "cognitocf0c6096-sns-policy", 21 | "smsAuthenticationMessage": "Your authentication code is {####}", 22 | "smsVerificationMessage": "Your verification code is {####}", 23 | "emailVerificationSubject": "Your verification code", 24 | "emailVerificationMessage": "Your verification code is {####}", 25 | "defaultPasswordPolicy": false, 26 | "passwordPolicyMinLength": 8, 27 | "passwordPolicyCharacters": [ 28 | "Requires Lowercase", 29 | "Requires Uppercase", 30 | "Requires Numbers", 31 | "Requires Symbols" 32 | ], 33 | "requiredAttributes": [ 34 | "email" 35 | ], 36 | "userpoolClientName": "cognitocf0c6096_app_client", 37 | "userpoolClientGenerateSecret": true, 38 | "userpoolClientRefreshTokenValidity": 30, 39 | "userpoolClientReadAttributes": [ 40 | "email" 41 | ], 42 | "mfaLambdaRole": "cognitocf0c6096_totp_lambda_role", 43 | "mfaLambdaLogPolicy": "cognitocf0c6096_totp_lambda_log_policy", 44 | "mfaPassRolePolicy": "cognitocf0c6096_totp_pass_role_policy", 45 | "mfaLambdaIAMPolicy": "cognitocf0c6096_totp_lambda_iam_policy", 46 | "userpoolClientLambdaRole": "cognitocf0c6096_userpoolclient_lambda_role", 47 | "userpoolClientLogPolicy": "cognitocf0c6096_userpoolclient_lambda_log_policy", 48 | "userpoolClientLambdaPolicy": "cognitocf0c6096_userpoolclient_lambda_iam_policy", 49 | "userpoolClientSetAttributes": false, 50 | "useDefault": "default", 51 | "resourceName": "cognitocf0c6096", 52 | "authSelections": "identityPoolAndUserPool", 53 | "authRoleName": { 54 | "Ref": "AuthRoleName" 55 | }, 56 | "unauthRoleName": { 57 | "Ref": "UnauthRoleName" 58 | }, 59 | "authRoleArn": { 60 | "Fn::GetAtt": [ 61 | "AuthRole", 62 | "Arn" 63 | ] 64 | }, 65 | "unauthRoleArn": { 66 | "Fn::GetAtt": [ 67 | "UnauthRole", 68 | "Arn" 69 | ] 70 | } 71 | } -------------------------------------------------------------------------------- /amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth": { 3 | "cognitocf0c6096": { 4 | "service": "Cognito", 5 | "providerPlugin": "awscloudformation" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notes", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "aws-amplify": "^4.3.14", 7 | "@aws-amplify/ui-react": "^1.2.6", 8 | "react": "^16.13.1", 9 | "react-dom": "^16.13.1", 10 | "react-scripts": "^5.0.0" 11 | }, 12 | "resolutions": { 13 | "set-value": "^2.0.1", 14 | "mixin-deep": "^1.3.2" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": "react-app" 24 | }, 25 | "browserslist": [ 26 | ">0.2%", 27 | "not dead", 28 | "not ie <= 11", 29 | "not op_mini all" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/3b0828caf96ffcc593e826cfa749e2e670374ee4/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | } 9 | 10 | .App-header { 11 | background-color: #282c34; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | justify-content: center; 17 | font-size: calc(10px + 2vmin); 18 | color: white; 19 | } 20 | 21 | .App-link { 22 | color: #61dafb; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { 27 | transform: rotate(0deg); 28 | } 29 | to { 30 | transform: rotate(360deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react' 5 | import Amplify from 'aws-amplify'; 6 | import aws_exports from './aws-exports'; 7 | Amplify.configure(aws_exports); 8 | 9 | class App extends Component { 10 | render() { 11 | return ( 12 |
13 | 14 |
15 | logo 16 |

17 | Edit src/App.js and save to reload. 18 |

19 | 25 | Learn React 26 | 27 |
28 |
29 | ); 30 | } 31 | } 32 | 33 | export default withAuthenticator(App); 34 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/images/amplify-pull.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/3b0828caf96ffcc593e826cfa749e2e670374ee4/src/images/amplify-pull.mov -------------------------------------------------------------------------------- /src/images/amplifyconsole-cra.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/3b0828caf96ffcc593e826cfa749e2e670374ee4/src/images/amplifyconsole-cra.gif -------------------------------------------------------------------------------- /src/images/auth.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/3b0828caf96ffcc593e826cfa749e2e670374ee4/src/images/auth.gif -------------------------------------------------------------------------------- /src/images/import-backend.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/3b0828caf96ffcc593e826cfa749e2e670374ee4/src/images/import-backend.gif -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export function register(config) { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Let's check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl, config); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl, config); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl, config) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | 70 | // Execute callback 71 | if (config.onUpdate) { 72 | config.onUpdate(registration); 73 | } 74 | } else { 75 | // At this point, everything has been precached. 76 | // It's the perfect time to display a 77 | // "Content is cached for offline use." message. 78 | console.log('Content is cached for offline use.'); 79 | 80 | // Execute callback 81 | if (config.onSuccess) { 82 | config.onSuccess(registration); 83 | } 84 | } 85 | } 86 | }; 87 | }; 88 | }) 89 | .catch(error => { 90 | console.error('Error during service worker registration:', error); 91 | }); 92 | } 93 | 94 | function checkValidServiceWorker(swUrl, config) { 95 | // Check if the service worker can be found. If it can't reload the page. 96 | fetch(swUrl) 97 | .then(response => { 98 | // Ensure service worker exists, and that we really are getting a JS file. 99 | if ( 100 | response.status === 404 || 101 | response.headers.get('content-type').indexOf('javascript') === -1 102 | ) { 103 | // No service worker found. Probably a different app. Reload the page. 104 | navigator.serviceWorker.ready.then(registration => { 105 | registration.unregister().then(() => { 106 | window.location.reload(); 107 | }); 108 | }); 109 | } else { 110 | // Service worker found. Proceed as normal. 111 | registerValidSW(swUrl, config); 112 | } 113 | }) 114 | .catch(() => { 115 | console.log( 116 | 'No internet connection found. App is running in offline mode.' 117 | ); 118 | }); 119 | } 120 | 121 | export function unregister() { 122 | if ('serviceWorker' in navigator) { 123 | navigator.serviceWorker.ready.then(registration => { 124 | registration.unregister(); 125 | }); 126 | } 127 | } 128 | --------------------------------------------------------------------------------