How to solve insufficient allawance issue when calling transferFrom? web3.js - smartcontracts

I'm struggling with the trasferFrom method of my standad ERC20 contract.
I'm working with web3.js and INFURA
I have wallet1 with 50 token allowance, now if I call my function I've always same error "ERC20: insufficient allowance".
This is my code
let data = await contract.methods.transferFrom(from, to, qta).encodeABI();
let nGas = web3.utils.toHex(100000);
let txObj = {
"gas": nGas,
"to": CONTRACT_ADDRESS,
"value": 0x0,
"data": data,
"from": wallet1
}
await web3.eth.accounts.signTransaction(txObj, PRIVATE_KEY, function(err, signedTx) {
if (err)
document.getElementById("ret").innerText = err;
else
{
web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(err, res) {
if (err)
document.getElementById("ret").innerText = err;
else{
document.getElementById("ret").innerHTML = "etherscan";
}
});
}
});
I've tried with
await contratto.methods.transferFrom(from, to, qta).call({ from: wallet });
it doesn't work. Also with .send instead of .call...same result...doesn't work
Anyone has any suggestion?
Thanks

Related

How to protect routes using JWT in NextJS?

I was working on a project in next js where i need to protect some routes. I was trying to do this using jwt but for some reason it's not working, the POST method below inside index.js is injecting new entry in db bypass the verify token middleware. Any kind of help would be greatly appreciated.
verifyAuthToken.middleware.js
import jwt from "jsonwebtoken";
export default function verifyAuthToken(req, res) {
try {
const token = req.headers;
if (!token) {
return res.status(401).json({
success: false,
msg: "You are not authorized to access this route",
});
}
const { userId } = jwt.verify(
req.headers.authorization,
process.env.TOKEN_SECRET
);
if (!userId) {
return res.status(401).json({
success: false,
msg: "You are not authorized to access this route",
});
}
req.userId = userId;
} catch (error) {
res.status(401).json({
success: false,
msg: "You are not authorized to access this route",
error: error.message,
});
}
}
index.js
import verifyAuthToken from "../../../middleware/verifyAuthToken.middleware";
import Evoluter from "../../../models/Evoluter.model";
import dbConnect from "../../../server-utils/connectDB";
import { sendEmail } from "../../../server-utils/sendEmail";
import baseURL from "../../../utils/baseURL";
export default async (req, res) => {
const { method } = req;
verifyAuthToken(req, res);
await dbConnect();
switch (method) {
// #route GET api/evoluters
// #desc Create new evoluter
// #access Private
case "POST":
try {
const { name, email } = req.body;
const evoluter = await Evoluter.findOne({ email: email.toLowerCase() });
if (evoluter) {
return res.status(400).json({
success: false,
msg: "Evoluter already exists",
});
}
const newEvoluter = await Evoluter.create({
name,
email: email.toLowerCase(),
});
try {
await sendEmail({
email: newEvoluter.email,
subject: "Welcome to Rubrica",
message: `Hi ${newEvoluter.name}, welcome to Rubrica. Please click on the link below to activate your account. ${baseURL}/home/${newEvoluter._id}`,
});
res.status(201).json({
success: true,
data: newEvoluter,
msg: "Evoluter created successfully. Please check your email to activate your account.",
});
} catch (error) {
console.log(error);
res.status(500).json({
success: false,
msg: "Error sending invitation email, please let the admin know.",
});
}
} catch (error) {
res.status(400).json({
success: false,
msg: "Sorry, we couldn't send the invitation. Please try again.",
error: error,
});
}
break;
default:
res.status(400).json({
success: false,
msg: "Invalid request",
});
break;
}
};
Here we can see that the verify token middleware was fired as expected, however the data inside the body got injected into the DB which we don't really need.
Postman output
Please let me know if you need more information I don't have much experience asking questions in stackoverflow.
It is bypassing the verifyAuthToken function because You are doing it anyway you are just generating response on verifyAuthToken
You can return a boolean at the end of your verifyAuthToken something like this:
if (userId) return true;
else return false;
Then in your index.js before injecting data to database instead of verifyAuthToken(req, res); do this:
if (!verifyAuthToken(req, res)) {
return;
}
You can also use NextJs middleware

Express can't set headers after they are sent to the client

I have the following code:
router.post('/:email/addWorkflow', async function (req, res, next) {
const params = req.params;
const workflow = req.body;
const email = params.email;
User.findOne({ email: email }, function (err, user) {
if (err) {
res.status(500).send({
error: 'Error while querying database'
});
} else if (user) {
const workflows = user.workflows;
workflows.forEach(wf => {
if (wf) {
if (wf.workflowId === workflow.workflowId) {
res.status(409).send({
error: 'Workflow with that id already exists'
});
}
}
});
workflows.push(workflow);
User.updateOne({ email: email }, { $set: { workflows: workflows } }, { upsert: false }, function (err) {
if (err) {
res.status(500).send({
message: 'Error while updating database'
});
} else {
res.status(200).send({
message: 'Wf added successfully'
});
}
});
} else {
res.status(404).send({
message: 'No such user'
});
}
});
});
After I make a post with an already existing workflowId, I get the following error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:485:11)
..........
at /home/petar/Documents/jsProjects/p/backend/routes/users.js:50:29
at CoreDocumentArray.forEach (<anonymous>)
at /home/petar/Documents/jsProjects/p/backend/routes/users.js:47:17
at /home/petar/Documents/jsProjects/p/backend/node_modules/mongoose/lib/model.js:4915:16
at /home/petar/Documents/jsProjects/p/backend/node_modules/mongoose/lib/model.js:4915:16
at /home/petar/Documents/jsProjects/linear-mixed-models/backend/node_modules/mongoose/lib/query.js:4380:11
[... lines matching original stack trace ...]
at processTicksAndRejections (internal/process/task_queues.js:76:11) {
code: 'ERR_HTTP_HEADERS_SENT'
Any ideas? I looked at other posts for the same error. I understand that it happens if I try to send response 2 time: res.send({...}) and res.send({...}). However, this does not happen in my case. Thanks in advance
I am not completely sure what line the error message is indicating, but the following loop is the only place I can think of a multiple response on your code
workflows.forEach(wf => {
//foreach is looping
if (wf) {
if (wf.workflowId === workflow.workflowId) {
res.status(409).send({
error: 'Workflow with that id already exists'
});
//but I don't think this guy will stop looping after the first "send()"
}
}
});

Using asynchronous methods but Express still returning 503 (NodeJS)

I'm developing a web application in NodeJS with an Express back-end. The application is running smoothly except that when a user signs up, a somewhat long operation is called on the back end that involves saving to a database, resizing an image, etc. It takes a few seconds for this process to complete, and during this time anyone else who makes a request to the server will receive a 503 error and will be unable to do anything, whether that's sending or receiving data. I am using asynchronous functions in order to do this whole process. I am using multer to read the file, fs to read and write the file, and Jimp to resize the image. The code is as shown below.
module.exports = function(router) {
router.route('/')
.post(function(req, res, next) {
upload(req, res, function(err) {
var salt = bcrypt.genSaltSync(saltRounds);
var identifier = makeIdentifier(req.body.first_name.trim())
let emailNotifications = 0;
if (req.body.email_notifications === 'true') {
emailNotifications = 1;
}
var signup = {
identifier: identifier,
first_name: toTitleCase(req.body.first_name.trim()),
last_name: req.body.last_name.trim(),
hobby: req.body.hobby,
type: 'user',
email: req.body.email.trim(),
email_notifications: emailNotifications,
password: bcrypt.hashSync(req.body.password, salt)
};
let ascii = /^[ -~]+$/;
for (var propertyName in signup) {
if (!ascii.test(signup[propertyName])) {
res.json({
reason: "invalid-characters"
});
return;
}
}
if (req.file.size > 5000000) {
res.json({
reason: "file-size"
});
return;
}
let emailExists = false;
db.doesEmailExist(req.body.email, function(err, results) {
if (err) {
res.status(500).send("Server error");
return;
} else {
if (results.length > 0) {
res.json({
reason: "email-exists"
});
return;
} else {
fs.readFile(req.file.path, function(err, data) {
let newPath = __dirname + "/profile-pictures/" + identifier + ".png";
fs.writeFile(newPath, data, function(err) {
if (err) {
console.log(err);
} else {
try {
Jimp.read(newPath, (err, file) => {
if (err) throw err;
file
.resize(300, 300) // resize
.quality(60) // set JPEG quality
.write(newPath); // save
});
} catch (error) {
res.json({
reason: "image-properties"
});
return
}
}
});
});
db.signup(signup, function(err, results) {
if (err) {
res.status(500).send("Server error");
return;
} else {
res.json({
success: true
});
return;
}
})
}
}
})
})
});
}
What is causing the server to respond with a 503 error? Any help would be appreciated, thanks!

Express Passportjs Authenticate not being reached in router callback

If I pass passport.authenticate("local") as middleware into my route, it executes. But this way I do not have access to res so I can send a message back to my front end. However, if I attempt to call it in the route callback function, it is not firing.
router.post("/login", function(req, res, next) {
passport.authenticate("local", function(err, user, info) {
console.log("Unreached"); // This is not logging
});
})
Here is my passport.use inside app.js
passport.use(new LocalStrategy({
usernameField: "portalId"
}, function(portalId, enteredPassword, done) {
var params = {
TableName: "MyTableName",
KeyConditionExpression : "PortalID = :portalID",
ExpressionAttributeValues : {
":portalID" : Number(portalId)
}
}
docClient.query(params, function(err, user) {
if (err) throw err;
let realPassword = user.Items[0].password;
bcrypt.compare(enteredPassword, realPassword, function(err, res) {
if (err) throw err;
if (res) {
return done(null, user);
}
if (!res) {
return done(null, false, { message: "Invalid Credentials" });
}
})
})
}));
Saw in some other post a snippet of code using the custom callback and he had (req, res, next) right after the passport.authenticate function. I added this and my code was being fired now.

Using Express.js's res.send() with async.each

async1.each(arr, function(arrayMember) {
orders.where('name', arrayMember).fetch({withRelated: ['allOrders']}).
then(function(dd2, callback) {
dd2 = dd2.toJSON();
var sendMemberOrder = {};
sendMemberOrder.name = dd2.name;
sendMemberOrder.lastOrder = dd2.allOrders.length;
res.send(sendMemberOrder);
});
}, function(err) {
if (err) {
console.log("err");
}
});
I'm trying to use Express's res.send() feature but given that I'm using async.each, I'm getting
headers already sent
error.
How can I pass the result of each iteration as an array when a request is being made?
Since you already use promises here, I would like to doscourage you from using async.js here. Your code is broken anyway as it does not call callback at all, and the callback parameter is declared on the wrong function. Instead you could try this:
app.get(your_route, function(req, res, next) {
// obtain arr
Promise.all(arr.map(function(arrayMember) {
return orders.where('name', arrayMember)
.fetch({withRelated: ['allOrders']})
.then(function(dd2) {
dd2 = dd2.toJSON();
return {
name: dd2.name,
lastOrder: dd2.allOrders.length
};
});
})).then(function(resultData) {
res.send(resultData);
}).catch(function(err) {
console.log(err);
next(err);
});
});