constructor()

in cdk-stacks/lib/infrastructure/cognito-stack.ts [22:163]


    constructor(scope: cdk.Construct, id: string, props: CognitoStackProps) {
        super(scope, id, props);

        //create a User Pool
        const userPool = new cognito.UserPool(this, 'UserPool', {
            userPoolName: `${props.cdkAppName}-UserPool`,
            removalPolicy: cdk.RemovalPolicy.DESTROY,
            signInAliases: {
                username: false,
                phone: false,
                email: true
            },
            standardAttributes: {
                email: {
                    required: false,   //Cognito bug with federation - If you make a user pool with required email field then the second google login attempt fails (https://github.com/aws-amplify/amplify-js/issues/3526)
                    mutable: true
                }
            },
            customAttributes: {
                connectUserId: new cognito.StringAttribute({ minLen: 36, maxLen: 36, mutable: true })
            },
            userInvitation: {
                emailSubject: "Your VideoCallEscalation temporary password",
                emailBody: "Your VideoCallEscalation username is {username} and temporary password is {####}"
            },
            userVerification: {
                emailSubject: "Verify your new VideoCallEscalation account",
                emailBody: "The verification code to your new VideoCallEscalation account is {####}"
            }
        });

        //SAML Federation
        let cognitoSAML: cognito.CfnUserPoolIdentityProvider | undefined = undefined;
        let supportedIdentityProviders: cognito.UserPoolClientIdentityProvider[] = [];
        let userPoolClientOAuthConfig: cognito.OAuthSettings = {
            scopes: [cognito.OAuthScope.EMAIL, cognito.OAuthScope.OPENID, cognito.OAuthScope.COGNITO_ADMIN, cognito.OAuthScope.PROFILE]
        }
        if (props.SSMParams.cognitoSAMLEnabled) {
            cognitoSAML = new cognito.CfnUserPoolIdentityProvider(this, "CognitoSAML", {
                providerName: props.SSMParams.cognitoSAMLIdentityProviderName,
                providerType: 'SAML',
                providerDetails: {
                    MetadataURL: props.SSMParams.cognitoSAMLIdentityProviderURL
                },
                attributeMapping: {
                    "email": "email",
                    "email_verified": "email_verified",
                    "name": "name"
                },
                userPoolId: userPool.userPoolId
            })
            supportedIdentityProviders.push(cognito.UserPoolClientIdentityProvider.custom(cognitoSAML.providerName));
            userPoolClientOAuthConfig = {
                ...userPoolClientOAuthConfig,
                callbackUrls: props.SSMParams.cognitoSAMLCallbackUrls.split(',').map((item: string) => item.trim()),
                logoutUrls: props.SSMParams.cognitoSAMLLogoutUrls.split(',').map((item: string) => item.trim())
            }
        }

        //create a User Pool Client
        const userPoolClient = new cognito.UserPoolClient(this, 'UserPoolClient', {
            userPool: userPool,
            userPoolClientName: 'amplifyFrontend',
            generateSecret: false,
            supportedIdentityProviders: supportedIdentityProviders,
            oAuth: userPoolClientOAuthConfig
        });

        if (cognitoSAML) {
            userPoolClient.node.addDependency(cognitoSAML);
        }

        const userPoolDomain = new cognito.CfnUserPoolDomain(this, "UserPoolDomain", {
            domain: props.SSMParams.cognitoDomainPrefix,
            userPoolId: userPool.userPoolId
        });


        //create an Identity Pool
        const identityPool = new cognito.CfnIdentityPool(this, 'IdentityPool', {
            identityPoolName: `${props.cdkAppName}-IdentityPool`,
            allowUnauthenticatedIdentities: false,
            cognitoIdentityProviders: [{
                clientId: userPoolClient.userPoolClientId,
                providerName: userPool.userPoolProviderName
            }],

        });

        //Cognito Identity Pool Roles
        const unauthenticatedRole = new iam.Role(this, 'CognitoDefaultUnauthenticatedRole', {
            assumedBy: new iam.FederatedPrincipal('cognito-identity.amazonaws.com', {
                "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref },
                "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "unauthenticated" },
            }, "sts:AssumeRoleWithWebIdentity")
        });

        unauthenticatedRole.addToPolicy(new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            actions: [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            resources: ["*"]
        }));

        const authenticatedRole = new iam.Role(this, "CognitoDefaultAuthenticatedRole", {
            assumedBy: new iam.FederatedPrincipal('cognito-identity.amazonaws.com', {
                "StringEquals": { "cognito-identity.amazonaws.com:aud": identityPool.ref },
                "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" },
            }, "sts:AssumeRoleWithWebIdentity")
        });

        authenticatedRole.addToPolicy(new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            actions: [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            resources: ["*"]
        }));

        const defaultPolicy = new cognito.CfnIdentityPoolRoleAttachment(this, 'DefaultValid', {
            identityPoolId: identityPool.ref,
            roles: {
                'unauthenticated': unauthenticatedRole.roleArn,
                'authenticated': authenticatedRole.roleArn
            }
        });

        this.authenticatedRole = authenticatedRole;

        /**************************************************************************************************************
        * Stack Outputs *
        **************************************************************************************************************/

        this.identityPool = identityPool;
        this.userPool = userPool;
        this.userPoolClient = userPoolClient;
        this.userPoolDomain = userPoolDomain;
    }