constructor()

in source/infrastructure/lib/console.ts [48:239]


  constructor(scope: Construct, id: string, props: ConsoleConstructProps) {
    super(scope, id);

    const consoleCloudfrontDist = new CloudFrontToS3(this, 'Distribution', {
      bucketProps: {
        serverAccessLogsBucket: props.s3LogsBucket,
        serverAccessLogsPrefix: 'console-s3/'
      },
      cloudFrontDistributionProps: {
        comment: 'IoT Device Simulator Distribution',
        enableLogging: true,
        errorResponses: [
          { httpStatus: 403, responseHttpStatus: 200, responsePagePath: '/index.html' },
          { httpStatus: 404, responseHttpStatus: 200, responsePagePath: '/index.html' }
        ],
        httpVersion: 'http2',
        logBucket: props.s3LogsBucket,
        logFilePrefix: 'console-cf/'

      },
      insertHttpSecurityHeaders: false
    });
    this.cloudFrontDomainName = consoleCloudfrontDist.cloudFrontWebDistribution.domainName;
    this.consoleBucket = consoleCloudfrontDist.s3BucketInterface;

    const userPool = new UserPool(this, 'UserPool', {
      passwordPolicy: {
        minLength: 12,
        requireDigits: true,
        requireLowercase: true,
        requireSymbols: true,
        requireUppercase: true
      },
      removalPolicy: RemovalPolicy.DESTROY,
      selfSignUpEnabled: false,
      signInAliases: {
        email: true
      },
      userPoolName: `${Aws.STACK_NAME}-user-pool`,
      userInvitation: {
        emailSubject: '[IoT Device Simulator] Login information',
        emailBody: `
          <p>
            You are invited to join IoT Device Simulator.<br />
            https://${this.cloudFrontDomainName}
          </p>
          <p>
            Please sign in to IoT Device Simulator using the temporary credentials below:<br />
            Username: <strong>{username}</strong><br />Password: <strong>{####}</strong>
          </p>
        `
      }
    });
    (userPool.node.defaultChild as CfnUserPool).userPoolAddOns = { advancedSecurityMode: 'ENFORCED' };
    this.userPoolId = userPool.userPoolId;

    const userPoolClient = new UserPoolClient(this, 'UserPoolClient', {
      generateSecret: false,
      preventUserExistenceErrors: true,
      refreshTokenValidity: Duration.days(1),
      userPool,
      userPoolClientName: `${Aws.STACK_NAME}-userpool-client`
    });
    this.webClientId = userPoolClient.userPoolClientId;

    new CfnUserPoolUser(this, 'User', { // NOSONAR: typescript:S1848
      userPoolId: userPool.userPoolId,
      desiredDeliveryMediums: ['EMAIL'],
      forceAliasCreation: true,
      userAttributes: [
        { name: 'email', value: props.adminEmail },
        { name: 'email_verified', value: 'true' }
      ],
      username: props.adminEmail
    });

    const identityPool = new CfnIdentityPool(this, 'IdentityPool', {
      allowUnauthenticatedIdentities: false,
      cognitoIdentityProviders: [{
        clientId: userPoolClient.userPoolClientId,
        providerName: userPool.userPoolProviderName,
        serverSideTokenCheck: false
      }]
    });


    this.identityPoolId = identityPool.ref;

    const idsIotPolicy = new CfnPolicy(this, 'IDS-IoT-Policy', {
      policyDocument: new PolicyDocument({
        statements: [
          new PolicyStatement({
            effect: Effect.ALLOW,
            actions: ["iot:Connect"],
            resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'client', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
          }),
          new PolicyStatement({
            effect: Effect.ALLOW,
            actions: ["iot:Subscribe"],
            resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'topicfilter', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
          }),
          new PolicyStatement({
            effect: Effect.ALLOW,
            actions: ["iot:Receive"],
            resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'topic', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
          })
        ]
      })
    });

    this.iotPolicy = idsIotPolicy;
    addCfnSuppressRules(idsIotPolicy, [
      { id: 'W11', reason: 'Cannot specify the resource to attach policy to identity.' }
    ]);

    const authenticatedRole = new Role(this, 'IdentityPoolAuthenticatedRole', {
      assumedBy: new FederatedPrincipal(
        'cognito-identity.amazonaws.com',
        {
          StringEquals: { 'cognito-identity.amazonaws.com:aud': identityPool.ref },
          'ForAnyValue:StringLike': { 'cognito-identity.amazonaws.com:amr': 'authenticated' }
        },
        'sts:AssumeRoleWithWebIdentity'
      ),
      description: `${Aws.STACK_NAME} Identity Pool authenticated role`,
      inlinePolicies: {
        'ExecuteApiPolicy': new PolicyDocument({
          statements: [
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: ['execute-api:Invoke'],
              resources: [Stack.of(this).formatArn({ service: 'execute-api', resource: `${props.apiId}`, resourceName: 'prod/*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
            }),
          ],
        }),
        'LocationServicePolicy': new PolicyDocument({
          statements: [
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: [
                "geo:SearchPlaceIndexForText",
                "geo:GetMapGlyphs",
                "geo:GetMapSprites",
                "geo:GetMapStyleDescriptor",
                "geo:SearchPlaceIndexForPosition",
                "execute-api:Invoke",
                "geo:GetMapTile"
              ],
              resources: [
                props.mapArn,
                props.placeIndexArn,
              ]
            }),
          ]
        }),
        'IoTPolicy': new PolicyDocument({
          statements: [
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: [
                "iot:AttachPrincipalPolicy"
              ],
              resources: ['*']
            }),
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: ["iot:Connect"],
              resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'client', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
            }),
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: ["iot:Subscribe"],
              resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'topicfilter', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
            }),
            new PolicyStatement({
              effect: Effect.ALLOW,
              actions: ["iot:Receive"],
              resources: [Stack.of(this).formatArn({ service: 'iot', resource: 'topic', resourceName: '*', arnFormat: ArnFormat.SLASH_RESOURCE_NAME })]
            })
          ]
        })
      }
    });
    addCfnSuppressRules(authenticatedRole, [
      { id: 'W11', reason: 'iot:AttachPrincipalPolicy does not allow for resource specification' }
    ]);

    new CfnIdentityPoolRoleAttachment(this, 'IdentityPoolRoleAttachement', { // NOSONAR: typescript:S1848
      identityPoolId: identityPool.ref,
      roles: { authenticated: authenticatedRole.roleArn }
    });
  }