2024 06 30 AWS Lambda signup function missing required fields in incoming request - bizkite-co/handterm GitHub Wiki


original file name: Codeium Chat - 6GSJzNHJjYe7lWMtubGRt4s7f4sYzj1t.md summary: The user is facing an issue with a AWS Lambda function deployed from their CDK. The function is for user sign-up and is receiving a request with missing username and password fields. The conversation includes code snippets showing the Lambda function implementation and the HTTP request being made. In response, the assistant explains that the issue is likely due to the structure of the incoming request body being double-nested and provides a corrected code snippet to correctly extract the username, password, and email fields. date: 2024-06-30T15:12

Codeium Chat Conversation

Note: This is purely the output of the chat conversation and does not contain any raw data, codebase snippets, etc. used to generate the output.

User at 3:12 pm, Jun 30, 2024

I am having trouble debugging this AWS Lambda function deployed from my cdk/

// cdk/lambda/authentication/signUp.ts

import * as AWS from 'aws-sdk';

const cognito = new AWS.CognitoIdentityServiceProvider({ region: 'us-east-1' });

exports.handler = async (event: { body: string; }) => {
 console.log('Signup received event:', event); // Log the incoming event

 const body = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;

 try {
  // Check if event.body is a string and parse it, otherwise, use it directly
  const { username, password, email } = body;

  console.log(`Processing signUp for username: ${body}`); // Log the extracted variables
  const clientId = process.env.COGNITO_APP_CLIENT_ID;
  if (!clientId) {
   throw new Error('COGNITO_APP_CLIENT_ID environment variable is not set.');
  }
  var params = {
   ClientId: clientId,
   Username: username,
   Password: password,
   UserAttributes: [
    {
     Name: 'email',
     Value: email
    },
   ],
  };
  body.params = params;
  const data = await cognito.signUp(params).promise();
  console.log('SignUp success:', JSON.stringify(data)); // Log successful signup
  // Include CORS headers in the successful response
  return {
   statusCode: 200,
   headers: {
    "Access-Control-Allow-Origin": "*", // Adjust this value based on your requirements
    "Access-Control-Allow-Credentials": true, // If your client needs to handle cookies
   },
   body: JSON.stringify(data)
  };
 } catch (err: any) {
  console.error('SignUp error:', err); // Log any errors that occur
  // Include CORS headers in the error response
  return {
   statusCode: 400,
   headers: {
    "Access-Control-Allow-Origin": "*", // Adjust this value based on your requirements
    "Access-Control-Allow-Credentials": true, // If your client needs to handle cookies
   },
   body: JSON.stringify({ error: err.message, request: body })
  };
 }
};

I get this error and I can't figer out why the username and password are missing:

 HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 377
Connection: close
Date: Sun, 30 Jun 2024 22:07:57 GMT
x-amzn-RequestId: 383f723f-0020-4de6-8b16-af0a0cede3cd
Access-Control-Allow-Origin: *
x-amz-apigw-id: aM6RjE-XoAMEZQA=
X-Amzn-Trace-Id: Root=1-6681d73c-58380d011f55c733536a8c44;Parent=712007c352fb4205;Sampled=0;lineage=b7b1ca60:0
Access-Control-Allow-Credentials: true
X-Cache: Error from cloudfront
Via: 1.1 bc026bbeb6351b9fc6315a678d5987e6.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: LAX3-C4
X-Amz-Cf-Id: gN2JKqk2yLezOeAfRsJ1s85O-6kTuLe8o5eb04k_4uUBppXqPjN3pQ==

{
  "error": "There were 2 validation errors:\n* MissingRequiredParameter: Missing required key 'Username' in params\n* MissingRequiredParameter: Missing required key 'Password' in params",
  "request": {
    "body": {
      "username": "[email protected]",
      "email": "[email protected]",
      "password": "Pass_w0rd"
    },
    "params": {
      "ClientId": "5v7fgpudlhl7kdagmhcej6rlku",
      "UserAttributes": [
        {
          "Name": "email"
        }
      ]
    }
  }
}

That's from this request in my useAuth.http

### Sign Up
POST {{ $dotenv VITE_API_URL}}/signUp HTTP/1.1
content-type: application/json

{ "body":{
 "username": "[email protected]",
 "email": "[email protected]",
 "password": "Pass_w0rd"
}}

Codeium at 3:12 pm, Jun 30, 2024

The root cause of the issue where the username and password are reported as missing in the AWS Lambda function request handling seems to be due to the structure of the incoming event.body in your Lambda function and how you're handling it in your useAuth.http request.

From your provided request in useAuth.http, it appears the request body is double-nested under "body", like so:

{ "body":{
  "username": "[email protected]",
  "email": "[email protected]",
  "password": "Pass_w0rd"
}}

However, in your Lambda handler (cdk/lambda/authentication/signUp.ts), you're parsing event.body assuming it's either a string that directly contains the JSON with username, password, and email, or it's already an object with those keys at the top level:

const body = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;

Given this code, if event.body is a stringified JSON that looks like { "body": { "username": "...", "email": "...", "password": "..." } }, then after parsing, you'll have an object where the data you want is actually one level deeper under the body key, not at the top level.

To fix this, you need to adjust how you extract username, password, and email after parsing event.body. Here’s a corrected approach:

// Assuming event.body is a string that needs to be parsed as JSON
const parsedBody = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;
// Now extract the actual data from the parsedBody.body if it's structured that way
const { username, password, email } = parsedBody.body ? parsedBody.body : parsedBody;

This change accounts for the double-nesting by checking if parsedBody.body exists and using it if so; otherwise, it falls back to parsedBody directly, which should make your function correctly extract username, password, and email from the incoming requests.

⚠️ **GitHub.com Fallback** ⚠️