How to disable ssl3 that used by express + mongodb - node.js

I have a troubles with express.js it's trying to use ssl3 but I didn't use it anywhere. I see next error then running the server:
(node:7920) [DEP0026] DeprecationWarning: util.print is deprecated.
Use console.log instead. Error: 4776:error:1408F10B:SSL
routines:ssl3_get_record:wrong version
number:openssl\ssl\record\ssl3_record.c:252:
The server.js file looks like this:
// import npm modules
import fs from 'fs';
import path from 'path';
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import winston from 'winston';
import compression from 'compression';
import expressWinston from 'express-winston';
import winstonPapertrail from 'winston-papertrail';
import jwt from 'express-jwt';
import http from 'http';
// import custom configuration and utilities
import config from './config';
import logger from './utils/logger';
import db from './utils/db';
import routes from './routes';
// initialize the api
const api = express();
// initialize middleware
api.use(cors());
api.use(compression());
api.use(bodyParser.urlencoded({ extended: true }));
api.use(bodyParser.json());
// ignore authentication on the following routes
api.use(
jwt({ secret: config.jwt.secret }).unless({
path: [
'/',
'/auth/signup',
'/auth/login',
'/auth/forgot-password',
'/auth/reset-password',
],
}),
);
// throw an error if a jwt is not passed in the request
api.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
res.status(401).send('Missing authentication credentials.');
}
});
// initialize our logger (in our case, winston + papertrail)
api.use(
expressWinston.logger({
transports: [
new winston.transports.Papertrail({
host: config.logger.host,
port: config.logger.port,
level: 'error',
}),
],
meta: true,
}),
);
// listen on the designated port found in the configuration
api.listen(config.server.port, err => {
if (err) {
logger.error(err);
process.exit(1);
}
// require the database library (which instantiates a connection to mongodb)
db();
// loop through all routes and dynamically require them – passing api
Object.entries(routes).forEach(([ key, route ]) => {
route(api);
});
// output the status of the api in the terminal
logger.info(`API is now running on port ${config.server.port} in ${config.env} mode`);
});
export default api;
├───dist
└───src
├───config
├───controllers
├───models
├───routes
└───utils
How can I solve this problem? I wont use ssl right now. Thanks

Related

Network Error while connecting backend to frontend (MERN stack used)

I am making a web app and have made back-end with express, mongodb and node.js, while the frontend is made in React.js.
The backend runs completely fine on its own, when run using "nodemon server.js"
But when connected to frontend using axios, it throws "Network Error" error.
Here is my code to server.js (back-end, connecting url) and http-common.js (front-end, axios)
server.js
import cors from "cors";
import userquery from "./student/api/query.routes.js";
import admin from "./admin/api/admin.routes.js";
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api/v1/user", userquery);
app.use("/api/v1/admin", admin);
app.use("*", (req, res) => {
res.status(404).json({ error: "not found" });
});
export default app;
query.routes.js
import QueryCtrl from "./query.controller.js";
import personalQueriesCtrl from "./personalQueries.controller.js";
import SubjectCtrl from "./subject.controller.js";
import UserCtrl from "./user.controller.js";
const router = express.Router(); //creates routes people can go to
router.route("/").get(QueryCtrl.apiGetQueries);
router.route("/signup").post(UserCtrl.apiPostUser);
router.route("/subjects").get(SubjectCtrl.apiGetSubjects);
router.route("/AskQuery").post(personalQueriesCtrl.apiPostQuery);
export default router;
http-common.js
export default axios.create({
baseURL: "http://localhost:5000/api/v1/user/",
headers: {
"Content-type": "application/json",
},
proxy: false,
});
Please help if you can!

How can I use express app in Supertest request when it gets ready asynchronously?

I have a nodejs application which starts asynchronously because of graphql.
require('custom-env').env();
import { DateTruncAggregateGroupSpecsPlugin } from './subgraphs/db/date_trunc_aggregate_group_specs_plugin';
import PgAggregatesPlugin from "#graphile/pg-aggregates";
import FederationPlugin from "#graphile/federation";
import ConnectionFilterPlugin from "postgraphile-plugin-connection-filter";
const PostGraphileDerivedFieldPlugin = require("postgraphile-plugin-derived-field");
import express from "express";
import { ApolloServer, gql } from "apollo-server-express";
const { makeSchemaAndPlugin } = require("postgraphile-apollo-server");
import pg from 'pg';
import { makeExtendSchemaPlugin } from "graphile-utils";
import { readFileSync } from 'fs';
import { resolve } from 'path';
import resolvers from './resolvers';
export let app = express();
export let server: any;
const { PORT, NODE_ENV, SCHEMA, DATABASE_URL } = process.env;
async function main() {
const { schema, plugin } = await makeSchemaAndPlugin(
new pg.Pool({
connectionString: DATABASE_URL
}),
SCHEMA,
{
subscriptions: false,
appendPlugins: [
FederationPlugin,
ConnectionFilterPlugin,
PostGraphileDerivedFieldPlugin,
PgAggregatesPlugin,
DateTruncAggregateGroupSpecsPlugin,
makeExtendSchemaPlugin((build) => ({
typeDefs: gql(readFileSync(resolve(__dirname, '../graphs/custom.graphql'), { encoding: 'utf-8' })),
resolvers
}))
],
graphileBuildOptions: {
connectionFilterRelations: true
}
}
);
const graphql = new ApolloServer({
debug: false,
schema,
plugins: [plugin],
introspection: true
});
await graphql.start();
graphql.applyMiddleware({
app,
path: '/graphql'
});
server = this.app.listen(PORT, () => console.info(`🚀 Running on PORT ${PORT} 🚀`));
}
main();
The above is my express server that adds graphql to it.
As you can see, the starting of the server is asynchronous.
Now I am using supertest to test APIs end-to-end. Supertest requires app to be passed in.
I need server to start before all tests in my project and tests to be able to use app for supertest reuqest.
How do I do that. With regualar server it is easy as starting of server is not asynchronous, so my app is ready to use by tests. But not in this case. How do I carry out supertest requests.

What address should I use for "localhost" in my Flutter app?

I was using the following code within my Flutter app and it was working with no problems, but today after I upgraded my Flutter, it doesn't work and gives me XMLHttpRequest error.
Future<void> _authenticate(
String email, String password, String urlSegment) async {
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
final url = Uri.parse('http://$host:8000/api/$urlSegment');
try {
final http.Response response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(
{
'email': email,
'password': password,
},
),
);
Does anything have been changed in new Flutter version? Should I change the following line of code that specifies my host address?
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
EDIT: I tried to add cors to my NodeJS backend server and this is my app.ts file as following:
import express, { Request, Response, NextFunction } from "express";
import cors from "cors";
import dotenv from "dotenv";
dotenv.config();
import config from "config";
import responseTime from "response-time";
import connect from "./utils/connect";
import logger from "./utils/logger";
import routes from "./routes";
import deserializeUser from "./middleware/deserializeUser";
import { restResponseTimeHistogram, startMetricsServer } from "./utils/metrics";
import swaggerDocs from "./utils/swagger";
const allowedOrigins = ['http://localhost:8000' , 'https://10.0.2.2:8000', 'http://127.0.0.1:8000'];
const options: cors.CorsOptions = {
origin: allowedOrigins
};
const port = config.get<number>("port");
const app = express();
app.use(express.json());
app.use(cors(options));
app.use(deserializeUser);
app.use(
responseTime((req: Request, res: Response, time: number) => {
if (req?.route?.path) {
restResponseTimeHistogram.observe(
{
method: req.method,
route: req.route.path,
status_code: res.statusCode,
},
time * 1000
);
}
})
);
app.listen(port, async () => {
logger.info(`App is running at http://localhost:${port}`);
await connect();
routes(app);
startMetricsServer();
swaggerDocs(app, port);
});
But still doesn't work and I get the same error!
You've set the allowed origins to :8000, but that's the backend server's address. Instead, you need to set it to the Flutter debug server's address (and eventually to the web server where you host the production app, if that's not exactly the same as the backend server). (You can remove all the addresses ending in 8000.)
The problem is that the debug server picks a random port for each run. You can tell it to use a fixed port and then that becomes the port you need to include in your allowed origins.
Add --web-hostname=localhost --web-port=9999 as command line parameters to where you run your main.dart, then add localhost:9999 as an allowed origin.
(As a get-out-of-jail, also try * as an allowed origin.)
Finally, you should probably explicitly set the CORS allowed methods to the list of methods your server's API expects; probably OPTIONS, GET and POST.

Proper Way to Import Dev Dependencies in Express Application with ESLint

ESLint has me second-guessing myself today. I am building a simple Express application and it's yelling because I am importing DevDependencies in my app.ts file (yes, I am using Typescript). Basically I want my app to use the npm packages dotenv and morgan only when in development. In production, I will not need either of these packages. So what is the proper way to include these in my project?
Here is my current setup:
Basic app.ts file:
import express from 'express';
import morgan from 'morgan';
import dotenv from 'dotenv';
import helmet from 'helmet';
import compression from 'compression';
import cookieParser from 'cookie-parser';
import https from 'https';
import path from 'path';
import fs from 'fs';
import logger, { stream } from './util/logger';
/**
* Express Application Class
*/
class App {
public app: express.Application;
public port: number;
constructor(port: number) {
this.app = express();
this.port = port;
this.registerMiddleware();
}
/**
* Registers middleware for use
*/
private registerMiddleware(): void {
/** Use dotenv for development env variables */
if (process.env.NODE_ENV !== 'production') {
dotenv.config();
this.app.use(morgan('dev', { stream }));
}
this.app.use(helmet());
this.app.use(compression());
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: false }));
this.app.use(cookieParser());
}
/**
* Starts the Express.js server.
*/
public start(): void {
this.app.listen(this.port, () => {
logger.info(`Server started at https://localhost:${this.port}`);
});
}
/**
* Starts the secure Express.js server.
*/
public startDev(): void {
/** Start a secure Express server for local testing */
https
.createServer(
{
key: fs.readFileSync(path.resolve('server.key')),
cert: fs.readFileSync(path.resolve('server.crt')),
},
this.app
)
.listen(3000, () => {
logger.info(`Secure server started at https://localhost:${this.port}`);
});
}
}
export default App;
Basic server.ts file:
import App from './app';
/**
* Init Express.js server.
*/
const server = new App(3000);
/**
* Start Express.js server.
*/
if (process.env.NODE_ENV !== 'production') {
server.startDev();
} else {
server.start();
}
you can save them as optional dependencies other than dev dependencies using
npm install dotenv morgan --save-optional
Reference

Cannot use TypeOrm with express "connection "Default" not found

I'm currently having a bad time with typeOrm, I don't know why but express is getting initialized before my connection to the database with typeOrm So I get an error "Connection default not found"
here's the code
Typeorm.config.ts
import {Connection, createConnection} from 'typeorm';
export function connectToDb(): Promise<Connection> {
return createConnection({
type: 'postgres',
url: process.env.TYPEORM_URL,
synchronize: false,
logging: true,
entities: [process.env.TYPEORM_ENTITIES],
migrations: ["../../migrations/*.ts"],
cli: {migrationsDir: process.env.TYPEORM_MIGRATIONS_DIR}
})
}
Room.repository
import {getRepository} from 'typeorm';
import {Room} from '../entities/Room';
const roomRepository = getRepository(Room)
export async function getAllRooms(): Promise<Room[]> {
return await roomRepository.find()
}
this repo is used by my router, here's my app.ts
import * as express from 'express'
import * as bodyParser from 'body-parser';
import * as PassportJs from './passport';
import cors from 'cors';
import logger from './config/logger';
import "reflect-metadata";
import * as dotenv from 'dotenv';
dotenv.config();
import roomRouter from './routes/room.route';
import {connectToDb} from './config/typeorm.config';
const passport = PassportJs.initPassport();
async function main(): Promise<void> {
logger.info('connecting to database...')
await connectToDb()
logger.info('connected to database')
const app = express();
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(cors());
app.use(roomRouter);
app.listen(3000, () => {
logger.info(`API is running on port ${3000}`);
});
}
main().catch(error => {
logger.error(error)
process.exit(1)
})
Can you help me?
Thank
From the code snippets you have share, I guess const roomRepository = getRepository(Room) is being called before the await connectToDb(). Creating a repo needs connection.

Resources