How to retrieve client ip address and find location using node js - node.js

I have tried using the following approach but when hosted the application . I'm getting the ip address that the application us hosted on.
Also I have used req.ip and req.socket.remoteAddress but it was returning the local host ip I.e ,::1
here is what I tried.
var express = require('express');
var request = require('request');
var app = express();
const IPData = require("ipdata").default;
require('dotenv').config();
const apiKey = process.env.API_KEY;
const ipdata = new IPData(apiKey);
app.get('/location', async (req, res) => {
try{
request.get('http://ipinfo.io/ip', (error, response, body) => {
if (!error && response.statusCode == 200) {
let clientIp = req.headers["x-forward-ip"] || body
console.log(body);
ipdata.lookup(clientIp)
.then((data) => {
console.log(data);
return res.json({
city: data.city,
region: data.region,
country: data.country_name,
postal: data.postal
});
})
.catch((error) => {
console.log(error);
res.status(500).send('Error looking up location');
});
}
});
}catch(error) {
console.log(error);
res.status(500).send('Error looking up location');
}
});
app.listen(8000, () => {
console.log('Server started on port 8000');
});

Try this:
const express = require("express");
const app = express();
const IpGeoLocation = require("ip-geolocation-api-javascript-sdk");
app.get("/", (req, res) => {
// Get client's IP address
const clientIp = req.connection.remoteAddress;
// Initialize IpGeoLocation with your API key
const apiKey = "YOUR_API_KEY";
const ipGeoLocation = new IpGeoLocation(apiKey);
// Get location information for the client's IP address
ipGeoLocation
.getGeoLocation(clientIp)
.then((location) => {
console.log(location);
res.send(location);
})
.catch((error) => {
console.error(error);
res.status(500).send(error);
});
});
app.listen(3000, () => {
console.log("Server listening on port 3000");
});
const ipGeoLocation = require("ip-geolocation-node");
const clientIp = req.connection.remoteAddress;
ipGeoLocation
.getGeoLocation(clientIp)
.then((location) => {
console.log(location);
})
.catch((error) => {
console.error(error);
});

Related

Error: Unable to acquire a connection Knex postgres

I have added a model to my frontend and backend so that users can update their profile (name age etc.), however, when I'm trying to update my test user name it's not updating, and I'm recieving the below error message in my terminalTerminal error
See below my server.js and profile.js
SERVER.JS
const express = require("express");
const bodyParser = require("body-parser");
const bcrypt = require("bcrypt-nodejs");
const cors = require("cors");
const knex = require("knex");
const register = require("./controllers/register");
const signin = require("./controllers/signin");
const profile = require("./controllers/profile");
const image = require("./controllers/image");
const { Pool } = require("pg");
const morgan = require("morgan");
const nodemailer = require("nodemailer");
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "1";
const pool = new Pool({
connection: process.env.POSTGRES_URI,
ssl: process.env.DATABASE_URI ? true : false,
});
const db = knex({
client: "pg",
connection: process.env.POSTGRES_URI,
ssl: {
rejectUnauthorized: false,
},
});
const app = express();
app.use(bodyParser.json());
app.use(morgan("combined"));
app.use(cors());
app.get("/", (req, res) => {
res.send("it is working");
});
app.post("/signin", (req, res) => {
signin.handleSignin(req, res, db, bcrypt);
});
app.post("/register", (req, res) => {
register.handleRegister(req, res, db, bcrypt);
});
app.get("/profile/:id", (req, res) => {
profile.handleProfile(req, res, db);
});
app.post("/profile/:id", (req, res) => {
profile.handleProfileUpdate(req, res, db);
});
app.put("/image", (req, res) => {
image.handleImage(req, res, db);
});
app.post("/imageurl", (req, res) => {
image.handleApiCall(req, res);
});
app.post("/sendResetPassowrdLink", (req, res) => {
const email = req.body.email;
pool.query(`SELECT * FROM login WHERE email='${email}'`).then((data) => {
if (data.rowCount === 0) {
return res
.status(401)
.json({ message: "user with that email does not exists" });
}
const { email } = data.rows[0];
const emailBody = `your sever url is http://localhost:3001/resetpassword/${btoa(
email
)}`;
res.send(emailBody);
});
});
app.get("/resetpassword/:token", (req, res) => {
const email = atob(req.params.token);
const { newPassowrd, newPassowrdConfirm } = req.body;
if (newPassowrd !== newPassowrdConfirm) {
return res.status(400).json({ message: "passowrd does not match" });
}
const hash = bcrypt.hashSync(newPassowrd);
pool
.query(`UPDATE login SET hash='${hash}' WHERE email='${email}'`)
.then((data) => {
if (data.rowCount === 1) {
return res
.status(200)
.json({ message: "password updated successfully" });
}
});
});
const PORT = process.env.PORT || 3005;
app.listen(PORT, () => {
console.log(`app is running on port ${PORT}`);
});
PROFILE.JS
const handleProfile = (req, res, db) => {
const { id } = req.params;
db.select("*")
.from("users")
.where({ id })
.then((user) => {
if (user.length) {
res.json(user[0]);
} else {
res.status(400).json("not found");
}
})
.catch((err) => res.status(400).json("error getting user"));
};
const handleProfileUpdate = (req, res, db) => {
const { id } = req.params;
const { name, age, pet } = req.body.formInput;
db("users")
.where({ id })
.update({ name })
.then((resp) => {
if (resp) {
res.json("success");
} else {
res.status(400).json("Unable to udpate");
}
})
.catch((err) => console.log(err));
};
module.exports = {
handleProfile,
handleProfileUpdate,
};
I also recently added docker container to my backend and database, could that be the cause for the issue?
below is my github backend repo with the docker included
https://github.com/Moshe844/smartbrain-api/tree/master

Failed to execute 'send' on 'WebSocket': Still in CONNECTING state. using node.js, heroku, netlify

My frontend service is running on netlify.
And backend is on heroku.
I am trying to make chatApp.
After I entered chatRoom press sending button below error message pop up on console log.
"Failed to execute 'send' on 'WebSocket': Still in CONNECTING state."
I guess
problem is below code.
client
created() {
this.channel = this.$route.query.channel || '';
this.$store.state.user.stateWebSocket = new WebSocket('ws://peaceful-ridge-59102.herokuapp.com:9999/ws');
// this.websocket = new SockJS('http://localhost:8080/ws/realtime');
this.websocket=this.$store.state.user.stateWebSocket;
this.websocket.onmessage = ({ data }) => {
const vo = JSON.parse(data);
if (vo.channel === this.channel) {
this.appendNewMessage(this.tempName, vo.message, vo.time);
}
};
this.websocket.onopen = (event) => {
console.log('open event..', event);
};
this.websocket.onerror = (event) => {
console.log('error', event);
};
this.websocket.onclose = (event) => {
console.log('close', event);
};
}
This is sever.js
const cors = require('cors');
const express = require('express');
const app = express();
const WebSocket = require('ws');
const PORT = 9999;
app.use(
cors({
origin: true,
credentials: true,
})
);
const server = app.listen(PORT, () => {
console.log(PORT, 'waiting unitil connects');
});
app.get('/', (req, res) => {
res.send('Hello World!');
});
const wss = new WebSocket.Server({ server, path: '/ws' });
wss.on('connection', (ws, req) => {
// connection
console.log('새로운 클라이언트 접속');
ws.on('message', (message) => {
// receiving message
const json = JSON.parse(message.toString());
json.time = Date.now()
message = JSON.stringify(json)
console.log(message.toString());
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message.toString());
}
});
// Runs when client disconnects
wss.on('disconnect', () => {
});
});
ws.on('error', (err) => {
// error
console.error(err);
});
ws.on('close', () => {
// close
console.log('Client close');
clearInterval(ws.interval);
});
});
some people say I am sending your message before the WebSocket connection is established.
I am newbie on JS plz help me~!

ERR_HTTP_HEADERS_SENT node js socket connection

I am building an API that uses socket connection to interact with a server backend built in C#. This is what I have so far
const request = require('request');
const express = require('express');
const app = express();
var server = require('http').createServer(app);
var cors = require("cors");
app.use(cors());
const net = require('net');
const client = new net.Socket();
const stringToJson=require('./stringToJson')
const port = process.env.PORT;
const host = process.env.HOST;
client.keepAlive=true
client.on('close', function() {
console.log('Connection closed');
});
app.get('/getScores',function (req,res) {
let dataSend=''
client.on('data', function (data) {
console.log('Server Says : ' + data);
if(data!='ANALYSIS-ERROR'){
dataSend=stringToJson.stringToJson(data)
}
else{
dataSend=stringToJson.stringToJson('0:0.0:0.0:0.0:0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0:0:0.0:0.0:0.0:0.0:0.0')
}
client.destroy()
return res.send(dataSend)
});
client.connect(port, host, function () {
client.write(`GENERAL-ANALYSIS|${req.query.id}|${req.query.website}|`)
return
});
return
})
app.get('/getPlace',function (req,res) {
console.log(req.query)
request(
{ url: `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${req.query.name}+in+${req.query.city}&key=${process.env.API_KEY}` },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).json({ type: 'error', message: error.message });
}
return res.json(JSON.parse(body));
}
)
})
//TODO ADD 404 500 PAGES
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
server.listen(9000, () => {
console.log(`App running at http://localhost:9000`);
});
Basically it creates a connection with the server and listens for some data to be sent back. Then processes the string and sends it to the React frontend. The api calls are made by the frontend using axios
It works but if you refresh the page it throws this error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
How do I fix this?
Try setting the headers as found in the documentation request.setHeader(name, value)
request.setHeader('Content-Type', 'application/json');

How to subscribe a HTTP endpoint to SNS in node js?

I am trying to subscribe my endpoint to a topic (I am using an EC2 instance), I have tried visiting my endpoint in a browser (GET request) to call sns.subscribe but I am not receiving a POST request afterwards.
The response I get from calling sns.subscribe is this.
{ ResponseMetadata: { RequestId: 'xxxx-xxxx-xxxx-xxx-xxxx' },
SubscriptionArn: 'arn:aws:sns:topic_location:xxxx:topic_name:xxxx-xxxx-xxxx-xxx-xxxx' }
This is my code.
const express = require("express");
const AWS = require('aws-sdk');
const request = require('request')
const bodyParser = require('body-parser')
const app = express();
var SNS_TOPIC_ARN = "arn:aws:sns:topic_location:xxxx:topic_name";
// configure AWS
AWS.config.update({
'accessKeyId': 'mykey',
'secretAccessKey': 'mysecretkey',
"region":"myregion"
});
const sns = new AWS.SNS();
app.get('/', (req, res) => {
var params = {
Protocol: 'http', /* required */ //http , https ,application
TopicArn: SNS_TOPIC_ARN, /* required */ // topic you want to subscribe
Endpoint: 'http://ec2-xx-xx-xx-xxx.myregion.compute.amazonaws.com/:80', // the endpoint that you want to receive notifications.
ReturnSubscriptionArn: true //|| false
};
sns.subscribe(params, function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
res.end();
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.post('/', (req, res) => {
let body = ''
req.on('data', (chunk) => {
body += chunk.toString()
})
req.on('end', () => {
let payload = JSON.parse(body)
if (payload.Type === 'SubscriptionConfirmation') {
const promise = new Promise((resolve, reject) => {
const url = payload.SubscribeURL
request(url, (error, response) => {
if (!error && response.statusCode == 200) {
console.log('Yess! We have accepted the confirmation from AWS')
return resolve()
} else {
return reject()
}
})
})
promise.then(() => {
res.end("ok")
})
}
})
})
app.listen(80, process.env.IP, function(request, response){
console.log("## SERVER STARTED ##");
});
I had to remove my port number from the endpoint when calling sns.subscribe! My subscription has now been confirmed :D The new endpoint looks like this.
Endpoint: 'http://ec2-xx-xx-xx-xxx.myregion.compute.amazonaws.com/

NodeJS, Express and JSON API Response Time

I have create a simple express api to handle JSON data on my webapp.
Even if the app is on the same server, the response times are always on 100ms range, the actual data fetching is under 5ms;
Here is the data fetching zone :
export function getData(params) {
return new Promise((resolve, reject) => {
if (!params.take || params.take > 30 && isBrowser) {
params.take = 30;
}
console.time("API QUERY Execute");
{Data Fetching Goes here}
console.timeEnd("API QUERY Execute");
});
}
That method takes under 5 ms to complete from console.time.
Here is the express route config
app.route('/api/data').get((req, res) => {
getData(req.query)
.then((data) => {
res.json(data);
}).catch((err) => {
res.status(400);
res.send(err.message);
});
});
The actual Express App :
export default (parameters) => {
const app = Express();
const server = require('http').Server(app);
let io;
let redisCaching;
if (process.env.ENABLE_API === 'true') {
const Mongoose = require('mongoose');
const Redis = require('socket.io-redis');
Mongoose.connect(config.server.mongodb.url, config.server.mongodb.options);
Mongoose.connection.on('connected', () => {
console.log('==> Connected ', config.server.mongodb.url);
});
io = require('socket.io')(server);
io.sockets.on('connection', (socket) => {
console.log('==> Socket Connect', socket.handshake.headers.referer);
});
io.adapter(Redis({ host: 'localhost', port: 6379 }));
redisCaching = require('../../redis/redisCaching').redisCaching;
redisCaching.configure(6379, config.server.hostname);
}
if (process.env.CORS === 'true') {
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
}
app.route('/api/data').get((req, res) => {
getArticles(req.query)
.then((data) => {
res.json(data);
}).catch((err) => {
res.status(400);
res.send(err.message);
});
});
app.listen(process.env.PORT, () => {
console.log(`App listening on port ${process.env.PORT}`);
});
};
When using tools like pingdom, it showcases 100MS

Resources