Passing parameter from app get function of one file to another - javascript

How can I give a function that gets called in one file a parameter to use in another file. I am trying to create a RestApi with node.js and express.js. The file entry.routes.js contains the following code:
app.get("/energy/api/ActualTotalLoad/:AreaName/:Resolution/date/:Year-:Month-:Day", entry.findTwo);
However in this link there are some parameters inside the header as a token. I decode the token with the following code:
app.use(
jwt({
secret: privateKey,
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
}
}));
In the file entry.controllers.js the code is the following:
exports.findTwo =async function (req, res) {
console.log(req);
const correct =await getResults2(req.user.apikey);
console.log(correct);
if (correct==1){
Entry.findByPars(req.params.AreaName,req.params.Resolution,req.params.Year,req.params.Month,req.params.Day, (err, data) => {
if (err) {
if (err.kind === "not_found") {
res.status(403).send({
message: `No data`
});
} else {
res.status(400).send({
message: "Bad Request"
});
}
} else{
if(req.query.format!==undefined && req.query.format=="csv"){
const {Parser} = require('json2csv');
const json2csvParser=new Parser();
const csv=json2csvParser.parse(data);
res.send(csv);
}
else if (req.query.format==undefined || req.query.format=="json"){
res.send(data);
}
else {
res.status(400).send({
message: "Bad Request"
});
}
}
});
}
else if (correct==2) res.status(402).send({ message: "Out of Quota"});
else res.status(401).send({message: "Not authorized"});
}
In the last code when I do the following command
const correct =await getResults2(req.user.apikey);
where I try to access req.user.apikey . This parameter is available in other app.post commands in the entry.routes file but is not accessible in the other file. It passes as undefined.
For example in the entry.routes file the following code works perfectly:
app.post("/energy/api/Logout",function(req,res){
console.log(req.user.apikey);
var jwt=require('jsonwebtoken');
sql.query(`SELECT apikey FROM users WHERE apikey=?`,[req.user.apikey],(err,res1) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
else if (res1.length){
res.status(200).send(" ");
}
else res.status(400).send("Bad Request");
});
});
Why doesn't the parameter req.user.apikey get passed in the entry.findTwo function on the file entry.controllers?

💡 The One reason why you can only get the value from req.user.apikey inentry.controller when you send request to this endpoint:
app.get("/energy/api/ActualTotalLoad/:AreaName/:Resolution/date/:Year-:Month-:Day", entry.findTwo);
It's because you add authorization to the header, before you send the request.
👨‍🏫 It should be noted: this req.user.apikey is comming from the access token that you provided in the header before sending the request.
Because you're using express-jwt, so, every token that you include in the header will be decoded directly and added to the req parameter, that's why you can access req.user.apikey.
So, if your question ❓ is why req.user.apikey can only be accessed inentry.controller, then the answer is because on your other route, for example:
When you call this route: energy/fire/logout
You didn't add authorization there.
💡 So, To be able to use req.user.apikey on your other route, make sure in your header you have added authoriazation.
I hope it can help you 🙏.

Related

Google Cloud Function Not Returning Error Message

I have the following code in a google cloud function. When the user account is created it returns status 200 and the name of the registered user which I can access from the return of the successful promise. All works as expected. However, when there is an error creating the new user the status changes to 400 but no matter what on the client side I get an error of "Error: invalid-argument". I want to pass the error message from the google cloud function. When I check the cloud function logs, I can see the error code and error message.
What I tried: I did try to use the throw new functions.https.HttpsError() but I get a CORS error message.
Any advice on getting the cloud function to pass the error message properly?
const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue } = require('firebase-admin/firestore');
const { getAuth } = require('firebase-admin/auth')
const functions = require('firebase-functions')
const app = initializeApp();
const db = getFirestore();
exports.registerUser = (req, res) => {
let registerDetails = req.body.data;
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
// Send response to OPTIONS requests
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.set('Access-Control-Max-Age', '3600');
res.status(204).send('');
} else {
console.log(registerDetails)
if(registerDetails.FirstName === undefined || registerDetails.FirstName === ""){
res.status(400).json({data: 'Invalid Request'})
} else {
console.log(registerDetails);
getAuth()
.createUser({
email: registerDetails.Email,
emailVerified: false,
password: registerDetails.Password,
displayName: registerDetails.DisplayName,
disabled: false,
})
.then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
let message = 'Registered user '+registerDetails.DisplayName+".";
res.status(200).json({data: message});
console.log('Successfully created new user:', userRecord.uid);
},(error)=>{
res.status(400).json({code:error.errorInfo.code,message:error.errorInfo.message})
console.log('Error creating new user:', error);
})
}
}
};
To anyone who views this post, the solution is that I was confusing HTTP and HTTPS Callable functions, which have different syntax.
See this post:
Google Cloud Function Cors Error Only When Error is Thrown

document not getting deleted in mongo using jwt token

Task of code : Is to delete document from DB using JWT token
error : sending 500 internal error
code of Auth.js
const auth=async(req,res,next)=>{
try{
const token=req.header('Authorization').replace('Bearer ','');
const decoded=jwt.verify(token,'helloworld');
const user=await User.findOne({_id:decoded._id,'tokens.token':token});
if(!user){
throw new Error();
}
// console.log(token);
req.token=token;
req.user=user;
next();
}
catch(err){
// console.log(token);
res.status(401).send({error:"please authenticate"});
}
}
module.exports=auth;
Code To delete document (API endpoint)
router.delete('/users/me',auth,async(req,res)=>{
try{
await req.user.remove();
res.status(201).send(req.user);
}
catch(err){
console.log(err);
console.log(req.user);
res.status(500).send();
}
})
The Problem is even if I am sending incorrect JWT token it should give me {error : please authenticate} but I am not getting this error too instead I am getting 500 internal error and same error when sending correct JWT .
Even I am printing error in console ,its not showing error in console
In your API endpoint, you have to call your collection name then you need to remove with query/params id.
If you are using mongoose Like this and send id from frontend as query/params,
Model.remove({ _id: req.body.id }, function(err) {
if (!err) {
message.type = 'notification!';
} else {
message.type = 'error';
}
});
or
router.delete('/users/me/:id', auth, async(req,res) => {
try {
await Model.deleteOne({ _id: req.params.id})
res.status(201).send(req.user);
} catch(err) {
console.log(err);
res.status(500).send();
}
});
I hope if you follow this way you can solve this problem.
This is the wrong way to remove await req.user.remove(); Because, when code executes it will don't know which collection of data needs to remove.

How to delete zip file after sent response in express

I just want to delete zip folder after sent response so I am looking for any alternative solution
Here is my code / it is get request
exports.Download = async (req, res) => {
try {
var zp = new admz();
zp.addLocalFolder(`./download/${folder}`);
const file_after_download = 'downloaded.zip';
const data = zp.toBuffer();
res.set('Content-Type', 'application/octet-stream');
res.set('Content-Disposition', `attachment; filename=${file_after_download}`);
res.set('Content-Length', data.length);
return res.send(data);
// HERE I want execute this code
let dir = `./download/${folder}`;
if (fse.existsSync(dir)) {
fse.rmdirSync(dir, { recursive: true })
}
} catch (err) {
console.log(err)
return res.render('pages/404');
}
}
Update
If send code without return ( res.send(data);)
Im getting this error //Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client //
If I put return res.send(data); at the end of block , then downloaded zip file will be empty - because its deleted already
From the docs of Express, you can use res.download() function which has a callback parameters to be executed once download is done.
res.download(filePath, 'yourFileName', function(err) {
if (err) {
next(err)
} else {
console.log('Delete:', filePath);
}
})

Why socket.io listener in android side not called?

I write socket middleware for user Authentication but I don't know what's my problem!
in android side "unauthorized" event not called.
Server-side :
async function (socket, next) {
if (socket.handshake.query && socket.handshake.query.token) {
jwt.verify(socket.handshake.query.token, process.env.SECRET_JWT_KEY, function (err, decoded) {
if (err) {
socket.emit( "unauthorized", "unauthorized user") <==send to sender you'r authentication is failed
console.log("Query: ", "unauthorized"); <==This line is lunched
return next(new Error('Authentication error'));
}
socket.decoded = decoded;
next();
});
} else {
next(new Error('Authentication error'));
}
Client-side :
val socket = IO.socket("http://192.168.1.6:3000", IO.Options().apply {
path = "/sockets/chat"
query = "token=wrongtoken"
})
socket.on("unauthorized", object : Emitter.Listener { <== THIS NOT LUNCED!!
override fun call(vararg args: Any?) {
println("user authentication failed" )
}
}
I think you need to connect to the socket first by calling this line inside apply block
this.connect()
Finally found the solution no need to emit from middleware when throwing an error you can get predefined events in an android client like this:
socket.on(Socket.EVENT_ERROR) { args -> println(args.contentToString()) }

why am I getting 'GET/ 304 --' in my code? (vue.js, express)

When I request data on client(vue.js) with axios,
I got a error code in server side, 'GET/ 304 --'
But I don't know why this happened
and how to approach this problem or how to fix that.
If I delete codes about 'axios' on client side,
That error doesn't show up.
Please can someone help me.
the code below:
Client side
created() {
axios
.get("http://localhost:4000/")
.then(
result => (
(this.greeting = result.data.greeting),
(this.greeting2 = result.data.greeting2)
)
);
}
Server side
export const getHome = async (req, res) => {
let user;
if (req.headers.authorization !== undefined) {
try {
user = auth.verify(req.headers.authorization);
user = await models.User.findOne({
where: { id: user.id }
});
} catch (err) {
console.log(err);
}
} else {
user = null;
}
const name = user ? user.name : 'Please LOGIN';
res.json({ greeting: `Welcome to Chat N Chill`, greeting2: name });
};
auth.verify code on server side
verify(token) {
return jwt.verify(token.replace(/^Bearer\s/, ''), SECRET_KEY);
}
Express will automatically set the status code to 304 for requests that are fresh:
https://github.com/expressjs/express/blob/e1b45ebd050b6f06aa38cda5aaf0c21708b0c71e/lib/response.js#L206
The property fresh is defined here:
https://github.com/expressjs/express/blob/e1b45ebd050b6f06aa38cda5aaf0c21708b0c71e/lib/request.js#L467
It is documented here:
https://expressjs.com/en/4x/api.html#req.fresh
It should be nothing to worry about, it just means that the content of the response hasn't changed relative to what the browser already has in its cache.

Categories

Resources