Search code examples
amazon-web-servicesamazon-cognitoaws-mobilehubaws-appsyncaws-amplify

AWS Cognito/Amplify - have new user sign ups be automatically add to a user group


I am using AWS Amplify library to sign up and perform Auth for an AppSync project. This uses Cognito. However, when a new user signs up via Amplify/Cognito, the new user isn't assigned to any specific group in the cognito pool. I am using the Amplify higher order component for login/signup.

import { withAuthenticator } from 'aws-amplify-react';

which I wrap over a component

class Authenticator extends React.Component {
   //... basically empty component, only exists so I can wrap it w/ the HOC
}
export default withAuthenticator(Authenticator)

Amplify is set up in index.js

import config from './aws-exports';
import Amplify from 'aws-amplify';
Amplify.configure(config);

aws-exports.js was autogenerated by AWS Mobile Hub CLI. Looks like...

const awsmobile = {
    'aws_app_analytics': 'enable',
    'aws_cognito_identity_pool_id': 'us-west-2:XXX',
    'aws_cognito_region': 'us-west-2',
    'aws_content_delivery': 'enable',
    'aws_content_delivery_bucket': 'flashcards-hosting-mobilehub-XXX',
    'aws_content_delivery_bucket_region': 'us-west-2',
    'aws_content_delivery_cloudfront': 'enable',
    'aws_content_delivery_cloudfront_domain': 'XXX.cloudfront.net',
    'aws_mandatory_sign_in': 'enable',
    'aws_mobile_analytics_app_id': 'XXX',
    'aws_mobile_analytics_app_region': 'us-east-1',
    'aws_project_id': 'XXX',
    'aws_project_name': 'flash-cards',
    'aws_project_region': 'us-west-2',
    'aws_resource_name_prefix': 'flashcards-mobilehub-XXX',
    'aws_sign_in_enabled': 'enable',
    'aws_user_pools': 'enable',
    'aws_user_pools_id': 'us-west-2_XXX',
    'aws_user_pools_mfa_type': 'OFF',
    'aws_user_pools_web_client_id': 'XXX',
}
export default awsmobile;

Solution

  • I got it working. As mentioned by Vladamir in the comments this needs to be done server side, in a Post Confirmation lambda trigger. Here is the lambda function.

    'use strict';
    var AWS = require('aws-sdk');
    module.exports.addUserToGroup = (event, context, callback) => {
      // console.log("howdy!",event);
      var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
      var params = {
        GroupName: 'users', //The name of the group in you cognito user pool that you want to add the user to
        UserPoolId: event.userPoolId, 
        Username: event.userName 
      };
      //some minimal checks to make sure the user was properly confirmed
      if(! (event.request.userAttributes["cognito:user_status"]==="CONFIRMED" && event.request.userAttributes.email_verified==="true") )
        callback("User was not properly confirmed and/or email not verified")
      cognitoidentityserviceprovider.adminAddUserToGroup(params, function(err, data) {
        if (err) {
          callback(err) // an error occurred
        }
        callback(null, event);           // successful response
      });  
    };
    

    You will also have to set the policy for the lambda function role. In the IAM console, find the role for this lambda and added this inline policy. This give the lambda the keys to the castle for everything cognito so make yours more restrictive.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "cognito-identity:*"
                ],
                "Resource": "*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "cognito-sync:*"
                ],
                "Resource": "*"
            },
            { //this might be the only one you really need
                "Effect": "Allow",
                "Action": [
                    "cognito-idp:*"
                ],
                "Resource": "*"
            }
        ]
    }