I have a chat app i'm building, it works fine offline but in production, it refuses to connect and it gives out this error in the browser.
Blocked loading mixed active content
here is the code for the back end app.js
const http = require("http");
const express = require("express");
const app = express();
const path = require("path");
const server = http.createServer(app);
const dotenv = require("dotenv").config();
const router = require(path.join(__dirname + "/modules/router.js"));
const mongoose = require("mongoose");
const URL = process.env.DB_URL;
const Schema = require(path.join(__dirname + "/modules/Schema.js"));
const io = require("socket.io")(server, {
cors: {
origin: "*",
},
});
app.use(router);
mongoose.connect(URL, (err) => {
if (err) throw err;
else {
server.listen(process.env.PORT, console.log("Server is running"));
}
});
io.on("connection", (socket) => {
let payload = socket.handshake.auth.$token;
socket.emit("thru", true);
socket.on("join", async (link, cb) => {
// Checking users
Schema.Link.findOne({ code: link }, (err, d) => {
if (err || d == " ") cb(false, false);
else {
if (d.onlineUsers.length < 2) {
if (d.onlineUsers.includes(payload)) {
cb(true, true);
} else {
// Adding user
d.onlineUsers.unshift(payload);
Schema.Link.findOneAndUpdate(
{ code: link },
{ onlineUsers: d.onlineUsers },
(err, x) => {
if (err || x == "") cb(false, false);
else {
if (x.onlineUsers.length == 1) cb(true, true);
else cb(true, false);
}
}
);
}
} else cb(false, false);
}
});
socket.join(link);
socket.broadcast.to(link).emit("online", true);
socket.on("message", (m, cb) => {
m.date = new Date();
socket.broadcast.to(link).emit("broadcast", m);
cb(m);
});
});
socket.on("disconnect", (data) => {
const $link = socket.handshake.auth.$link;
Schema.Link.findOne({ code: $link })
.then((x) => {
if (x == "") console.log("user not found");
else {
let n = x.onlineUsers.filter((c) => c !== payload);
Schema.Link.findOneAndUpdate(
{ code: $link },
{ onlineUsers: n },
(err) => {
if (err) console.log(err);
else {
socket.broadcast.to($link).emit("online", false);
}
}
);
}
})
.catch((e) => {
console.log("Ending", e);
});
});
});
And here is the front end chat screen
useEffect(() => {
try {
socket.current = io("http://chatterbox-v2-api.vercel.app", {
auth: {
$token: localStorage.getItem("senders_token"),
$link: link,
},
});
} catch (err) {
console.log("Error");
}
i've tried hosting the scoket server on another platform but nothing.
I think the problem here is that you are trying to reach a HTTP server (http://chatterbox-v2-api.vercel.app) from a page served with HTTPS, which triggers an "Blocked loading mixed active content" error.
Reference: https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
Is your server available with HTTPS (https://chatterbox-v2-api.vercel.app)?
Related
I make a Longpolling for this little project but alot of Network Request are been sent and later ther browser froze
.
Is there anything that i am doing wrong here
On the server side
server.js
`
//...
const PORT = 3000;
let subscribers = Object.create(null);
const server = createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const urlPath = parsedUrl.pathname;
const queryStringObject = parsedUrl.query;
const method = req.method.toLowerCase();
if (urlPath === "/" && method === "get") {
res.writeHead(200, {
"Content-Type": "text/html",
"Access-Control-Allow-Origin": "*",
});
res.end(`<h1>Home Page of the API</h1>`);
return;
}
if (urlPath === "/datas" && method === "get") {
res.writeHead(200, {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "no-cache, must-revalidate",
});
let id = Math.random();
subscribers[id] = res;
fs.readFile(`${process.cwd()}/data/datas.json`, "utf-8", (err, data) => {
res.end(data);
});
req.on("close", function () {
delete subscribers[id];
// console.log(`${id} deleted`);
});
return;
}
});
server.listen(PORT, (err) => {
console.log(`Server up and running,\nYou can now visit http://localhost:3000`);
});
`
and on the client Side
app.js
`
const prices = document.querySelector(".prices");
function createEl(resultDatas) {
prices.innerHTML = "";
resultDatas.forEach((resultData) => {
const div = document.createElement("div");
div.classList.add("element-container");
const p = document.createElement("p");
p.innerHTML = resultData.title;
if (resultData.title.toLowerCase() === "silver") {
p.classList.add(`silver`);
}
p.classList.add(`title`);
div.appendChild(p);
const h3 = document.createElement("h3");
h3.innerHTML = resultData.price;
h3.classList.add("price");
div.appendChild(h3);
prices.append(div);
});
}
let tickerData = null;
const fetchTickerValue = async () => {
try {
const response = await fetch("http://localhost:3000/datas");
const data = await response.json();
createEl(data);
} catch (error) {
console.error(error?.message ?? "ticker call failed");
} finally {
fetchTickerValue();
}
};
fetchTickerValue();
if (tickerData) console.log(tickerData);
`
I want only one request to be send while waiting for the response from the server
My app fails on prod and can't find a way how to fix. It works on another environments.
Some logs from the console:
2022-08-22T23:56:05.760Z INFO - Waiting for response to warmup request for container projectprod-fe_0_fd84e. Elapsed time = [225.2643051] sec
2022-08-22T23:56:35.818Z ERROR - Container projectprodfe_0_fd84e for site teamgullitpreview-fe did not start within expected time limit. Elapsed time = 255.322965 sec
It is next.js app and I create middlewares for it.
const next = require('next');
const { parse } = require('url');
nextMiddleware
async function nextMiddleware(dev = false) {
const app = next({ dev });
const handle = app.getRequestHandler();
await app.prepare();
return function nextHandler(req, res) {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
};
}
redirectMiddleware
const path = require('path');
const fs = require('fs');
const staticFiles = ['_next', '/', 'images', 'api'];
const getRedirect = async (srcPath) => {
try {
const url = `${process.env.NEXT_PUBLIC_apiUrl}/redirect?path=${srcPath}`;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (e) {
throw new Error(e);
}
};
function redirecter(pathname) {
return new Promise((resolve, reject) => {
const pathParts = pathname.split('/');
if (staticFiles.indexOf(pathParts[1]) > -1) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
const possibleFile = `${path.resolve(
__dirname,
'../../public',
)}${pathname}`;
if (fs.existsSync(possibleFile)) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
getRedirect(pathname)
.then((result) => {
resolve({
shouldRedirect: true,
redirectData: result,
});
})
.catch((e) => {
reject(e);
});
}
}
});
}
async function redirectMiddleware(req, res, next) {
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
try {
const { shouldRedirect, redirectData } = await redirecter(pathname);
if (shouldRedirect && redirectData.destination) {
const redirectUri = `${process.env.NEXT_PUBLIC_hostname}${
redirectData.type ? redirectData.type : ''
}${redirectData.destination}`;
res.writeHead(redirectData.statusCode[0], {
Location: redirectUri,
});
res.end();
}
} catch (e) {
next();
} finally {
next();
}
}
What I do wrong in this file or whenever?
const http = require('http');
const express = require('express');
const redirectMiddleware = require('./src/server/redirectMiddleware');
const nextMiddleware = require('./src/server/nextMiddleware');
const port = process.env.PORT || 3000;
async function bootstrap() {
const isDevelopment = process.argv.includes('--dev');
const app = express();
app.use(await redirectMiddleware);
app.use(await nextMiddleware(isDevelopment));
const server = http.createServer(app);
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
}
bootstrap().catch((err) => {
console.error('something went wrong booting up the server.');
console.error(err);
process.exit(1);
});
I have no idea what's wrong and how to debugg it. Is anyone who experienced it before?
I have been working on a real-time tweet streamer app. Whenever the app tries to fetch new tweets, it throws up repeating errors in the console.
I looked into possible solutions and people suggested using the following code:
cors: {
origin: "*",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
But this error led to another issue and now, my bearer token is not being authenticated.
I am attaching the code of the server.js file below. Would really appreciate it if someone could help me understand the error and the solutions.
const express = require("express");
const bodyParser = require("body-parser");
const util = require("util");
const request = require("request");
const path = require("path");
const socketIo = require("socket.io");
const http = require("http");
const app = express();
let port = process.env.PORT || 3000;
const post = util.promisify(request.post);
const get = util.promisify(request.get);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const server = http.createServer(app);
const io = socketIo(server);
const BEARER_TOKEN = process.env.TWITTER_BEARER_TOKEN;
let timeout = 0;
const streamURL = new URL(
"https://api.twitter.com/2/tweets/search/stream?tweet.fields=context_annotations&expansions=author_id"
);
const rulesURL = new URL(
"https://api.twitter.com/2/tweets/search/stream/rules"
);
const errorMessage = {
title: "Please Wait",
detail: "Waiting for new Tweets to be posted...",
};
const authMessage = {
title: "Could not authenticate",
details: [
`Please make sure your bearer token is correct.
If using Glitch, remix this app and add it to the .env file`,
],
type: "https://developer.twitter.com/en/docs/authentication",
};
const sleep = async (delay) => {
return new Promise((resolve) => setTimeout(() => resolve(true), delay));
};
app.get("/api/rules", async (req, res) => {
if (!BEARER_TOKEN) {
res.status(400).send(authMessage);
return;
}
const token = BEARER_TOKEN;
const requestConfig = {
url: rulesURL,
auth: {
bearer: token,
},
json: true,
};
try {
const response = await get(requestConfig);
if (response.statusCode !== 200) {
if (response.statusCode === 403) {
res.status(403).send(response.body);
return;
} else {
throw new Error(response.body.error.message);
}
}
res.send(response);
return;
} catch (e) {
res.send(e);
return;
}
});
app.post("/api/rules", async (req, res) => {
if (!BEARER_TOKEN) {
res.status(400).send(authMessage);
return;
}
const token = BEARER_TOKEN;
const requestConfig = {
url: rulesURL,
auth: {
bearer: token,
},
json: req.body,
};
try {
const response = await post(requestConfig);
if (response.statusCode === 200 || response.statusCode === 201) {
res.send(response);
return;
} else {
throw new Error(response);
}
} catch (e) {
res.send(e);
return;
}
});
const streamTweets = (socket, token) => {
let stream;
const config = {
url: streamURL,
auth: {
bearer: token,
},
timeout: 31000,
};
try {
const stream = request.get(config);
stream
.on("data", (data) => {
try {
const json = JSON.parse(data);
if (json.connection_issue) {
socket.emit("error", json);
reconnect(stream, socket, token);
} else {
if (json.data) {
socket.emit("tweet", json);
} else {
socket.emit("authError", json);
}
}
} catch (e) {
socket.emit("heartbeat");
}
})
.on("error", (error) => {
// Connection timed out
socket.emit("error", errorMessage);
reconnect(stream, socket, token);
});
} catch (e) {
socket.emit("authError", authMessage);
}
};
const reconnect = async (stream, socket, token) => {
timeout++;
stream.abort();
await sleep(2 ** timeout * 1000);
streamTweets(socket, token);
};
io.on("connection", async (socket) => {
try {
const token = BEARER_TOKEN;
io.emit("connect", "Client connected");
const stream = streamTweets(io, token);
} catch (e) {
io.emit("authError", authMessage);
}
});
console.log("NODE_ENV is", process.env.NODE_ENV);
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../build")));
app.get("*", (request, res) => {
res.sendFile(path.join(__dirname, "../build", "index.html"));
});
} else {
port = 3001;
}
server.listen(port, () => console.log(`Listening on port ${port}`));
You can not use wildcard origin and credentials at the same time. If you want to use credentials specify domains explicitly.
cors: {
origin: "*", // <-- set origin explicitly.
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
I´ve the file cases.js to create the route I want:
const express = require("express");
const { requireSignin } = require("../controllers/auth");
const { getCases } = require("../controllers/cases");
const { scrapingData } = require("../scrapingData");
const router = express.Router();
router.get("/cases", requireSignin, scrapingData, getCases);
module.exports = router;
requireSignin from controllers/auth looks like this:
exports.requireSignin = expressJwt({
secret: process.env.JWT_SECRET,
userProperty: "auth",
});
scrapingData as middleware I have:
const updateMongoRecords = async () => {
mongoose.Promise = global.Promise;
mongoose.set("debug", true);
Case.deleteMany({}, (err, result) => {
if (err) {
console.log(err);
} else {
console.log("Successfully deleted all records");
}
});
const dataPath = Path.join(__dirname, "files", "covid-data.csv");
try {
let headers = Object.keys(Case.schema.paths).filter(
(k) => ["_id", "__v"].indexOf(k) === -1
);
await new Promise((resolve, reject) => {
let buffer = [],
counter = 0;
let stream = fs
.createReadStream(dataPath)
.pipe(csv())
.on("error", reject)
.on("data", async (doc) => {
stream.pause();
buffer.push(doc);
counter++;
// log(doc);
try {
if (counter > 10000) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
}
} catch (e) {
stream.destroy(e);
}
stream.resume();
})
.on("end", async () => {
try {
if (counter > 0) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
resolve();
}
} catch (e) {
stream.destroy(e);
}
});
});
} catch (e) {
console.error(e);
} finally {
process.exit();
}
};
exports.scrapingData = async (req, res, next) => {
const url = "https://covid.ourworldindata.org/data/owid-covid-data.csv";
const path = Path.resolve(__dirname, "files", "covid-data.csv");
const response = await Axios({
method: "GET",
url: url,
responseType: "stream",
});
response.data.pipe(fs.createWriteStream(path));
return new Promise((resolve, reject) => {
response.data.on("end", () => {
resolve(updateMongoRecords());
next();
});
response.data.on("error", (err) => {
reject(err);
});
});
};
And getCases.js inside controllers/cases I have:
const Case = require("../models/case");
exports.getCases = async (req, res) => {
const cases = await Case.find().then((cases) => res.json(cases));
};
With this code I am able to fetch in the route /cases all the cases in the client side (like postman) and it shows all of them. But the problem is that I can´t make any other requests (like signing out, which works fine if I don´t make the get request for the cases like before) afterwards because client (postman) gives the error: GET http://localhost:5000/signout
Error: connect ECONNREFUSED 127.0.0.1:5000
in case you want to see the code for signout is like this:
const express = require("express");
const { signup, signin, signout } = require("../controllers/auth");
const router = express.Router();
router.post("/signup", userSignupValidator, signup);
router.post("/signin", userSigninValidator, signin);
router.get("/signout", signout);
inside controllers/auth.js:
exports.signout = (req, res) => {
res.clearCookie("t");
return res.json({ message: "Signout successfully done" });
};
Any help on this??
I am at a complete loss as to why this is not working, I am new to using Hooks in react however want to try.
This app basically connects sockets.io to the server using sockets-auth server emits the time every 1s <- this shows me that the connection is definitely live. It then uses sockets.emit to receive an array of data, this functions. The part that doesn't is a simple button press fails to achieve anything (see both 'Save Changes' buttons at bottom of React element). No error, no response, no acknowledgment at all. I have tried it inline, in its own function. The exact same server routes are functional simultaneously running a separate app with class components.
Help would be much appreciated. Anyway here is some code..
Client-Side (React.js)
import React, { Component,useState, useEffect } from "react";
import io from "socket.io-client";
import './Secret.css'
const Secret = () => {
const [time, setTime] = useState('');
const [userlist, setUserlist] = useState([]);
const socketUrl = 'http://localhost:3001';
let socket = io(socketUrl, {
autoConnect: false,
});
useEffect(() => {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'React POST Request Example' })
};
fetch('/api/connectsocket', requestOptions)
.then(async response => {
const data = await response.json();
if (!response.ok) {
const error = (data && data.message) || response.status;
return Promise.reject(error);
}
console.log(data)
connectSocket(data)
})
.catch(error => {
console.error('There was an error!', error);
});
}, [socketUrl]);
const connectSocket= (data)=>{
let dataUser = data
console.log(dataUser.email)
let error = null;
socket.on('connect', () => {
console.log('Connected');
socket.emit('authentication', {
token: dataUser.email,
i: dataUser.i
});
});
socket.on('unauthorized', (reason) => {
console.log('Unauthorized:', reason);
error = reason.message;
socket.disconnect();
});
socket.on('disconnect', (reason) => {
console.log(`Disconnected: ${error || reason}`);
error = null;
});
socket.on("admin connected", data => {
socket.emit('admin userlist', { get:'x',for:'who' }, (error) => {
if(error) {
alert(error);
}
});
console.log(data)
});
socket.on("admin user list", data => {
setUserlist(data)
console.log(data)
});
socket.on("FromAPI", data => {
setTime(data)
console.log(data)
});
socket.open();
}
const sendMessage = (x)=>{
console.log(x)
socket.emit('hello', 'JSON.stringify(x)');
}
const doSomething = ()=>{
socket.emit('chatmessage', {msg:"Hello"});
}
return (
<div>
<div className="outerContainer">
<div className="container">
{time}
<button onClick={sendMessage}>Save Changes</button>
<button onClick={doSomething}>Save Changes</button>
{userlist.map(user => (
<tr key={user.id} value={user.id}>
<td>{user.email}</td>
<td>{user.email}</td>
<td>{user.email}</td>
</tr>
))}
</div>
</div>
</div>
);
}
export default Secret
Server-side (Node.js)
const http = require('http');
const cors = require('cors');
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const io = require('socket.io')();
const socketAuth = require('socketio-auth');
//custom modules
const router = require('./modules/router');
const db = require('./modules/db.js');
const prettyDate = require('./modules/prettyDate.js');
const sortArray = require('./modules/sortArray.js');
const app = express();
const server = http.createServer(app);
io.attach(server);
app.use(cors()); ///delete for production
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileUpload({
createParentPath: true
}));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(router);
app.use(express.static('public'))
db.i12345.sessions.persistence.setAutocompactionInterval(400)
////Sessions Store; not important if you want to run the code without
function setUser(id,user,i){
console.log('setuser')
let institution = i
db[institution].sessions.find({ user:user }, function (err, docs) {
if(docs.length){
db[institution].sessions.update({user:user }, { $set: { id: id } }, { multi: true }, function (err, numReplaced) {
});
} else {
var d = new Date();
var n = d.getTime();
var doc = { user: user
, id: id
, t:n
};
db[institution].sessions.insert(doc, function (err, newDoc) {
});
}
});
}
///user verification; could easily mock; if wanting to actually run code
async function verifyUser (token,i) {
var institution =i
return new Promise((resolve, reject) => {
// setTimeout to mock a cache or database call
setTimeout(() => {
var user = new Promise((resolve,reject) =>{
db[institution].users.find({email:token}, function (err, docs) {
if(docs.length){
resolve(docs);
} else {
reject(false)
}
});
});
if (!user) {
return reject('USER_NOT_FOUND');
}
return resolve(user);
}, 200);
});
}
//// Sockets auth implementation
socketAuth(io, {
authenticate: async (socket, data, callback) => {
const { token, i } = data;
console.log(data)
try {
const user = await verifyUser(token, i);
socket.user = user;
socket.i = i
console.log(i)
return callback(null, true);
} catch (e) {
console.log(`Socket ${socket.id} unauthorized.`);
return callback({ message: 'UNAUTHORIZED' });
}
},
postAuthenticate: async (socket) => {
console.log(`Socket ${socket.id} authenticated.`);
console.log(socket.user)
setUser(socket.id,socket.user, socket.i)
socket.emit('empty list', {queryList:true});
io.emit('admin connected', {admin:true});
socket.conn.on('packet', async (packet) => {
if (socket.auth && packet.type === 'ping') {
}
});
socket.on('chatmessage', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});
socket.on('hello', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});
socket.on('get tasks', (get) => {
let i = socket.i
let user = socket.user
getTasksChunk(get,i,user)
});
socket.on('admin userlist', (get) => {
let i = socket.i
let user = socket.user
adminGetUserList(get,i,user)
});
socket.on('admin roles', (data) => {
let i = socket.i
let user = socket.user
console.log(data)
console.log('reaced')
});
interval = setInterval(() => getApiAndEmit(socket), 1000);
},
disconnect: async (socket) => {
console.log(`Socket ${socket.id} disconnected.`);
if (socket.user) {
}
},
})
function getTasksChunk(get,i, user){
console.log(get,i,user);
let institution = i
db[institution].tasks24.find({}, async function (err, docs) {
if(docs.length){
for(i=0;i<docs.length;i++){
docs[i].location = `Ward: ${docs[i].location.Ward} Bed: ${docs[i].location.Bed}`
docs[i].patient = docs[i].patient.join(' | ')
docs[i].timestamp = prettyDate(new Date(+docs[i].timestamp))
}
console.log(docs)
let sorted = await sortArray(docs,'timestamp')
let chunk = sorted.slice(0,10)
io.emit('tasks in', chunk);
} else {
}
});
}
const getApiAndEmit = socket => {
const response = new Date();
// Emitting a new message. Will be consumed by the client
socket.emit("FromAPI", response);
};
///////ADMIN????????
function adminGetUserList(get,i,user){
var institution = i
console.log('hello')
db[institution].users.find({}, async function (err, docs) {
if(docs.length){
console.log(docs)
let sorted = await sortArray(docs,'timestamp')
io.emit('admin user list', sorted);
} else {
}
});
}
server.listen(process.env.PORT || 3001, () => console.log(`Server has started.`));
You must store your socket instance in a ref otherwise you would loose the connected socket instance when your component re-renders.
In short you need the socket reference to be the same across renders
const socketUrl = 'http://localhost:3001';
let socket = useRef(null);
useEffect(() => {
socket.current = io(socketUrl, {
autoConnect: false,
});
...
}, [socketUrl]);
Now note that whereever you are using socket you would use socket.current.
Ex:
socket,.current.on('hello', (msg) => {
io.emit('chatmessage', msg);
console.log(msg);
});