trying mqtt over tls connection with certificate and private key, but i can't build a connection - react-native

error:
Error: Unable to resolve module node:fs from C:\i_vec_Dashboard\src\screens\auth\LoginScreen.js: node:fs could not be found
within the project or in these directories:
22 | const tls = require('node:tls');
> 23 | const fs = require('node:fs');
| ^
Code:
const options = {
key: fs.readFileSync('private.key'),`your text`
cert: fs.readFileSync('certificate.crt'),
// Necessary only if the server uses a self-signed certificate.
ca: [fs.readFileSync('AmazonRootCA1.pem')],
// Necessary only if the server's cert isn't for "localhost".
checkServerIdentity: () => { return null; },
};
const socket = tls.connect(8883, options, () => {
console.log('client connected',
socket.authorized ? 'authorized' : 'unauthorized');
process.stdin.pipe(socket);
process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
console.log(data);
});
socket.on('end', () => {
console.log('server ends connection');
});
I am trying to do mqtt over a TCP connection with port 8883, certificate, and privatekey, but I am not aware of TCP and mqtt, but I would like to do a connection(secured) with the server for data receive from the server

Related

Error: self-signed certificate When connecting to google FCM with XMPP protocol

I am trying to connect to google Firebase Messaging with xmpp protocol with Node Js with node-xmpp-client
But I am getting an TLS error
Below is the code:
const XMPP = require("node-xmpp-client");
config = {
id: "push-notify-xmpp",
key: "________KEY______",
port: "5236",
host: "fcm-xmpp.googleapis.com",
};
client = new XMPP.Client({
jid: `${config.id}#fcm-xmpp.googleapis.com`,
password: config.key,
port: config.port,
host: config.host,
legacySSL: true,
preferredSaslMechanism: "PLAIN",
});
client.connection.socket.on("error", function (error) {
console.log("socket error");
console.error(error);
process.exit(1);
});
client.on("online", function (data) {
console.log(
"Connected as " +
data.jid.local +
"#" +
data.jid.domain +
"/" +
data.jid.resource
);
});
client.on("error", function (err) {
console.log("server error");
console.error(err);
process.exit(1);
});
Error:
server error
Error: self-signed certificate
at TLSSocket.onConnectSecure (node:_tls_wrap:1538:34)
at TLSSocket.emit (node:events:513:28)
at TLSSocket._finishInit (node:_tls_wrap:952:8)
at ssl.onhandshakedone (node:_tls_wrap:733:12) {
code: 'DEPTH_ZERO_SELF_SIGNED_CERT'
}
Also tried the command :
NODE_TLS_REJECT_UNAUTHORIZED='0' node appServer.js
But above get an different error Unauthorised
Can Anyone have any Idea ow to deal with FCM server with XMPP

Express JS Websocket Connection to wss failed without error but still able to communicate

I am using an Express JS to initiate websocket connection. Below is the following configuration that I used.
socket.js
const ip_address = `${process.env.MIX_HTTPS_APP_URL}`;
const socket_port = `${process.env.MIX_EXPRESS_PORT}`;
const URL = ip_address + ":" + socket_port;
export const socket = io(URL, { autoConnect: true });
socket.onAny((event, ...args) => {
// console.log(event, args);
});
index.js
const app = express();
// app settings
/** Create HTTP server. */
const privateKey = fs.readFileSync(env.privateKey, "utf8");
const certificate = fs.readFileSync(env.certificate, "utf8");
const options = {
key: privateKey,
cert: certificate,
};
const server = https.createServer(options, app).listen(port);
/** Create socket connection */
const socketio = new Server(server);
global.io = socketio.listen(server, {
cors: {
origin: env.url,
},
});
global.io.on("connection", WebSockets.connection);
/** Listen on provided port, on all network interfaces. */
/** Event listener for HTTP server "listening" event. */
server.on("listening", () => {
console.log(`Listening on port:: ${env.url}:${port}/`);
});
Though I can emit and listen to socket, I am still getting this error message. How should I solve this so that users wont see this error message when they view the console?
With reference to your example, the listening on port should be on http server, & socket.io should just attach to on new conn.
see doc https://socket.io/docs/v4/server-initialization/#with-an-https-server
Hope this helps.

protractor node-libcurl Failed: SSL peer certificate or SSH remote key was not OK

I am trying to use node-libcurl module in my protractor project but I am getting the error :
Failed: SSL peer certificate or SSH remote key was not OK
const {curly} = require('node-libcurl')
const { data } = await curly.post('https://www.example.com', {
postFields: JSON.stringify({"name":"rak"}),
httpHeader: [
'Content-Type: application/json',
'Accept: application/json',
'Access-Control-Allow-Origin : *'
],
})
How to get rid of this error .
From the COMMON_ISSUES.md file on the project's repository:
You need to set either CAINFO or CAPATH options, or disable SSL
verification with SSL_VERIFYPEER (not recommended).
The certificate file can be obtained in multiple ways:
Extracted directly from your system/browser
Downloaded from https://curl.haxx.se/docs/caextract.html, which is based on the one
from Firefox
Creating a file with the contents of tls.rootCertificates, which was added with Node.js v12.3.0, example:
const fs = require('fs')
const path = require('path')
const tls = require('tls')
const { curly } = require('node-libcurl')
// important steps
const certFilePath = path.join(__dirname, 'cert.pem')
const tlsData = tls.rootCertificates.join('\n')
fs.writeFileSync(certFilePath, tlsData)
async function run() {
return curly.post('https://httpbin.org/anything', {
postFields: JSON.stringify({ a: 'b' }),
httpHeader: ['Content-type: application/json'],
caInfo: certFilePath,
verbose: true,
})
}
run()
.then(({ data, statusCode, headers }) =>
console.log(
require('util').inspect(
{
data: JSON.parse(data),
statusCode,
headers,
},
null,
4,
),
),
)
.catch((error) => console.error(`Something went wrong`, { error }))

how to get socketid in socket.io(nodejs)

In my nodejs application, i am using socket.io for sockets connection.
I am configuring my server side code like this
socket.io configuration in separate file.
//socket_io.js
var socket_io = require('socket.io');
var io = socket_io();
var socketApi = {};
socketApi.io = io;
module.exports = socketApi;
below is my server.js file in which i am attaching my socket io to the server like this
var socketApi = require('./server/socket_io');
// Create HTTP server.
const server = http.createServer(app);
// Attach Socket IO
var io = socketApi.io;
io.attach(server);
// Listen on provided port, on all network interfaces.
server.listen(port, () => console.log(`API running on localhost:${port}`));
and then i am using socket.io in my game.js file to emit updated user coins like this.
//game.js
var socketIO = require('../socket_io');
function updateUserCoins(userBet) {
userId = mongoose.Types.ObjectId(userBet.user);
User.findUserWithId(userId).then((user) => {
user.coins = user.coins - userBet.betAmount;
user.save((err, updatedUser) => {
socketIO.io.sockets.emit('user coins', {
userCoins: updatedUser.coins,
});
});
})
}
and then in my client side, i am doing something like this,
socket.on('user coins', (data) => {
this.coins = data.userCoins;
});
but with the above implementation, updating coins of any user, updates all user coins at the client side, since all the clients are listening to the same socket user coins.
To solve the above problem, i know that i have to do something like this,
// sending to individual socketid (private message)
socketIO.io.sockets.to(<socketid>).emit('user coins', {
userCoins: updatedUser.coins,
});
but my concern is that how will get <socketid> with my current implementation.
You can get it by listening to connection to your socket.io server :
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Here you have a socket object ( io.on('connection', function (socket) ) and you can get his id with socket.id
So you'll probably need to wrap your code with the connection listener.
Source of the exemple for the connection listener
Socket object description

node.js, socket.io with SSL

I'm trying to get socket.io running with my SSL certificate however, it will not connect.
I based my code off the chat example:
var https = require('https');
var fs = require('fs');
/**
* Bootstrap app.
*/
var sys = require('sys')
require.paths.unshift(__dirname + '/../../lib/');
/**
* Module dependencies.
*/
var express = require('express')
, stylus = require('stylus')
, nib = require('nib')
, sio = require('socket.io');
/**
* App.
*/
var privateKey = fs.readFileSync('../key').toString();
var certificate = fs.readFileSync('../crt').toString();
var ca = fs.readFileSync('../intermediate.crt').toString();
var app = express.createServer({key:privateKey,cert:certificate,ca:ca });
/**
* App configuration.
*/
...
/**
* App routes.
*/
app.get('/', function (req, res) {
res.render('index', { layout: false });
});
/**
* App listen.
*/
app.listen(443, function () {
var addr = app.address();
console.log(' app listening on http://' + addr.address + ':' + addr.port);
});
/**
* Socket.IO server (single process only)
*/
var io = sio.listen(app,{key:privateKey,cert:certificate,ca:ca});
...
If I remove the SSL code it runs fine, however with it I get a request to http://domain.example/socket.io/1/?t=1309967919512
Note it's not trying HTTPS, which causes it to fail.
I'm testing on chrome, since it is the target browser for this application.
I apologize if this is a simple question, I'm a node/socket.io newbie.
Use a secure URL for your initial connection, i.e. instead of "http://" use "https://". If the WebSocket transport is chosen, then Socket.IO should automatically use "wss://" (SSL) for the WebSocket connection too.
Update:
You can also try creating the connection using the 'secure' option:
var socket = io.connect('https://localhost', {secure: true});
The following is how I set up to set it up with express:
var app = require('express')();
var https = require('https');
var fs = require( 'fs' );
var io = require('socket.io')(server);
var options = {
key: fs.readFileSync('./test_key.key'),
cert: fs.readFileSync('./test_cert.crt'),
ca: fs.readFileSync('./test_ca.crt'),
requestCert: false,
rejectUnauthorized: false
}
var server = https.createServer(options, app);
server.listen(8080);
io.sockets.on('connection', function (socket) {
// code goes here...
});
app.get("/", function(request, response){
// code goes here...
})
Update : for those using lets encrypt use this
var server = https.createServer({
key: fs.readFileSync('privkey.pem'),
cert: fs.readFileSync('fullchain.pem')
}, app);
On the same note, if your server supports both http and https you can connect using:
var socket = io.connect('//localhost');
to auto detect the browser scheme and connect using http/https accordingly. when in https, the transport will be secured by default, as connecting using
var socket = io.connect('https://localhost');
will use secure web sockets - wss:// (the {secure: true} is redundant).
for more information on how to serve both http and https easily using the same node server check out this answer.
If your server certificated file is not trusted, (for example, you may generate the keystore by yourself with keytool command in java), you should add the extra option rejectUnauthorized
var socket = io.connect('https://localhost', {rejectUnauthorized: false});
Depending on your needs, you could allow both secure and unsecure connections and still only use one Socket.io instance.
You simply have to instanciate two servers, one for HTTP and one for HTTPS, then attach those servers to the Socket.io instance.
Server side :
// needed to read certificates from disk
const fs = require( "fs" );
// Servers with and without SSL
const http = require( "http" )
const https = require( "https" );
const httpPort = 3333;
const httpsPort = 3334;
const httpServer = http.createServer();
const httpsServer = https.createServer({
"key" : fs.readFileSync( "yourcert.key" ),
"cert": fs.readFileSync( "yourcert.crt" ),
"ca" : fs.readFileSync( "yourca.crt" )
});
httpServer.listen( httpPort, function() {
console.log( `Listening HTTP on ${httpPort}` );
});
httpsServer.listen( httpsPort, function() {
console.log( `Listening HTTPS on ${httpsPort}` );
});
// Socket.io
const ioServer = require( "socket.io" );
const io = new ioServer();
io.attach( httpServer );
io.attach( httpsServer );
io.on( "connection", function( socket ) {
console.log( "user connected" );
// ... your code
});
Client side :
var url = "//example.com:" + ( window.location.protocol == "https:" ? "3334" : "3333" );
var socket = io( url, {
// set to false only if you use self-signed certificate !
"rejectUnauthorized": true
});
socket.on( "connect", function( e ) {
console.log( "connect", e );
});
If your NodeJS server is different from your Web server, you will maybe need to set some CORS headers. So in the server side, replace:
const httpServer = http.createServer();
const httpsServer = https.createServer({
"key" : fs.readFileSync( "yourcert.key" ),
"cert": fs.readFileSync( "yourcert.crt" ),
"ca" : fs.readFileSync( "yourca.crt" )
});
With:
const CORS_fn = (req, res) => {
res.setHeader( "Access-Control-Allow-Origin" , "*" );
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader( "Access-Control-Allow-Methods" , "*" );
res.setHeader( "Access-Control-Allow-Headers" , "*" );
if ( req.method === "OPTIONS" ) {
res.writeHead(200);
res.end();
return;
}
};
const httpServer = http.createServer( CORS_fn );
const httpsServer = https.createServer({
"key" : fs.readFileSync( "yourcert.key" ),
"cert": fs.readFileSync( "yourcert.crt" ),
"ca" : fs.readFileSync( "yourca.crt" )
}, CORS_fn );
And of course add/remove headers and set the values of the headers according to your needs.
check this.configuration..
app = module.exports = express();
var httpsOptions = { key: fs.readFileSync('certificates/server.key'), cert: fs.readFileSync('certificates/final.crt') };
var secureServer = require('https').createServer(httpsOptions, app);
io = module.exports = require('socket.io').listen(secureServer,{pingTimeout: 7000, pingInterval: 10000});
io.set("transports", ["xhr-polling","websocket","polling", "htmlfile"]);
secureServer.listen(3000);
Server-side:
import http from 'http';
import https from 'https';
import SocketIO, { Socket } from 'socket.io';
import fs from 'fs';
import path from 'path';
import { logger } from '../../utils';
const port: number = 3001;
const server: https.Server = https.createServer(
{
cert: fs.readFileSync(path.resolve(__dirname, '../../../ssl/cert.pem')),
key: fs.readFileSync(path.resolve(__dirname, '../../../ssl/key.pem'))
},
(req: http.IncomingMessage, res: http.ServerResponse) => {
logger.info(`request.url: ${req.url}`);
let filePath = '.' + req.url;
if (filePath === './') {
filePath = path.resolve(__dirname, './index.html');
}
const extname = String(path.extname(filePath)).toLowerCase();
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.json': 'application/json'
};
const contentType = mimeTypes[extname] || 'application/octet-stream';
fs.readFile(filePath, (error: NodeJS.ErrnoException, content: Buffer) => {
if (error) {
res.writeHead(500);
return res.end(error.message);
}
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
});
}
);
const io: SocketIO.Server = SocketIO(server);
io.on('connection', (socket: Socket) => {
socket.emit('news', { hello: 'world' });
socket.on('updateTemplate', data => {
logger.info(data);
socket.emit('updateTemplate', { random: data });
});
});
server.listen(port, () => {
logger.info(`Https server is listening on https://localhost:${port}`);
});
Client-side:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Websocket Secure Connection</title>
</head>
<body>
<div>
<button id='btn'>Send Message</button>
<ul id='messages'></ul>
</div>
<script src='../../../node_modules/socket.io-client/dist/socket.io.js'></script>
<script>
window.onload = function onload() {
const socket = io('https://localhost:3001');
socket.on('news', function (data) {
console.log(data);
});
socket.on('updateTemplate', function onUpdateTemplate(data) {
console.log(data)
createMessage(JSON.stringify(data));
});
const $btn = document.getElementById('btn');
const $messages = document.getElementById('messages');
function sendMessage() {
socket.emit('updateTemplate', Math.random());
}
function createMessage(msg) {
const $li = document.createElement('li');
$li.textContent = msg;
$messages.appendChild($li);
}
$btn.addEventListener('click', sendMessage);
}
</script>
</body>
</html>
For enterprise applications it should be noted that you should not be handling https in your code. It should be auto upgraded via IIS or nginx. The app shouldn't know about what protocols are used.
In case someone need a shorter form
var fs = require('fs');
var https = require('https');
var express = require('express');
var app = express();
var options = {
key: fs.readFileSync('/path-to/ssl.key'),
cert: fs.readFileSync('/path-to/ssl.cert')
};
var server = https.createServer(options, app);
var io = require('socket.io')(server);
This is my nginx config file and iosocket code. Server(express) is listening on port 9191. It works well:
nginx config file:
server {
listen 443 ssl;
server_name localhost;
root /usr/share/nginx/html/rdist;
location /user/ {
proxy_pass http://localhost:9191;
}
location /api/ {
proxy_pass http://localhost:9191;
}
location /auth/ {
proxy_pass http://localhost:9191;
}
location / {
index index.html index.htm;
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
}
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:9191/socket.io/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
ssl_certificate /etc/nginx/conf.d/sslcert/xxx.pem;
ssl_certificate_key /etc/nginx/conf.d/sslcert/xxx.key;
}
Server:
const server = require('http').Server(app)
const io = require('socket.io')(server)
io.on('connection', (socket) => {
handleUserConnect(socket)
socket.on("disconnect", () => {
handleUserDisConnect(socket)
});
})
server.listen(9191, function () {
console.log('Server listening on port 9191')
})
Client(react):
const socket = io.connect('', { secure: true, query: `userId=${this.props.user._id}` })
socket.on('notifications', data => {
console.log('Get messages from back end:', data)
this.props.mergeNotifications(data)
})
I needed to get this to work with Debian 10, ISPConfig 3 and Let's Encrypt. Took me a while to work out the specifics. Maybe this saves someone else some timeā€¦
Server-side:
const fs = require('fs');
const https = require('https');
const express = require('express');
const socketio = require('socket.io');
const app = express();
const https_options = {
key: fs.readFileSync('/var/www/clients/client1/web1/ssl/your-domain.com-le.key'),
cert: fs.readFileSync('/var/www/clients/client1/web1/ssl/your-domain.com-le.crt'),
ca: fs.readFileSync('/root/.acme.sh/your-domain.example/fullchain.cer'),
requestCert: false,
rejectUnauthorized: false
}
const server = https.createServer(https_options, app);
server.listen(3000, () => {
console.log('server started ok');
});
const io = socketio(server, {
cors: {
origin: "https://your-domain.example",
},
secure: true
});
io.on('connection', (sock) => {
console.log('someone connected');
}
Client-side:
const sock = io('https://your-domain.example:3000/');
sock.on('status', (text) => {
add_text($('#status'), text);
});
Server side:
var ssl_options = {
ca: [fs.readFileSync('../ssl/cert1.crt'), fs.readFileSync('../ssl/cert2.crt'), fs.readFileSync('../ssl/cert3.crt')],
key: fs.readFileSync('../ssl/xxx.key'),
cert: fs.readFileSync('../ssl/xxx.example.crt'),
};
var wssServer = https.createServer(ssl_options,app); // Express app
wssServer.listen(4433, '0.0.0.0');
global.io = require("socket.io")();
io.listen(wssServer);
io.on( "connection", function( socket ) {
console.log( "user connected" );
});
Client-side (no luck with the built-in WebSocket API):
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.js"></script>
<script>
const socket = io("https://xxx.example:4433",{ transports: ['websocket', 'polling', 'flashsocket'] });
</script>