Trying to dynamically set .find() parameters from client input - mongodb:Atlas - javascript

I am trying to use data from the client, which they would type into an input box. The idea is to use this for finding in my database to pull the data with the same username. on my Mongo DB:Atlas collection.
So its to use it like this to get the names from the database, .find({"username": request.body})
However, I keep getting the error "CastError: Cast to string failed for value "{ username: '' }" (type Object) at path "username" for model "Db1" on my terminal.
But when I try to hard code it onto the .find({"username": "name"), it works fine. Does anyone have any ideas?
**Javascript app**
async function pullData () {
let clientQ = document.querySelector('#userDB').value;
let entry = {
'username':clientQ
};
const options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(entry)
};
const getData = await fetch('/database', options);
const request = await getData.json();
console.log(request);
};
```
-----------------------------------------------------
**Node Server**
app.post('/database', (request,response) => {
const info = request.body;
postModel.find({"username": info}, (error,data) => {
if(error){
console.log(error);
} else {
response.json(data);
}
});
});
----------------------------------------------
***client side DB***
async function pullData () {
let clientQ = document.querySelector('#userDB').value;
let entry = {
'username':clientQ
};
const options = {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(entry)
};
const getData = await fetch('/database', options);
const request = await getData.json();
console.log(request);

Actually, you're passing the object {username : "value"} to the find method. You need to pass the string.
app.post('/database', (request,response) => {
const info = request.body; // object {username : "value"}
const username = info.username; // the string to search by username
postModel.find({"username": username}, (error,data) => {
if(error){
console.log(error);
} else {
response.json(data);
}
});
});

Related

POST returns undefined with Cloud Function

I'm implementing Stripe for React Native and I'm trying to send the customerId to my Cloud Function using POST, but when I execute the code it returns in the console.log undefined
Cloud Function (Firebase)
exports.addCardForExistingCustomer = functions.https.onRequest(async (request, response) => {
let id = await request.body.customer_id
response.send({
result: id
})
});
Client side
const fetchPaymentSheetParams = async () => {
const response = await fetch(`${API_URL}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ customer_id: customerId })
});
const { result } = await response.json();
console.log(result)
};

Session cookie from node-fetch is invalid?

I am writing a javascript program (for a github action) right now but ran into a problem.
I was trying to log into www.overleaf.com and access the page https://www.overleaf.com/project after generating a session cookie by sending a POST request to https://www.overleaf.com/login with my credentials and the csrf token.
The response contained the requested token in the set-cookie header as expected, however, when I tried to access https://www.overleaf.com/project via GET, I get redirected back to https://www.overleaf.com/login
When copying a session cookie saved in my browser, the request works just fine as expected.
I tried doing the same thing in the command line with cURL and it worked there.
I am fairly certain my authentication request is accepted by Overleaf's server, because I have tried intentionally incorrectly sending the password or the csrf token and in both cases, the response does not give me a new session cookie but sends the old one.
If anyone has any clue what is going wrong, I'd be very thankful for your input.
This is what worked in the terminal, which I'm trying to replicate in javascript with node-fetch:
curl -v --header "Content-Type: application/json" --cookie "GCLB=someothercookie;overleaf_session2=firstsessioncookie" --data '{"_csrf":"the_csrf_token", "email": "MYEMAIL", "password":"MYPASSWORD"}' https://www.overleaf.com/login
to get the cookie and csrf token and
curl -v https://www.overleaf.com/project --cookie "overleaf_session2=returnedsessioncookie; GCLB=someothercookie" as the request that returns the html page of my projects.
This is my javascript code, I have double, triple, quadruple checked it but I think I'm missing something.
const fetch = require("node-fetch");
const parser = require("node-html-parser");
const scparser = require("set-cookie-parser");
async function run() {
const email = process.env.EMAIL;
const password = process.env.PASSWORD;
var cookies = await login(email, password);
console.log(await all_projects(cookies));
}
async function login(email, password) {
const login_get = await fetch("https://www.overleaf.com/login");
const get_cookies = login_get.headers.raw()["set-cookie"];
const parsed_get_cookies = scparser.parse(get_cookies, {
decodeValues: false
});
const overleaf_session2_get = parsed_get_cookies.find(
(element) => element.name == "overleaf_session2"
).value;
const gclb = parsed_get_cookies.find(
(element) => element.name == "GCLB"
).value;
console.log("overleaf_session2_get:", overleaf_session2_get, "gclb:", gclb);
const get_responsetext = await login_get.text();
const _csrf = parser
.parse(get_responsetext)
.querySelector("input[name=_csrf]")
.getAttribute("value");
login_json = { _csrf: _csrf, email: email, password: password };
console.log(login_json);
const login_post = await fetch("https://www.overleaf.com/login", {
method: "post",
body: JSON.stringify(login_json),
headers: {
"Content-Type": "application/json",
"Cookie": "GCLB=" + gclb + ";overleaf_session2=" + overleaf_session2_get
}
});
const post_cookies = login_post.headers.raw()["set-cookie"];
const parsed_post_cookies = scparser.parse(post_cookies, {
decodeValues: false
});
const overleaf_session2_post = parsed_post_cookies.find(
(element) => element.name == "overleaf_session2"
).value;
console.log(
"successful:",
overleaf_session2_get != overleaf_session2_post ? "true" : "false"
);
console.log(await fetch("https://www.overleaf.com/project", {
headers: {
"Cookie": "overleaf_session2=" + overleaf_session2_post
}
}))
return "overleaf_session2=" + overleaf_session2_post;
}
async function all_projects(cookies) {
const res = await fetch("https://www.overleaf.com/project", {
headers: {
Cookie: cookies
}
});
return res;
}
run();
Yes your authentication request is probably valid however this is likely to be a security issue which browsers do not allow you to do such thing and freely access another website's cookie.
Browsers do not allow you to access other domain's cookies, If they did then web would be an unsafe place because for example Stackoverflow could access my Facebook account cookie and extract my personal information.
I fixed my issue by not using node-fetch and switching to https.
Here is what worked:
async function login(email, password) {
//GET login page
const get = await get_login();
//get necessary info from response
const csrf = parser
.parse(get.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
const session1 = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
const gclb = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "GCLB").value;
//POST login data
const post = await post_login(csrf, email, password, session1, gclb);
//get necessary data from response
const session2 = scparser
.parse(post["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
//GET new csrf token from project page
const projects = await get_projects(session2, gclb);
const csrf2 = parser
.parse(projects.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
//return data
return {
session: session2,
gclb: gclb,
csrf: csrf2,
projects: projects.html
};
}
async function get_login() {
const url = "https://www.overleaf.com/login";
return new Promise((resolve) => {
https.get(url, (res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
});
});
}
async function get_projects(session2, gclb) {
const url = "https://www.overleaf.com/project";
return new Promise((resolve) => {
https.get(
url,
{ headers: { Cookie: `GCLB=${gclb};overleaf_session2=${session2}` } },
(res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
}
);
});
}
async function post_login(_csrf, email, password, session1, gclb) {
const url = "https://www.overleaf.com/login";
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: `GCLB=${gclb};overleaf_session2=${session1}`
}
};
const postData = {
_csrf: _csrf,
email: email,
password: password
};
return new Promise((resolve) => {
var req = https.request(url, options, (res) => {
resolve(res.headers);
});
req.on("error", (e) => {
console.error(e);
});
req.write(JSON.stringify(postData));
req.end();
});
}

Promise.all() with dynamically sized array of requests using await

I'm new to JavaScript and Promises. I need to send an array of requests using Promise.all and await. Unfortunately, I do not know the size of the array, so it needs to be dynamic. The array would be requests. Ex:
let arrayOfApiCreateRecords = [];
arrayOfApiCreateRecords.push(apiCreateRecords(req, { clientHeaders: headers, record }));
let responses = await Promise.all( arrayOfApiCreateRecords );
I tried to write my code like this, but I seem to be stuck. Is it possible to rewrite the code using Promise.all and await with a dynamic array of requests? Please advise. Below is what I have:
'use strict';
const { apiCreateRecords } = require('../../../records/createRecords');
const createRecords = async (req, headers) => {
let body = [];
let status;
for(let i = 0; i < req.body.length; i++) {
let r = req.body[i];
let record = {
recordId: r.record_Id,
recordStatus: r.record_status,
};
const response = await apiCreateRecords(req, { clientHeaders: headers, record });
status = (status != undefined || status >= 300) ? status : response.status;
body.push(response.body);
};
return { status, body };
};
module.exports = {
createRecords,
};
Okay, I'm going to use fetch API to demonstrate the usage of Promise.all()
Normal usage (for one fetch call)
let user = { username: 'john.doe', password: 'secret' };
try{
let res = await fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
console.log('User creation response: ', res);
}
catch(err){
console.error('User creation error: ', err);
}
Now let's use Promise.all()
const users = [
{ username: 'john.doe', password: 'secret' },
{ username: 'jane.doe', password: 'i-love-my-secret' }
];
const requests = [];
// push first request into array
requests.push(
fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user[0])
})
);
// push second request into array
requests.push(
fetch('https://example.com/user/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user[1])
})
);
try{
const responses = await Promise.all(requests);
console.log('User creation responses: ', responses);
}
catch(err){
console.log('User creation error: ', err);
}

here i am getting await can only use inside async function error but i am using async in my function

const express = require('express')
const router = express.Router()
const request = require('request')
const endponits = require('../sub/endpoints')
const status = require('../sub/status')
const db = require('../util/db')
const util = require('../util/util')
const CryptoJS = require('crypto-Js')
const fetch = require('node-fetch')
const notify = router.post('/', async (req, res) => {
console.log(req.body);
const CLIENT_SECRET = process.env.PAYMENT_TEST_SECRET_KEY;
// const amt = req.body.orderAmount;
let postData = {
oid: req.body.orderId,
amt: req.body.orderAmount,
rsn: req.body.txMsg,
tt: req.body.txTime
}
let signData =
req.body.orderId +
req.body.orderAmount +
req.body.referenceId +
req.body.txStatus +
req.body.paymentMode +
req.body.txMsg +
req.body.txTime;
// const postData = {
// oid: req.body.orderId,
// amt: req.body.orderAmount,
// refId: req.body.referenceId,
// sts: req.body.txStatus,
// pm: req.body.paymentMode,
// tm: req.body.txMsg,
// tt: req.body.txTime,
// signature: req.body.signature
// }
// var keys = Object.keys(postData);
// var signature = postData.signature;
// keys.sort();
// var signatureData = "";
// keys.forEach((key) => {
// if (key != "signature") {
// signatureData += postData[key];
// }
// });
// var computedSignature = crypto.createHmac('sha256', CLIENT_SECRET).update(signatureData).digest('base64');
// if (computedSignature == signature) {
let sdata = util.computeSign(signData);
if (sdata == req.body.signature) {
let data = {
sts: 'Inprogress',
//'so.pm': req.body.paymentMode || '',
//'so.refId': req.body.referenceId || '',
//uAt: Date.now()
}
db.getref(postData.oid, 'txn', successFunc => {
if (successFunc) {
const txnid = successFunc.id;
const appId = successFunc.appid;
db.updateById(
txnid,
data,
'txn',
success => {
if (success) {
let payload = {}
payload['txnId'] = txnid;
let PAYOUT_URI = 'https://ap.moneyorder.ws/api/v1/payout/test'
let Token = 'ceobrtoen'
let options = {
method: 'POST',
body: JSON.stringify(payload),
headers: {
appid: appId,
token: Token
}
}
try {
let response = await fetch(PAYOUT_URI, options)
let tokenres = await response.json()
//here we call payout Api
// let payload = { txnId: txnid };
// let Token = 'ceobrtoen';
// const PAYOUT_URI = 'https://ap.moneyorder.ws/api/v1/payout/test
// let options = {
// method: 'POST',
// url: PAYOUT_URI,
// body: JSON.stringify(payload),
// headers: {
// appid: appId,
// token: Token
// }
// }
// request(options, (err, response, body) => {
// if (err) {
// res
// .status(status.HTTPS.SERVER_ERROR)
// .json({ msg: 'Something went wrong.' })
// } else {
// let data = JSON.parse(body)
// console.log(data);
// console.log(options.body);
if (tokenres && tokenres.status === 'SUCCESS') {
// 3. update txn record
let updateObj = {
sts: 'Success',
}
db.updateById(
txnid,
updateObj,
'txn',
success => {
if (success) {
cosole.log("payout updated")
} else {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
},
err => {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
)
} else {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: "ERROR 1",
success: false
})
}
} catch (error) {
res.status(status.HTTPS.SERVER_ERROR).json({
data: null,
msg: 'Something went wrong at our end.',
success: false
})
}
// })
}
},
err => {
res
.status(status.HTTPS.BAD_REQUEST)
.json({ success: false, msg: 'error 404', data: null })
}
)
} else {
res
.status(status.HTTPS.BAD_REQUEST)
.json({ success: false, msg: "empty response" })
}
})
} else {
console.log(signData)
console.log(sdata)
}
})
module.exports = router
here I am using async and await but I am getting await only can be used inside an async function where I am wrong in this I am trying to hit other API but I am not getting success.i have also use request module instead of node-fetch but it is not working . can anybody tell me where I am wrong.......................................................................................................................................................
The success function of your db.updateById() isn't async, so you can't use await inside of it.
Also, consider abstracting those callback-style db functions, wrapping them in promises. That way, you can use async-await on the main flow of your application rather than nesting callbacks.
Please note you are doing an await inside success callback function of db.updateById()
Which should be async. Try this.
.
db.updateById( txnid,data, 'txn',
async (success) => {
},
async (err)=> {
}
}
if it dosent work and you can not make the success callback async for some reason
just return another function in the callback and make that async
db.updateById( txnid,data, 'txn',
success => {
(async () => {
})()
},
err => {
}
}

TypeError: Cannot read property 'data' of undefined

In my bot I have a section where the user can search for knowledge articles using a keyword. The knowledge articles are stored in a service now table. The bot is supposed to return all of the articles that match the keyword in a carousel format but whenever I click the search button nothing happens. Code below:
const search = async (turnContext) => {
const knowledgeBaseTopic = turnContext.activity.value.knowledgeBaseTopic;
const message = await new Promise(resolve => {
axios.request({
url: `url + topic`,
method: 'get',
baseURL: 'url',
auth: {
username: 'username',
password: 'password'
}
},
(error, response, body) => {
console.log(error);
var stuff = [];
let messageWithCarouselOfCards = MessageFactory.carousel(stuff);
for (var i = 0, len = body.result.length; i < len; i++) {
stuff.push(
CardFactory.heroCard(body.result[i].short_description, ['imageUrl1'], [`${ process.env.SN_KB_Resp_URl }${ body.result[i].number }`])
);
}
resolve(messageWithCarouselOfCards);
});
});
return turnContext.sendActivity(message);
};
I took my axios request and put it in a .js file completely seperate to the bot to ensure that the request was finding results. Code below:
const axios = require('axios')
const getArticles = async () => {
try {
axios.request({
url: 'url',
method: 'get',
baseURL: 'url',
auth: {
username: 'username',
password: 'password'
},
}
)
}
catch (error) {
console.error(error)
}
}
const countArticles = async () => {
try{
let articles = await getArticles()
console.log(`${Object.entries(articles.data.message).length}`)
} catch (error) {
console.error(error)
}
}
countArticles()
When running this .js file it fails with the error:
TypeError: Cannot read property 'data' of undefined
Any idea what I'm doing wrong with my request?

Categories

Resources