Continuously changing Express Route Paths for protection - javascript

I want to create a hidden internal webserver with ever-changing routes.
The aim is to prevent/deter people from scraping the site or using the API without permission.
There's probably a better way (or this could be totally useless)
I've written some code that works but either convince me why I'm wasting my time or why it would work.
const express = require('express');
const uuid = require('uuid/v4');
const app = express();
// These are the hidden routes
const routes = {
hiddenPage: undefined,
};
setInterval(() => {
// Change the path of the hidden page
// every 5 seconds
routes.hiddenPage = `/${uuid()}`;
}, 1000 * 5);
app.get('*', (req, res) => {
// There would be other middleware for
// security reasons
if (req.path === routes.hiddenPage) {
res.send('Welcome to the hidden page');
return;
}
res.send(`Page at <a href=${routes.hiddenPage}>${routes.hiddenPage}</a>`);
});
// Listen on 3000
app.listen(3000);

You can use CORS middleware to allow only specific clients to access your server.
https://expressjs.com/en/resources/middleware/cors.html
Example:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

Related

Subdomain routing node.js and express

I am trying to make a site where the code checks what subdomain the user is accessing from. I can get the host by running this:
app.get('/', (req, res) => {
const host = req.get('host');
const origin = req.get('origin');
res.send(host)
})
And i get the result: localhost:5000.
But i want to make it so that if the user is accessing from domain1.com it uses one router, and if it is from domain2.com it uses another. here is the code im trying to use:
server.js
const express = require('express')
const app = express()
const router = express.Router();
app.set('view engine', 'ejs')
app.get('/', (req, res) => {
const host = req.get('host');
const origin = req.get('origin');
if(host === "domain1.com:5000"){
const test = require('./routes/test.js')
app.use('/', test)
}else if(host === "domain2.com:5000"){
res.send("Domain2")
}else{
res.send(host)
}
})
app.listen(5000)
/routes/test.js
const express = require('express')
const router = express.Router()
router.get('/', async (req, res) => {
res.send("it Works")
})
module.exports = router
When i try accessing the domain1 it does not work, and i don't get any errors in console

Respond to client after receiving client to server POST request (Node.JS)

I have been attempting to respond to a client-side request with Node.JS. I have discovered Node JS - call function on server from client javascript, which seems to explain what I want, except that I can't seem to translate it to my program.
Here is the request via POST in index.html:
$.post("/", {data: 'hi'}, function(result){
$("body").html(result);
});
what I was hoping it would do would be write the result of the call, from my server.js (Node):
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/*', (req, res) => res.sendFile('static/index.html', { root: BUILDPATH }));
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
try this code:
const express = require('express');
const path = require('path');
const http = require('http');
const fs = require('fs');
function handler(data, app){
if(req.method == "POST"){
app.setHeader('Content-Type', 'text/html');
app.writeHead(200);
app.end(data);
}
}
const BUILDPATH = path.join(__dirname);
const { PORT = 3000 } = process.env;
const app = express();
app.set('port', PORT);
app.use(express.static(BUILDPATH));
app.get('/', (req, res) => {
res
// best practice is to always return an status code
.status(200)
// just return an json object
.json({"msg": "ok, it all works just fine"})
});
const httpServer = http.createServer(app);
httpServer.listen(PORT);
console.info(`🚀 Client Running on: http://localhost:${PORT}`);
The issue is, is that the only route your Node server listens to is the one you define with /*. As you can see, that route returns your index.html file to the client. You did not specify a route that listens for a request that comes from the client.
To solve the issue, you will have to define a route that listens on a specific route for the request you are trying to make from your client.
I see you are using ExpressJS. here is the documentation on writing routes.

Implementing socket.io in mongoDB and Angular it is throwing errors Cannot GET /socket.io/

I am developing an angular application which I need to use notifications for example.
I have a user which can add friends and then I can sent a friend request as in facebook and then the other user will be notificate in realtime for example You have one new notification, this user wants to be friends.
If anyone has better idea than socket.io I am free to listen and to learn
The problem it is that I get everytime Cannot GET /socket.io/
Request URL: http://localhost:4200/socket.io/?EIO=3&transport=polling&t=NVvJf99
Request Method: GET
Status Code: 404 Not Found
Remote Address: 127.0.0.1:4200
I can show the list who sent me friend but I need everytime to reload page to see new requests.
I am using socket.io in both frameworks.
Angular I have installed with npm and the same in the mongoDB.
My server.js that is what I use for the requests and responses in frontend.
Server.js
const express = require('express');
const mongoose = require('mongoose');
const http = require('http');
const cors = require('cors');
const routes = require('./src/app/routes/routes');
const path = require('path');
const socketIO = require('socket.io');
const app = express();
const server = http.Server(app);
mongoose.connect('mongodb+srv://vip:admin#test-name-sn4qu.mongodb.net/test?retryWrites=true&w=majority'
, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
});
app.use(cors());
const io = socketIO(server);
app.set(io);
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit: '50mb', extended: true}));
app.use('/images', express.static(path.resolve(process.cwd(), '../images')));
app.use(routes);
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
app.get("/", (req, res) => {
res.json({ message: "Welcome to application." });
});
const PORT = process.env.PORT || 5000;
server.listen(PORT);
And then in the friendController I use something like this.
function createNewRequest(req, res, next) {
const io = req.app.get('io');
friendService.createNewRequest(req.body)
.then(res.status(200).json({ message: 'Friend added successfully' }),
io.emit('newTaskAdded'))
.catch(err => next(err));
}
And then in the frontend I do have something like this.
And I am having an error which says
Cannot find namespace 'SocketIOClient'. private socket:SocketIOClient.Socket;
import * as io from "socket.io-client";
constructor() {
this.socket = io();
}
ngOnInit(): void {
this.LoadRequestingFriends();
this.socket.on('newTaskAdded', () => {
this.LoadRequestingFriends();
})
}

How can we implement an admin panel in nodeJS with express?

I am making a Portfolio application with nodeJS and express. I want to implement an admin panel which I can create,delete, update and edit my skills,experience,about etc, but I don't know how can I keep those admin routes secret and what kind of authentication to make.If we can do by putting Basic authentication on post,patch,delete route then how will we implement basic authentication on routes.
index.js
const express = require('express');
const app = express();
var cors = require('cors');
require('./db/mongoose')
const menuRouter = require('./routers/menu')
const skillRouter = require('./routers/skill')
const aboutRouter = require('./routers/About')
const experienceRouter = require('./routers/Experience')
const resumerouter = require('./routers/Resume')
const userRouter = require('./routers/user')
const port = process.env.PORT || 4000;
app.use(express.json());
app.use(cors());
app.use(menuRouter);
app.use(skillRouter);
app.use(aboutRouter);
app.use(experienceRouter);
app.use(resumerouter);
app.use(userRouter)
app.listen(port, () => {
console.log("Server is runing on port" + port)
});
skill.js
const express = require('express');
const Skill = require('../model/skill');
const router = new express.Router();
router.post('/skill', async (req, res) => {
const skill = new Skill(req.body);
try {
await skill.save();
res.status(201).send(skill);
} catch (e) {
console.log(e);
res.status(400).send(e);
}
})
router.get('/skill', async (rq, res) => {
try {
const skill = await Skill.find({});
res.status(201).send(skill);
} catch (e) {
res.status(400).send(e);
}
})
module.exports = router;
As specified in the comments, I would refactor your code a bit, seems messy and you're kind'a repeating yourself every line you import a route, so, you should do it better as well...
have an index.js file in your /routers folder with the content of the demo repo I've made for other StackOverflow question
then, to separate things, I would do something like:
const routes = require('./routes')
...
const protectRouteWithApiKey = (req, res, next) => {
const auth = req.headers['x-apikey']
if (auth && auth === '<YOUR API KEY>') return next()
return next(new Error('403 | Authorization is missing or value is wrong'))
}
...
app.use('/api', protectRouteWithApiKey, routes) // point to your routes and protect access
app.use('/', defaultEngine) // your engine to render html
you would then have a protected route in /api/* and normal routes for everything else
A middleware where you detect if the logged user is the admin?
In this sample checking by the email, and you can save the adminemail as a global variable
ensureAdmin: function(req, res, next) {
if (req.isAuthenticated()) {
if (req.user.email === adminemail) {
return next();
} else {
return res.redirect('/adminsecretroute');
}
}
res.redirect('/');
}

cookie doesn't get sent on first request

I've got the following code on my server.js express application:
var express = require('express');
var fallback = require('express-history-api-fallback');
var compress = require('compression');
var favicon = require('serve-favicon');
var prerenderio = require('prerender-node');
var config = require('getconfig');
var app = express();
app.use(function (req, res, next) {
if (config.environment !== 'local') {
res.cookie('config', JSON.stringify(config), { secure: true });
}
else {
res.cookie('config', JSON.stringify(config));
}
next();
});
app.get('/versioncheck', function(req, res) {
return res.json({ version: config.version });
});
app.use(compress());
app.use(prerenderio.set('prerenderToken', config.prerender_token).set('protocol', 'https'));
app.use(express.static(__dirname, { maxAge: 31536000 }));
app.use(favicon(__dirname + '/favicon.ico'));
app.use(fallback('index.html', { root: __dirname }));
const PORT = process.env.PORT || 1010;
app.listen(PORT, function () {
console.log('Server started on port %s', PORT);
});
The first middleware I'm setting up with express is quite simple: It sends down a cookie to the client with some config information. The issue I'm facing is that this cookie doesn't get sent down to the client upon first request. For all subsequent requests it does work fine. What am I missing?
I had a similar problem some time ago.
At the begin of the first request, the cookie does not exist.
The cookies get sent during the request, not before.
So, at the begin of the second request, the cookie is set (from request 1).

Categories