Issue login route using passport local strategy

Hi, I am fairly new to coding and I am having a problem with a Web Service and Postgres SQL database that I have deployed to render.

I have created an Postgres SQL database, and Web Service. The web service will act as a server back end for a React App that I have not deployed yet. I am testing the server and the database using postman and most of the routes seem to be working fine, however I am having trouble following the sign in route.

I am using a passport local strategy, and the sql databse as a session store. From adding console.log’s it seems that retrieving the user details from the database to compare to the body of the request works fine, however I have an issue when the session is needed to be created I get the following error message: AggregateError [ECONNREFUSED].

I have put the relevant code below:

SERVER SETUP:

// set up imports
const express = require('express');
require('dotenv').config();
const passport = require('passport');
const initializePassport = require('./controllers/auth.js');
const helmet = require('helmet');
const cors = require('cors');
const session = require('express-session');
const { DB, SS } =require('./config');

//route imports
const { registerRouter, signinRouter, logoutRouter, orderRouter, userRouter, checkRouter } = require('./routes/userRoute.js');
const { productRouter } = require('./routes/productRoute.js');
const { cartRouter } = require('./routes/cartRoute.js');

//server setup
const app = express();

app.set('trust proxy', 1)

// Used for testing to make sure server / express app is running.
app.get('/', (req, res, next) => {
    res.send('<h1>Hello Kiernan</h1>');
});

app.use(cors({
    origin: "http://localhost:3000",
    methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'DELETE', 'HEAD'],
    credentials: true,
}));
app.use(helmet());
const pgSession = require('connect-pg-simple')(session);
const { PORT } =require('./config');
const port = PORT || 3001;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));


const options = {
    user: DB.DB_USER, 
    host: DB.DB_HOST,
    database: DB.DB_DATABASE,
    password: DB.DB_PASSWORD,
    port: DB.DB_PORT,
    createDatabaseTable: true,
    createTableIfMissing: true
};

console.log(options);

const sessionStore = new pgSession(options);

app.use(session({
    name: SS.SS_SESS_NAME,
    resave: false, 
    saveUninitialized: false, 
    store: sessionStore,
    secret: SS.SS_SESS_SECRET,
    cookie: {
        maxAge: Number(SS.SS_SESS_LIFETIME),
        sameSite: 'lax', 
        secure: true,
        domain: "localhost",
        httpOnly: true,
        hostOnly: false,
    } 
}));

app.use(passport.initialize());
app.use(passport.session());

initializePassport(passport);

//configuration to allow the front end to store cookies created on the server:
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", http://localhost:3000); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Credentials", true); // allows cookie to be sent
    res.header("Access-Control-Allow-Methods", "GET, POST, PUT, HEAD, DELETE"); // you must specify the methods used with credentials. "*" will not work. 
    next();
});

//route for users
app.use('/api/users/register', registerRouter);
app.use('/api/users/signin', signinRouter);
app.use('/api/users/logout', logoutRouter);
app.use('/api/users/orders', orderRouter);
app.use('/api/users/details', userRouter);
app.use('/api/users/check-session', checkRouter);

//route for products
app.use('/api/products', productRouter);

//route for cart
app.use('/api/cart', cartRouter)

//app.listen
app.listen(port, () => {
    console.log(`Your server is listening on port: ${port}`);
});

SIGN IN ROUTE:

const signinRouter = express.Router();
signinRouter.post('/', (req, res, next) => {
    passport.authenticate('local', async (err, user, info) => {
        if (err) {
            return res.status(500).json({ error: 'Internal Server Error' });
        }
    
        if (!user) {
            return res.status(401).json ({ message: info.message, check: 'this is the error I am getting today' });
        }
        req.login(user, (loginErr) => {
            if (loginErr) {
                return res.status(500).json({ error: 'Login Error', msg: loginErr });
            }
            return res.status(200).json({ user }); 
        });
    }) (req, res, next);
});

LOCAL STRATEGY:

const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');

const pool = require('../db/index');

module.exports = (passport) => {
    const query = async (queryString, params) => {
        return await pool.query(queryString, params);
    };

    passport.use(
        new LocalStrategy ( async ( username, password, done) => {
            try {
                const querySchema = { name: 'user', email: `${username}`};
                const queryString = `SELECT * FROM user_customer WHERE email = $1`;
                const userResult = await query(queryString, [querySchema.email]);

                if (userResult.rows.length === 0 ) {
                    return done(null, false, { message: 'User not found' });
                }

                const foundUser = userResult.rows[0];

                console.log('This is the found user from auth.js', foundUser)

                const isMatch = await bcrypt.compare(password, foundUser.password);
                if (isMatch) {
                    return done(null, { //rather than an object here, does it just need to say 'user' after null?
                        id: foundUser.id,
                        email: foundUser.email,
                        firstName: foundUser.first_name,
                        lastName: foundUser.last_name
                    });
                } else {
                    return done(null, false, {message: 'Incorrect password '});
                }
            } catch (err) {
                console.error('Error during authentication. ' + err);
                return done(err);
            }
        })
    );

    passport.serializeUser((user, done) => {
        done(null, user.id);
    });

    passport.deserializeUser(async (id, done) => {
        try {
            const userResult = await query('SELECT * FROM user_customer WHERE id = $1',
                [id]
            );
            if (userResult.rows.length === 0) {
                return done(new Error('User not found'));
            } return done(null, userResult.rows[0].id);
        } catch(err) {
            done(err);
        }
    });
};

Any help would be greatly appreciated!

Many Thanks.

Hi,

I’ve replied to the ticket you also opened. Let’s keep the conversation in one place (on the ticket).

In general terms, it seems the ECONNREFUSED is coming from a misconfiguration in your Postgres connection.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.