2
votes

I'm trying to access the AWS Cognito UserPool from a Lambda function. The function is configured as the pool's PreSignUp trigger. Here is my lambda code (note, that I'm developing with TypeScript):

import { CognitoUserPoolEvent, Handler, Context, Callback } from 'aws-lambda';
import { CognitoIdentityServiceProvider } from 'aws-sdk';

export const onPreSignUp: Handler =
  (event: CognitoUserPoolEvent, context: Context, cb: Callback | undefined) => {
    context.callbackWaitsForEmptyEventLoop = false;
    const userAttr = event.request.userAttributes || undefined;
    console.log(userAttr);

    if (cb) {
      const cognitoPoolId = process.env.COGNITO_USER_POOL_ID;
      const email = userAttr.email || userAttr['cognito:email_alias'];

      if (!cognitoPoolId) {
        console.warn('No user pool id defined', cognitoPoolId);
        return cb(new Error('Can not create user'));
      }

      const identityService = new CognitoIdentityServiceProvider();

      const params = {
        UserPoolId: cognitoPoolId,
        Filter: `email = "${email}"`,
      };

      console.log("try to list users", params);
      identityService.listUsers(params, (err, data) => {
        console.log('list users');
        if (err) {
          console.warn('listUsers Error', err);
          return cb(new Error('Can not create user'));
        }
        console.log("data", data);
        return cb(null, 'todo');
      });
    }
  }

Unfortunately the callback of listUsers never returns. If I pass an invalid params object, the callback returns immediately.

I've also tried to set the lambdas timeout to max (5 minutes) and increasing the RAM. Nothing helps. The lambda execution role has the AmazonCognitoReadOnly, which gives full read access. I would also expect a authorization error if this would be a problem.

EDIT: Right after I had posted this I've solved my problem: the lambda was configured to run within a VPC. Setting VPC to none solved it.

1
Thanks for sharing! I was not considering the VPC neither! - MarcoS

1 Answers

2
votes

This code works for me:

module.exports.getUserByAttribute = async (attributeName, attributeValue) => {
  const params = {
      UserPoolId: process.env.userPoolId,
      Filter: `${attributeName} = "${attributeValue}"`,
  }
  try {
      const data = await cognitoIdentityService.listUsers(params).promise()
      const existingUser = data.Users.filter(user => user.UserStatus !== 'EXTERNAL_PROVIDER')[0]
      if (existingUser == null) {
          console.log('Error', 'User not found')
      }
      return existingUser
  } catch (error) {
      console.log('Error: getUserByAttribute', error)
  }
}