How do I make Heroku to listen to multiple ports? - express

I am trying to host my application on Heroku but I get the below error from the logs:
Error: listen EADDRINUSE: address already in use :::27427
Apollo Server:
const { ApolloServer } = require("apollo-server");
const typeDefs = require("./server/graphql/typedefs");
const resolvers = require("./server/graphql/resolvers");
const server = new ApolloServer({ typeDefs, resolvers });
server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => {
console.log(`🚀 Apollo Server ready at ${url} 🚀`);
});
// Express server
const express = require("express");
const app = express();
const cors = require("cors");
app.use(express.json());
app.use(
cors({
origin: "http://localhost:3000",
})
);
const stripe = require("stripe")("sk_test_51Kv9RvGa9sOwxIsovOU0IliCRkL4Qrvi0F1dis4M4Slk1TvEzcuYrx4zBuLZH1iU76ygkDtoXA3Gky6RJEdaBTDa00fDh2Oh1g");
app.post("/create-checkout-session", async (req, res) => {
try {
const session = await stripe.checkout.sessions.create({
customer_email: req.body.email ? req.body.email : undefined,
payment_method_types: ["card"],
mode: "payment",
line_items: req.body.items.map((item) => {
return {
price_data: {
currency: "usd",
product_data: {
name: item.name,
},
unit_amount: item.price * 100,
},
quantity: item.quantity,
};
}),
success_url: `http://localhost:3000/paymentsuccess/${req.body.secret}`,
cancel_url: `http://localhost:3000/paymentfailed/${req.body.secret}`,
});
res.json({ url: session.url });
} catch (e) {
res.status(500).json({ error: e.message });
}
});
app.listen({ port: process.env.PORT || 5001 }, () => {
console.log("🚀 Express server ready at http://localhost:5001 🚀");
});
I think the issue is that I am using both Apollo Server and Express Server in my app. But I need the express for my stripe application. Is there a way so that Heroku can listen to both of my ports?

Related

Cannot Established connection to Express Websocket Server from Nuxt JS using nuxt-socket-io

I have this following problem where I cannot establish connection from nuxt js app to express websocket
Here's my following code :
Server Side (websocket server) at index.js
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http, {
cors: {
origin: '*'
}
});
const port = 4000;
http.listen(port, () => {
console.log('server is up');
io.on('connection', (socket) => {
console.log('Connection established');
console.log(socket.id);
})
})
Client Side (nuxt js)
In nuxt.config.js
...
modules: [
...
'nuxt-socket-io'
]
...
io: {
sockets: [{
name: 'arena',
default: true,
url: 'http://localhost:4000',
}]
}
In component that uses websocket :
<template></template>
<script>
export default {
data() {
return {
socket: {},
};
},
mounted() {
this.socket = this.$nuxtSocket({
name: "arena",
channel: "/index",
reconnection: false,
});
this.socket.emit('connection')
},
};
</script>
The error I got from console log is :
GET http://localhost:4000/socket.io/?EIO=4&transport=polling&t=OMPZ7YZ&sid=WOhe-UjXtVOJoPlIAAAG 400 (Bad Request)
And the console.log from the server does not produce any output
What did I missed?

Vue 3, Socket IO - not listening to event

For server side I have following code:
const path = require("path");
const http = require("http");
const express = require("express");
const {instrument} = require('#socket.io/admin-ui')
const app = express()
const server = http.createServer(app)
const io = require("socket.io")(server, {
cors: {
origin: ["https://admin.socket.io", "http://localhost:3001"],
credentials: true
},
});
instrument(io, { auth: false });
server.listen(3000, () =>
console.log('connected')
)
io.on('connection', socket => {
console.log("user connected");
socket.on("join", function (room) {
console.log(room);
socket.join(room);
});
socket.on('newOrder', function (data) {
socket.emit('this', data)
console.log(data);
})
socket.on("thisNew", function (data) {
console.log('this new');
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
})
and in the Vue (client side) I have following:
import VueSocketIO from 'vue-3-socket.io'
import SocketIO from 'socket.io-client'
export const useSocketIO = () => {
const socket = new VueSocketIO({
debug: true,
connection: SocketIO('http://localhost:3000')
})
return {
socket,
}
}
And in the component:
<script setup>
import { useSocketIO } from "#/services/socketio"
const { socket } = useSocketIO()
onMounted(async () =>
{
await socket.io.emit('join', 'servant')
socket.io.on('this', () =>
{
console.log('event this fired')
})
})
</script>
Event this is emitted from the server, but nothing is happening on the client side. What am I doing wrong here?

Heroku to netlify session wont store session values

This works fine when I am running it on Localhost3000(client) and localhost:3005(server). However once I publish my app to Heroku(server) and netlify(client) it for some reason tells me the req.session.steamuser when accessing /user is null even after it has been set in /api/auth/steam/return and I have tested that the req.session.steamuser=req.user accutally work.
Server.js
var express = require('express');
var passport = require('passport');
var session = require('express-session');
var passportSteam = require('passport-steam');
const cors = require("cors");
var SteamStrategy = passportSteam.Strategy;
var app = express();
const corsOptions = {
origin: ["https://stunning-bavarois-0eef55.netlify.app"],
credentials: true, //access-control-allow-credentials:true
methods: ["GET", "POST"],
};
app.use(cors(corsOptions));
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
passport.use(new SteamStrategy({
returnURL: 'https://temtestt.herokuapp.com/api/auth/steam/return',
realm: 'https://temtestt.herokuapp.com/',
apiKey: 'MY SECRET API KEY'
}, function (identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
));
app.use(session({
secret: 'db5910cc8b9dcec166fda1d2c34860b6f8cd932cea641ea39924ed18fe6fc863',
resave: true,
saveUninitialized: true,
cookie: {
SameSite:"none",
maxAge: 3600000,
secure:true
}
}))
// Initiate Strategy
app.use(passport.initialize());
app.use(passport.session());
app.get('/', (req, res) => {
res.status(200);
res.send("Welcome to root URL of Server");
});
app.get("/user", (req, res) => {
if (req.session.steamuser) {
res.status(200).send(req.session.steamuser)
}
else {
res.send(false)
}
})
app.get('/api/auth/steam', passport.authenticate('steam', { failureRedirect: '/' }), function (req, res) {
res.redirect('/')
});
app.get('/api/auth/steam/return', passport.authenticate('steam', { failureRedirect: '/' }), function (req, res) {
req.session.steamuser = req.user;
res.redirect('https://stunning-bavarois-0eef55.netlify.app/')
});
app.listen(process.env.PORT || 3005);
Client
import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [user,setUser]=useState(null);
useEffect(()=>{
async function getUser(){
const data = await axios.get("https://temtestt.herokuapp.com/user",{withCredentials:true});
setUser(data.data);
}
getUser();
},[]);
return (
<div className="App">
<h1>Hello</h1>
{(user===false||user===null)?<><p>Please log in</p>Login</>:<p>{user.displayName}</p>}
</div>
);
}
export default App;
As mentioned already it works fine when I do with localhost and returns correct values. But when I try with netlify and heroku it almost seems like it doesn't recognize the session key or something.

How can I prevent third-party cookies from being set on my site?

I just noticed that some third-party tracking cookies have been set on my website without notifying me.
<img src="https://i.pravatar.cc/64" />
Rendering this creates 2 google analytics cookies on my site.
https://pravatar.cc/
They have no notices about setting cookies or tracking sites when using their API.
This is my server setup:
declare module 'express-session' {
export interface SessionData {
user: {
id: string;
organisation: string;
};
}
}
const startApolloServer = async () => {
const RedisStore = connectRedis(session);
const redisClient = createClient({ legacyMode: true });
redisClient.connect().catch(console.error);
const app = express();
//Redis
app.use(
session({
name: 'uId',
store: new RedisStore({ client: redisClient, disableTouch: true }),
saveUninitialized: false,
secret: 'mysecret',
resave: false,
cookie: {
maxAge: 1000 * 60 * 60 * 24, //One day
secure: false, //dev only
httpOnly: false, //dev only
sameSite: 'lax',
},
}),
);
const server = new ApolloServer({
schema,
context: ({ req, res }: { req: Request; res: Response }) => ({
req,
res,
}),
});
await server.start();
server.applyMiddleware({
app,
cors: {
credentials: true,
origin: ['http://localhost:3000', 'http://localhost:4000'],
},
bodyParserConfig: true,
});
await new Promise((resolve) =>
app.listen({ port: 4000 }, resolve as () => void),
);
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
return { server, app };
};
startApolloServer();
How can I allow cookies to be set only from my http api (Later my https api)?

fetch POST request is pending (sending data from registration form)

I know that similar questions have already been here, but I didn't find anything for my problem.
I am creating project using [Webpack-Express-Pug-VanillaJS] stack of technologies.
I'm trying to make POST-request to send formData to '/api/users' using fetch a push data to array in my express file, but its only pending...
What kind of problems it can be?
client-side code
document.addEventListener('DOMContentLoaded', () => {
async function postData(url, data) {
try {
console.log('addEventListener works!')
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
console.log('fetch works!')
return await response.json()
} catch(e) {
console.warn('Error',e.message)
}
}
const forms = document.getElementsByTagName('FORM');
for (let i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(e) {
console.log(forms[i])
e.preventDefault();
let formData = new FormData(this);
formData = Object.fromEntries(formData);
console.log(formData) return object like {name:'Zhanna', age:25, email:'123zhanna#gmail.com'}
postData('/api/users', formData).then(data => console.log('Successful!'))
})
}
})
server-side
const path = require('path')
const express =require('express')
const webpack = require('webpack')
const bodyParser = require('body-parser')
const users = require('../routes/userInfo')
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from '../../webpack.dev.config.js'
import { v4 } from 'uuid';
const PORT = process.env.PORT || 8080
const app = express(),
compiler = webpack(config)
app.use(users.router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.json());
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'pug');
app.locals.basedir = __dirname;
app.use('/assets',express.static(path.join(__dirname,'assets')))
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
})
)
app.use(webpackHotMiddleware(compiler))
app.get('/registration', (req,res)=> {
res.status(200).render('registration')
})
app.get('/login', (req,res)=> {
res.status(200).render('signIn')
})
app.get('/', (req, res) => {
res.status(200).render('index')
}
)
app.get('/api/users', (req,res)=> {
res.status(200).json(users.list)
})
app.post('/api/users', (req,res)=> {
const user = {...req.body, id:v4()}
users.list.push(user)
console.log('Data was sent')
res.status(201).json(user)
})
app.listen(PORT, () => {
console.log(`App listening to ${PORT}....`)
console.log('Press Ctrl+C to quit.')
})
And in my console there is only 3 logs:
addEvent listener works!
<form class="registration--form" id="send-form">...<form>
3.{name: "Zhanna", surname: "Kaymedenova", gender: "female", brth: "07.01.1994", email: "zh.kaymed#gmail.com"}