warning: req is not defined in (nodejs) lambda function - node.js

This is part of my code in lambda to insert some values into an oracle database (from Amplify cli)
exports.handler = async (event, context, callback) => {
console.log(`EVENT: ${JSON.stringify(event)}`);
let conn;
try {
conn = await oracledb.getConnection(connAttr);
let result = await conn.execute(
"INSERT INTO employee VALUES (:name, :id, TO_TIMESTAMP(:date1, 'DD-MM-YYYY HH24:MI:SS'), TO_TIMESTAMP(:date2, 'DD-MM-YYYY HH24:MI:SS'))",
[req.body.name, req.body.discount, req.body.date1, req.body.date2],
{
name : req.body.name,
id : req.body.id,
date1 : req.body.date1,
date2 : req.body.date2
}
);
);
const response = {
statusCode: 200,
body: JSON.stringify(result),
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Credentials" : "true",
"content-type": "application/json"
}
};
callback(null, response);
console.log('Query executed');
}
catch (err) {
const response = {
statusCode: 400,
body: JSON.stringify({message: err}),
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Credentials" : "true",
"content-type": "application/json"
}
};
}
}
When I call the api connected, I get no response so I decided to use the aws console for some quick debugging and the code editor is giving me the warning: req is not defined; please fix or add /*globalreq*/
How can I fix this?

Seem like you were trying to extract the request body when this Lambda function was called, but you have not assigned that body to your "req" variable.
You should explicitly extract it from the event argument, you can refer that body (payload) from the document below
https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html

Related

No 'Access-Control-Allow-Origin' AWS Lambda

happy new year everybody!
So I have a reactJS API call which looks like this:
async function callApi() {
const requestData = {
headers: {
Authorization: token
}
}
if (calledAPI === false) {
let data = await API
.get('caresyncauthapi' , '/access', requestData)
.then(response => {
let arr = {};
arr = response.Items;
setZorgSearchData(arr)
})
}
calledAPI = true;
}
The Lambda it calls looks like this:
exports.handler = async (event) => {
if (event.requestContext.authorizer) {
const claims = event.requestContext.authorizer.claims;
username = claims['cognito:username'];
}
var params = {
TableName: tableName,
IndexName: "ZorgverlenerID-index",
KeyConditionExpression: "#ZorgverlenerID = :zorg_id",
ExpressionAttributeNames: {
"#ZorgverlenerID": "ZorgverlenerID"
},
ExpressionAttributeValues: {
":zorg_id": username
}
};
try {
data = await dynamodb.query(params).promise();
console.log( "Status code : 200");
console.log(data.Items);
let response =
{
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
},
body: JSON.stringify(data.Items)
}
return JSON.stringify(response);
} catch (error){
console.log( "Status code : 400, Error code : ", error.stack);
}
};
Basically the Lambda gets the context from the sent token (username of the person logged in).
It then queries this database with this username, it then puts the result in a json and returns it.
The await dynamodb.query(params).promise(); gives me an 200 (success) and it also prints the correct data I want to return in cloudwatch.
But when the data returns to my ReactJS application i recieve:
Access to XMLHttpRequest at 'https://qcesrr2td3.execute-api.eu-west-1.amazonaws.com/devl/access' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
xhr.js:187 GET https://qcesrr2td3.execute-api.eu-west-1.amazonaws.com/devl/access net::ERR_FAILED 502
dispatchXhrRequest # xhr.js:187
xhrAdapter # xhr.js:13
Thing I already tried:
Enabling CORS in the API gateway
Changing up the headers in the response
Returning the response without JSON.stringify, its null then
Does anybody have an idea what I can still change?
Fixed it by not stringifying my response:
try {
data = await dynamodb.query(params).promise();
console.log( "Status code : 200");
console.log(data.Items);
let response =
{
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body: JSON.stringify(data)
}
return response;
} catch (error){
console.log( "Status code : 400, Error code : ", error.stack);
}
Weird because this code worked for a week then suddenly stopped. Oh well it works again.

AWS Lambda Node.js to write to a table after taking a JWT token using http post..Can we do both in same lambda

I am trying to take a jwt token using a http post and write it to a Dynomodb table. I'm trying to use it as a Lambda in AWS and invoked using the API gateway when a POST request comes it will get the token and write to the table and a GET request comes if will print it to the console. I have been trying to get the code working for a while but no luck. Can someone show me some love :-)
I'm starting to think I can't do all this with a single Lambda and need to break to 2 Lambdas. Any suggestions much appreciated!
//https://k3rezu1sre.execute-api.us-east-2.amazonaws.com/default/Authorizer
const AWS = require("aws-sdk");
const ddb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = "MyDynoTable";
var request = require('request');
exports.handler = async(event, context) => {
switch (event.requestContext.http.method) {
case "GET":
const data = await ddb.scan({ TableName: TABLE_NAME }).promise();
return {
statusCode: 200,
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
}
};
case "POST":
const { token } = JSON.parse(event.body);
var options = {
'method': 'POST',
'url': 'https://host-eu.eu.auth0.com/oauth/token',
'headers': {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"grant_type": "client_credentials",
"audience": "urn:",
"client_id": "",
"client_secret": ""
})
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
const stringBodytoJason = JSON.parse(body);
const token = stringBodytoJason.access_token;
//console.log(token);
await ddb.put({
TableName: TABLE_NAME,
Item: {
id: context.awsRequestId,
token
}
}).promise();
return {
statusCode: 201,
body: JSON.stringify({
id: context.awsRequestId,
}),
headers: {
"Content-Type": "application/json",
}
};
default:
break;
}
});
}

Postman works but not react redux action (axios.post request)

Something really weird is going on.
I am building an API using Cloud Functions. Basically the Cloud Function makes a request to the server and retrieves a token.
This is the code
exports.Klarna = functions.https.onRequest((req, res) => {
// const app = express();
// app.use(cors({ origin: true }));
res.set('Access-Control-Allow-Origin', '*');
const url = "https://someLink.com";
const creds = req.body;
const token = `Basic ${Buffer.from(
`${"Pxxx"}:${"xxx"}`
).toString("base64")}`;
request(
"https://somelink.com",
{
method: "POST",
url: url,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
Authorization: token,
},
Authorization: token,
body: creds,
json: true,
},
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body);
res.json(response.body.client_token);
}
}
);
});
Then I am calling it from the frontend (reactJS) like this using redux-thunk and axios:
export function Klarna() {
return async (dispatch) => {
try {
let response = await axios('https://google.cloud.function', {
method: 'POST',
redirect: 'follow',
headers: { 'Content-Type': 'application/json', "Access-Control-Allow-Origin": "*",Authorization: "Basic XXX" },
body: JSON.stringify({
"purchase_country": "SE",
"purchase_currency": "SEK",
"locale": "sv-SE",
"order_amount": 10,
"order_tax_amount": 0,
"order_lines": [
{
"type": "physical",
"reference": "19-402",
"name": "Battery Power Pack",
"quantity": 1,
"unit_price": 10,
"tax_rate": 0,
"total_amount": 10,
"total_discount_amount": 0,
"total_tax_amount": 0
}
]
}),
json: true
})
console.log(response);
} finally {
console.log("yea!")
}
}
}
however while in postman succeeds, here I get
[Error] Failed to load resource: The request timed out. (Klarna, line 0)
[Error] Unhandled Promise Rejection: Error: timeout of 0ms exceeded
(anonymous function) (main.chunk.js:7307)
asyncFunctionResume
(anonymous function)
promiseReactionJobWithoutPromise
promiseReactionJob
Any suggestions that could help me moving forward with this? Have been 2 days around this bug and I am not seeing a way to solve it.
UPDATE:
I went around and found how to do it. Here is the code:
const functions = require("firebase-functions");
const express = require("express");
var rp = require("request-promise");
const cors = require("cors")({
origin: true,
allowedHeaders: [
"Access-Control-Allow-Origin",
"Access-Control-Allow-Methods",
"Content-Type",
"Origin",
"X-Requested-With",
"Accept",
"Authorization"
],
methods: ["POST", "OPTIONS"],
credentials: true,
});
const admin = require("firebase-admin");
const serviceAccount = require("./serviceAccountKey.json");
var request = require("request");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
exports.Klarnas = functions.https.onRequest((req, res) => {
// Google Cloud Function res.methods
res.set("Access-Control-Allow-Headers", "Content-Type");
res.set("Content-Type", "Application/JSON");
// CORS-enabled req.methods, res.methods
return cors(req, res, async () => {
res.set("Content-Type", "Application/JSON");
var origin = req.get("Origin");
var allowedOrigins = [
"https://yourLink.com",
"http://localhost:3000",
"http://localhost:5001/xxx/xxx",
];
if (allowedOrigins.indexOf(origin) > -1) {
// Origin Allowed!!
res.set("Access-Control-Allow-Origin", origin);
if (req.method === "OPTIONS") {
// Method accepted for next request
res.set("Access-Control-Allow-Methods", "POST");
//SEND or end
return res.status(200).send({});
} else {
// After req.method === 'OPTIONS' set ["Access-Control-Allow-Methods": "POST"]
// req.method === 'POST' with req.body.{name} => res.body.{name}
// req.method === 'PUT' with req.body.{name}, no res.body.{name}
const url = "https://someLink.com";
const creds = req.body;
const token = `Basic ${Buffer.from(
`${"XXXX"}:${"XXX"}`
).toString("base64")}`;
request(
"https://someLink.com",
{
method: "POST",
url: url,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
Authorization: token,
},
Authorization: token,
body: creds,
json: true,
},
function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body);
res.json(response.body.client_token);
}
}
);
}
} else {
//Origin Bad!!
//SEND or end
return res.status(400).send("no access for this origin");
}
});
});
Please try to use then/catch to catch the error orhandle the promise rejection.
You can use the following code:
export function Klarna() {
return async (dispatch) => {
let response = await axios('https://[REGION]-[PROJECT-ID].cloudfunctions.net/Klarna', {
method: 'POST',
redirect: 'follow',
headers: { 'Content-Type': 'application/json', "Access-Control-Allow-Origin": "*",Authorization: "Basic [Token]==" },
body: JSON.stringify({
"purchase_country": "SE",
"purchase_currency": "SEK",
"locale": "sv-SE",
"order_amount": 10,
"order_tax_amount": 0,
"order_lines": [
{
"type": "physical",
"reference": "19-402",
"name": "Battery Power Pack",
"quantity": 1,
"unit_price": 10,
"tax_rate": 0,
"total_amount": 10,
"total_discount_amount": 0,
"total_tax_amount": 0
}
]
}),
json: true
}).then(data => console.log(data))
.catch(err => console.log(err);
}
}
Please let me know if it works.

no 'Access-Control-Allow-Origin' header is present on the requested resource. while uploading image to s3 using aws lambda

var mysql = require('mysql');
var config = require('./config.json');
var jwt = require('jsonwebtoken');
var configuration = require('./jwtconfig.js');
const isBase64 = require('is-base64');
const base64mime = require('base64mime');
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-2' });
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });
const bucket = "bucketname";
let path = "bucketpath/";
var pool = mysql.createPool({
host: config.dbhost,
user: config.dbuser,
password: config.dbpassword,
database: config.dbname
});
module.exports.handler = (event, context, callback) => {
const { eventname, event_type, event_platform, event_date, co_host, stream_url, description, event_time, user_id, zoom_id,c_id } = JSON.parse(event.body);
const image = JSON.parse(event.body).imageBase64;
//let token = event.headers['x-access-token'] || event.headers['authorization'];
context.callbackWaitsForEmptyEventLoop = false;
// if (token) {
// jwt.verify(token, configuration.secret, (err, decoded) => {
// if (err) {
// callback({
// statusCode: 201,
// headers: {
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Headers": "Content-Type,x-access-token",
// // "Access-Control-Request-Headers":"x-access-token",
// "Access-Control-Allow-Methods": "OPTIONS,POST"
// },
// body: JSON.stringify(err)
// }, null);
// } else {
// event.decoded = decoded;
if (eventname && event_type && event_date) {
let key = path + "img" + "_" + new Date().getTime();
const options = {
Bucket: bucket,
Key: key,
StorageClass: 'STANDARD_IA',
ACL: 'public-read',
ContentType: base64mime(image),
ContentEncoding: 'base64',
Body: Buffer.from(image.replace(/^data:image\/\w+;base64,/, ""), 'base64')
};
s3.upload(options, (err, data) => {
if (err) {
callback({
"statusCode": 400,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type,x-access-token,Origin,XMLHttpRequest",
"Access-Control-Request-Headers":"x-access-token",
"Access-Control-Allow-Methods": "OPTIONS,POST",
"Access-Control-Allow-Credentials" : "true"
},
"body": JSON.stringify(err)
}, null);
} else {
var bhu = data["Location"];
callback(null, { statusCode: 200, headers: { "Access-Control-Allow-Origin": "*" , "Access-Control-Allow-Headers": "Origin, X-Requested-With,x-access-token, Content-Type, Accept, Authorization, token, XMLHttpRequest"},body:JSON.stringify(bhu)});
pool.getConnection(function (err, connection) {
if (err) {
return callback(err, null);
}
var quer = `Insert INTO event (eventname,event_type,event_platform,event_date,co_host,stream_url,description,event_time,user_id,zoom_id,image,c_id) values ('${eventname}', '${event_type}', '${event_platform}', '${event_date}','${[co_host]}', '${stream_url}', '${description}','${event_time}','${event.pathParameters.user_id}','${zoom_id}','${bhu}','${c_id}')`;
connection.query(quer, [parseInt(event.pathParameters.user_id)], function (error, results, field) {
if (error) {
callback({
statusCode: 400,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,POST,OPTIONS,UPDATE,DELETE",
"Access-Control-Allow-Headers": "Origin, X-Requested-With,x-access-token, Content-Type, Accept, Authorization, token, XMLHttpRequest",
"Access-Control-Allow-Credentials" : "true"
},
body: JSON.stringify(error)
}, null);
} else {
var insertId = results.insertId;
var getquer = `SELECT * FROM event WHERE id = ${insertId}`;
connection.query(getquer, function (error, result) {
if (error) {
callback({
statusCode: 400,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,POST,OPTIONS,UPDATE,DELETE",
"Access-Control-Allow-Headers": "Origin, X-Requested-With,x-access-token, Content-Type, Accept, Authorization, token, XMLHttpRequest",
"Access-Control-Allow-Credentials" : "true"
},
body: JSON.stringify(error)
}, null);
} else {
var customRes = [];
customRes = {
"statusCode": 200,
"message": "event created successfully",
"data": result,
//"token data":decoded
};
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,POST,OPTIONS,UPDATE,DELETE",
"Access-Control-Allow-Headers": "Origin, X-Requested-With,x-access-token ,Content-Type, Accept, Authorization, token, XMLHttpRequest",
"Access-Control-Allow-Credentials" : "true"
},
body: JSON.stringify(customRes)
});
}
});
}
});
});
}
});
}
// });
// } else {
// var customRes = {};
// customRes = {
// "statusCode": 201,
// "message": "token is not provided",
// };
// callback(null, {
// statusCode: 201,
// headers: {
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Headers": "Content-Type,x-access-token",
// "Access-Control-Allow-Methods": "OPTIONS,POST"
// },
// body: JSON.stringify(customRes)
// });
//}
};
I am getting 'Access-Control-Allow-Origin' header is present on the requested resource error when accessing this code API in front end . i am using aws lambda function to upload image to s3 bucket . i have also included . access-control-allow -origin header in my code . i have enable proxy integration in API gateway . but I am getting this error
I found that you've already open CORS in your NodeJS code but it's just for lambda part only. But all of request will be passed through API Gateway thus you may need to open CORS in AWS API Gateway.
Go to your API Gateway Path > then click Actions dropdown > Click Enable CORS as per attach for reference.

Error 400 on trying to add a contact in mailchimp

I am getting this error when trying to call the mailchimp API V3 to add a new contact to my list
"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the \'errors\' array.","instance":"f8b79d9b-1c02-4062-a0e4-847e31f7bd61","errors":[{"field":"","message":"Schema describes object, NULL found instead"}]}'
Here is the code used:
app.post("/", function(req,res){
var email = req.body.email;
var data = {
members : [
{
email_address: email,
status: "subscribed"
}
]
};
var jsonData = JSON.stringify(data);
var options = {
headers :{
'Authorization': 'thomas APIKEY',
'Content-Type': 'application/json',
'Content-Length': jsonData.length
},
url: "https://us20.api.mailchimp.com/3.0/lists",
method: "POST",
data:jsonData
};
console.log(options);
request(options, function(error, response, body){
if(error)
{
console.log(error);
}
else{
console.log(response);
}
})
I tried adding /Listkey/members to my url with no success
Do you have some tips? Thank you
I found the solution, the elements passed to request were not good.
Here is the functional code:
app.post("/", function(req,res){
var email = req.body.email;
var data = {
"email_address": email,
"status" : "subscribed"
};
var options = {
"url": "https://us20.api.mailchimp.com/3.0/lists/c9b9a6e109/members/",
"method": "POST",
"headers": {
"Authorization": "thomas APIKEY"
},
"body": data,
"json": true
};
})

Resources