Socket hangup when using TLS in Hapi server - node.js

Whenever the server starts, I see the following console error message:
Server started at: https://localhost:3333
170929/232536.579, [log,connection,client,error] message: socket hang up, stack: Error: socket hang up
at TLSSocket.<anonymous> (_tls_wrap.js:829:25)
at emitOne (events.js:95:20)
at TLSSocket.emit (events.js:182:7)
at Socket.<anonymous> (net.js:484:12)
at Socket.g (events.js:273:16)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at TCP._onclose (net.js:484:12)
I was able to determine that if I removed the tls option from the server.connection, the error disappears.
This is the code in the server
import Hapi from 'hapi';
import inert from 'inert';
import fs from 'fs';
import { apiRoutes } from './api/api-routes';
import { serverConfig } from 'common';
import _ from 'lodash';
const good = require('good');
const server = new Hapi.Server();
const tls = {
key: fs.readFileSync('cert/server-key.pem'),
cert: fs.readFileSync('cert/server-crt.pem'),
ca: fs.readFileSync('cert/ca-crt.pem'),
};
const host = serverConfig.host;
const port = serverConfig.port;
server.connection({
address: '0.0.0.0', // listen on all interfaces!
host,
port,
tls,
});
const options = {
reporters: {
myConsoleReporter: [{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ log: '*', response: '*' }],
}, {
module: 'good-console',
}, 'stdout'],
myFileReporter: [{
module: 'good-squeeze',
name: 'Squeeze',
args: [{ ops: '*' }],
}, {
module: 'good-squeeze',
name: 'SafeJson',
}, {
module: 'good-file',
args: ['./hapi.log'],
}],
},
};
server.register([
{
register: inert,
},
{
register: good,
options,
},
],
(err) => {
if (err) {
throw
// define static ui
server.route({
method: 'GET',
path: '/{path*}',
handler: {
directory: {
path: serverConfig.staticAssetsDir,
},
},
});
// start server
server.start(() => {
console.log(`Server started at: ${server.info.uri}`);
});
}
);
What could be the issue, and how could I get started debugging this?

Related

MongoServerError: BSON field 'insert.jsonSchema' is an unknown field

I am new in MongoDB. I want to do client side field level encryption.
Here is the full project link which one I am practicing:
https://javascript.plainenglish.io/mongodb-client-side-field-level-encryption-csfle-for-beginners-5eed965d4ba3
Requirments: What I have Installed.
MongoDB Enterprise server 6.0,
npm i mongodb-client-encryption uuid-base64 mongodb
I am getting this error when running node app.js
app.js
const fs = require("fs");
const mongodb = require("mongodb");
const { MongoClient, Binary } = mongodb;
const base64KeyId = "fFGm1x/fRIWlWPLWhvf1Ig==";
const buffer = Buffer.from(base64KeyId, "base64");
const keyIdBinary = new Binary(buffer, Binary.SUBTYPE_UUID);
const JSONSchemaCreator = require("./schema-creator");
const jsonSchemas = JSONSchemaCreator(keyIdBinary);
const connectionString = "mongodb://localhost:27017/";
const keyVaultNamespace = "encryption.__keyVault";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
const patientSchema = {
"medicalRecords.patients": jsonSchemas,
};
const extraOptions = {
mongocryptdURI: "mongodb://localhost:27020",
};
const secureClient = new MongoClient(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap: patientSchema,
extraOptions: extraOptions,
},
});
async function insertPatient(name, bloodType, ssn) {
try {
await secureClient.connect();
const keyDB = secureClient.db("medicalRecords");
const collection = keyDB.collection("patients");
const writeResult = await collection.insertOne({
name,
ssn,
bloodType,
});
console.log(writeResult);
} catch (writeError) {
console.error("writeError occurred:", writeError);
}
}
insertPatient(
'Jon Doe',
"O+",
'1234567',
);
all of my server connection is perfect.
**
error:**
writeError occurred: MongoServerError: BSON field 'insert.jsonSchema' is an unknown field. This command may be meant for a mongocryptd process.
at Connection.onMessage (/home/shahed/Documents/encryptionDemo/node_modules/mongodb/lib/cmap/connection.js:230:30)
at MessageStream.<anonymous> (/home/shahed/Documents/encryptionDemo/node_modules/mongodb/lib/cmap/connection.js:61:60)
at MessageStream.emit (node:events:513:28)
at processIncomingData (/home/shahed/Documents/encryptionDemo/node_modules/mongodb/lib/cmap/message_stream.js:125:16)
at MessageStream._write (/home/shahed/Documents/encryptionDemo/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
at writeOrBuffer (node:internal/streams/writable:392:12)
at _write (node:internal/streams/writable:333:10)
at Writable.write (node:internal/streams/writable:337:10)
at Socket.ondata (node:internal/streams/readable:766:22)
at Socket.emit (node:events:513:28) {
ok: new Double(0.0),
code: new Int32(4662500),
codeName: 'Location4662500',
[Symbol(errorLabels)]: Set(0) {}
}
Please help me out and thanks in advance
I have a jsonschema format which one need create and perform encryption push into db
schema-creator.js
module.exports = function (keyId) {
return {
bsonType: "object",
encryptMetadata: {
keyId,
},
properties: {
bloodType: {
encrypt: {
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
ssn: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
};
};

electron-updater yields ERR_SSL_CLIENT_AUTH_CERT_NEEDED

Electron-Builder Version: 23.0.3
Node Version: v14.13.1
Electron Version: 18.2.3
Electron Type (current, beta, nightly): current
Target: nsis win x64
Hello, I'm trying do to a simple PoC on how we can update our electron app and I stumbled across this issue:
Error: Error: net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169) at SimpleURLLoaderWrapper.emit (node:events:390:28) 11:18:44.437 > Error: net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169) at SimpleURLLoaderWrapper.emit (node:events:390:28) 11:18:44.439 > Error: Error: net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169) at SimpleURLLoaderWrapper.emit (node:events:390:28) status: 'error', error: 'Error: net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED\n' + ' at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169)\n' + ' at SimpleURLLoaderWrapper.emit (node:events:390:28)' } (node:13428) UnhandledPromiseRejectionWarning: Error: net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:101:7169) at SimpleURLLoaderWrapper.emit (node:events:390:28)
My build config looks like this:
"build": { "appId": "myapptestid", "files": [ "app/**/*", "node_modules/**/*", "package.json" ], "publish": [ { "provider": "generic", "url": "my_artifactory_url" } ], "directories": { "buildResources": "resources" }, "win": { "target": "nsis" }, "nsis": { "oneClick": false } },
And my main looks like this:
import url from "url";
import { app, Menu, ipcMain, shell } from "electron";
import appMenuTemplate from "./menu/app_menu_template";
import editMenuTemplate from "./menu/edit_menu_template";
import devMenuTemplate from "./menu/dev_menu_template";
import createWindow from "./helpers/window";
const isDev = require("electron-is-dev");
const log = require("electron-log");
log.transports.file.resolvePath = () => path.join("./logs.log");
import env from "env";
import { NsisUpdater } from "electron-updater";
const options = {
provider: "generic",
url: "my_artifactory_url",
};
const autoUpdater = new NsisUpdater(options);
autoUpdater.logger = require("electron-log");
autoUpdater.logger.transports.file.level = "info";
autoUpdater.addAuthHeader(Basic ${base64PlainData});
autoUpdater.on("error", (error) => {
log.info(error);
log.info(
"Error: ",
error == null ? "unknown" : (error.stack || error).toString()
);
});
autoUpdater.on("checking-for-update", () => {
log.info({ status: "checking" });
});
autoUpdater.on("update-available", () => {
log.info({ status: "update-available" });
});
autoUpdater.on("update-not-available", () => {
log.info({ status: "current" });
});
autoUpdater.on("error", (err) => {
log.info({ status: "error", error: err });
});
autoUpdater.on("download-progress", (progressObj) => {
log.info(progressObj);
log.info({
status: "downloading",
download: {
bytesPerSecond: progressObj.bytesPerSecond,
percent: progressObj.percent,
transferred: progressObj.transferred,
total: progressObj.total,
},
});
});
autoUpdater.on("update-downloaded", () => {
log.info({ status: "completed" });
});
if (env.name !== "production") {
const userDataPath = app.getPath("userData");
app.setPath("userData", ${userDataPath} (${env.name}));
}
const setApplicationMenu = () => {
const menus = [appMenuTemplate, editMenuTemplate];
if (env.name !== "production") {
menus.push(devMenuTemplate);
}
Menu.setApplicationMenu(Menu.buildFromTemplate(menus));
};
const initIpc = () => {
ipcMain.on("need-app-path", (event, arg) => {
event.reply("app-path", app.getAppPath());
});
ipcMain.on("open-external-link", (event, href) => {
shell.openExternal(href);
});
};
app.on("ready", () => {
setApplicationMenu();
initIpc();
const mainWindow = createWindow("main", {
width: 1000,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: env.name === "test",
},
});
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, "app.html"),
protocol: "file:",
slashes: true,
})
);
// if (env.name === "development") {
mainWindow.openDevTools();
// }
if (isDev) {
log.info("dev");
autoUpdater.checkForUpdates();
} else {
log.info("prod");
autoUpdater.checkForUpdatesAndNotify();
}
setInterval(() => {
autoUpdater.checkForUpdatesAndNotify();
}, 1000 * 60 * 15);
});
app.on("window-all-closed", () => {
app.quit();
});
I'm trying to update through a generic repo from Jfrog Artifactory and that's why I need to use Auth header.
I've also tried to hook up to "select-client-certificate" and "certificate-error" from app, but none of this are triggered.
I'm doing the exactly same request in Postman and it works, no matter if the "SSL certificate verification" is on or off.
Can someone please give me a hint on this?

Node IMAP ECONNRESET with Mail-in-a-box email

When I create an IMAP connection with node-imap module with a Mail-in-a-box (MIAB) email, after a few minutes, I get the ECONNRESET error. I want to know if it is a fault in the connection configuration, or is it from MIAB server side that will disconnect the connection if it has been idle for too long.
Here is my IMAP connection configuration:
{
port: 993,
tls: true,
authTimeout: 30000,
connTimeout: 30000,
keepalive: {
forceNoop: true,
},
tlsOptions: {
rejectUnauthorized: false,
},
}
And this is the error I got:
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read',
source: 'socket'
}
I am using the mail-notifier module, which is a wrapper of node-imap module. This is the code where I register for events in the IMAP connection
const notifier = Notifier(imap);
notifier
.on("end", () => notifier.start())
.on("connected", () => {
console.log(`Connected IMAP: ${user}`);
})
.on("mail", (mail) => {
this.onMail(mail, user);
})
.on("error", (e: any) => {
console.log(`IMAP error: ${user}, time: ${Date.now()}`);
console.log(e);
setTimeout(() => {
notifier.stop();
notifier.start();
}, 5000);
})
.start();

Node error connect ETIMEDOUT at TCPConnectWrap

I started having this problem whenever I run "yarn run dev:server" and my application doesn't start. Does anyone know how to solve it?
A important OBS: The application is running on Docker with redis and peerjs
The full error:
Error: connect ETIMEDOUT 13.49.22.0:443
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1129:16)
[ERROR] 15:27:24 Error: connect ETIMEDOUT 13.49.22.0:443
When I run in production mode (yarn start)
Error: connect ETIMEDOUT 13.49.22.0:443
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1129:16) {
errno: -4039,
code: 'ETIMEDOUT',
syscall: 'connect',
address: '13.49.22.0',
port: 443,
type: 'FETCH',
sourceUrl: 'https://api.nodemailer.com/user'
I have the file .env:
# App settings
APP_API_URL=http://localhost:3333
APP_WEB_URL=http://localhost:3000
APP_ADMIN_URL=http://localhost:3001
APP_SECRET=admin
APP_DEFAULT_PAGE_LIMIT=50
PORT=3333
STORAGE_DRIVER=disk
MAIL_DRIVER=ethereal
I try configure with mailjet, but show the same error.
MailjetProvider.ts, where I belive the Mailjet is configured:
#injectable()
export default class MailjetMailProvider implements IMailProvider {
private client: Transporter;
constructor(
#inject('MailTemplateProvider')
private mailTemplateProvider: IMailTemplateProvider,
) {
this.client = nodemailer.createTransport({
host: mailConfig.mailjet.host,
port: mailConfig.mailjet.port,
secure: false,
auth: mailConfig.mailjet.auth,
});
}
public async sendMail({
to,
from,
subject,
templateData,
}: ISendMailDTO): Promise<void> {
const { name, email } = mailConfig.defaults.from;
await this.client.sendMail({
from: {
name: from?.name || name,
address: from?.email || email,
},
to: {
name: to.name,
address: to.email,
},
subject,
html: await this.mailTemplateProvider.parse(templateData),
});
}
}
mail.ts:
interface IMailConfig {
driver: 'ethereal' | 'ses';
mailjet: {
host: string;
port: number;
auth: {
user: string;
pass: string;
};
};
defaults: {
from: {
email: string;
name: string;
};
};
}
export default {
driver: process.env.MAIL_DRIVER || 'ethereal',
mailjet: {
host: process.env.MAILJET_HOST || '',
port: Number(process.env.MAILJET_PORT) || 587,
auth: {
user: process.env.MAILJET_USER || '',
pass: process.env.MAILJET_PASS || '',
},
},
defaults: {
from: {
email: process.env.MAIL_FROM,
name: process.env.MAIL_FROM_NAME,
},
},
} as IMailConfig;
EtherealMailProvider.ts, where Ethereal is config.
#injectable()
export default class EtherealMailProvider implements IMailProvider {
private client: Transporter;
constructor(
#inject('MailTemplateProvider')
private mailTemplateProvider: IMailTemplateProvider,
) {
nodemailer.createTestAccount().then(account => {
const transporter = nodemailer.createTransport({
host: account.smtp.host,
port: account.smtp.port,
secure: account.smtp.secure,
auth: {
user: account.user,
pass: account.pass,
},
});
this.client = transporter;
});
}
public async sendMail({
to,
from,
subject,
templateData,
}: ISendMailDTO): Promise<void> {
const { name, email } = mailConfig.defaults.from;
const message = await this.client.sendMail({
from: {
name: from?.name || name,
address: from?.email || email,
},
to: {
name: to.name,
address: to.email,
},
subject,
html: await this.mailTemplateProvider.parse(templateData),
});=
}

Truffle solidity loader Not working with Truffle 3.2.1

I was using truffle-webpack-demo but started getting errors since I upgraded to truffle 3.2.1. I found the new branch of the same repo and copied config from there. Which should be working, but now npm start gives me the following error.
Starting the development server...
Failed to compile.
Error in ./contracts/MetaCoin.sol
Module build failed: Error: You must specify the network name to deploy to. (network)
# ./src/components/AccountList/AccountListContainer.js 37:16-49
I have upgraded to the following versions of truffle, webpack-dev-server, webpack and truffle-solidity-loader
truffle-solidity-loader: "git+https://github.com/sogoiii/truffle-solidity-loader.git#1f1e213d52f033b6863218307b8968ae68220fe1"
truffle: 3.2.1
webpack-dev-server: 2.4.1
webpack: 2.2.1
Below is my config/webpack.config.dev.js
var path = require('path')
var autoprefixer = require('autoprefixer')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var precss = require('precss')
// TODO: hide this behind a flag and eliminate dead code on eject.
// This shouldn't be exposed to the user.
var isInNodeModules = path.basename(path.resolve(path.join(__dirname, '..', '..'))) === 'node_modules'
var relativePath = isInNodeModules ? '../../..' : '..'
var isInDebugMode = process.argv.some(arg =>
arg.indexOf('--debug-template') > -1
)
if (isInDebugMode) {
relativePath = '../template'
}
var srcPath = path.resolve(__dirname, relativePath, 'src')
var nodeModulesPath = path.join(__dirname, '..', 'node_modules')
var indexHtmlPath = path.resolve(__dirname, relativePath, 'index.html')
var faviconPath = path.resolve(__dirname, relativePath, 'favicon.ico')
var buildPath = path.join(__dirname, isInNodeModules ? '../../..' : '..', 'build')
var provided = {
'Web3': 'web3'
}
module.exports = {
devtool: 'eval',
entry: [
require.resolve('webpack-dev-server/client') + '?http://localhost:3000',
require.resolve('webpack/hot/dev-server'),
path.join(srcPath, 'index')
],
output: {
// Next line is not used in dev but WebpackDevServer crashes without it:
path: buildPath,
pathinfo: true,
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
root: srcPath,
extensions: ['', '.js'],
alias: {
contracts: path.resolve('contracts'),
// config: require('../truffle').networks.development,
config: path.resolve('truffle.js')
}
},
module: {
preLoaders: [
{
test: /\.js$/,
loader: 'eslint',
include: srcPath
}
],
loaders: [
{
test: /\.js$/,
include: srcPath,
loader: 'babel',
query: require('./babel.dev')
},
{
test: /\.css$/,
include: srcPath,
loader: 'style!css!postcss'
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)$/,
loader: 'file'
},
{
test: /\.(mp4|webm)$/,
loader: 'url?limit=10000'
},
{
test: /\.sol/,
loader: 'truffle-solidity',
loaders: ['json-loader', 'truffle-solidity-loader?migrations_directory=' + path.resolve(__dirname, '../migrations') + '&network=development&contracts_build_directory=' + path.resolve(__dirname, '../dist/contracts')]
}
]
},
eslint: {
configFile: path.join(__dirname, 'eslint.js'),
useEslintrc: false
},
postcss: function () {
return [precss, autoprefixer]
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: indexHtmlPath,
favicon: faviconPath
}),
new webpack.ProvidePlugin(provided),
new webpack.DefinePlugin({
'myEnv': JSON.stringify(require('../truffle').networks.development),
'process.env.NODE_ENV': '"development"'
}),
new webpack.EnvironmentPlugin(['NODE_ENV']),
new webpack.HotModuleReplacementPlugin()
]
}
Here's my MetaCoin.sol
pragma solidity ^0.4.4;
import "./ConvertLib.sol";
// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!
contract MetaCoin {
mapping (address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
function MetaCoin() {
balances[tx.origin] = 6000000000;
}
function sendCoin(address receiver, uint amount) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Transfer(msg.sender, receiver, amount);
return true;
}
function getBalanceInEth(address addr) returns(uint){
return convert(getBalance(addr),2);
}
function getBalance(address addr) returns(uint) {
return balances[addr];
}
function convert(uint amount,uint conversionRate) returns (uint convertedAmount)
{
return amount * conversionRate;
}
}
Here's my AccountListContainer.js
import React, { Component } from 'react'
import AccountList from 'components/AccountList/AccountList'
import SendCoin from 'components/SendCoin/SendCoin'
import Contract from 'truffle-contract'
import MetaCoinArtifact from 'contracts/MetaCoin.sol';
const MetaCoin = Contract(MetaCoinArtifact)
import Web3 from 'web3';
const provider = new Web3.providers.HttpProvider('http://localhost:8545')
MetaCoin.setProvider(provider);
class AccountListContainer extends Component {
constructor(props) {
super(props)
this.state = {
accounts: [],
coinbase: ''
}
this._getAccountBalance = this._getAccountBalance.bind(this)
this._getAccountBalances = this._getAccountBalances.bind(this)
}
_getAccountBalance (account) {
return MetaCoin.deployed()
.then(meta => {
return meta.getBalance.call(account, {from: account})
})
.then(function (value) {
return { account: value.valueOf() }
})
.catch(function (e) {
console.log(e)
throw e
})
}
_getAccountBalances () {
this.props.web3.eth.getAccounts(function (err, accs) {
if (err != null) {
window.alert('There was an error fetching your accounts.')
console.error(err)
return
}
if (accs.length === 0) {
window.alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.")
return
}
this.setState({coinbase: accs[0]})
var accountsAndBalances = accs.map((account) => {
return this._getAccountBalance(account).then((balance) => { return { account, balance } })
})
Promise.all(accountsAndBalances).then((accountsAndBalances) => {
this.setState({accounts: accountsAndBalances, coinbaseAccount: accountsAndBalances[0]})
})
}.bind(this))
}
componentDidMount() {
const refreshBalances = () => {
this._getAccountBalances()
}
refreshBalances()
setInterval(()=>{
refreshBalances();
return refreshBalances
}, 5000)
}
render() {
return (
<div>
<AccountList accounts={this.state.accounts} />
<SendCoin sender={this.state.coinbase} />
</div>
)
}
}
export default AccountListContainer
Here's the truffle.js
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
},
staging: {
host: "localhost",
port: 8546,
network_id: 1337
}
}
};
Given the error Module build failed: Error: You must specify the network name to deploy to. (network), I suspect your truffle.js file has not been updated to the new truffle 3 spec.
Review how the config changed at the migration guided. It should look something like.
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
},
staging: {
host: "localhost",
port: 8546,
network_id: 1337
},
ropsten: {
host: "158.253.8.12",
port: 8545,
network_id: 3
}
}
};

Resources