Home > Software design >  Node, Postgres and Knex: SASL: SCRAM_SERVER_FIRST_MESSAGE: client password must be a string
Node, Postgres and Knex: SASL: SCRAM_SERVER_FIRST_MESSAGE: client password must be a string

Time:05-29

I am creating a site using Node.js, React, Vite, Knex.js and PostgreSQL and have run into an error when trying to start up my server and connect to my database which I don't know how to solve. I have looked around elsewhere online, which also hasn't been much help. Here are what the relevant files look like:

server.js

const express = require('express');
const PATH = 5000;
const app = express();
const cors = require('cors');
const session = require('./db/session');
const { passport } = require('./passport');

app.use(cors({
    origin: process.env.VITE_CORS_ORIGIN,
    credentials: true
}));

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(session);

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

app.use(require('./routes'));

app.use(function(req, res, next) {
    res.status(404).send("Unable to find requested resource.")
});

app.use((err, req, res, next) => {
    if (err) {
        req.logout();
        next();
    }
    res.status(err.status || 500).send(err.message);
});

app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`)
});

knexfile.js

const path = require('path');
require('dotenv').config({ path: path.join(__dirname, '.env.development') });

const dbMode = 
    process.env.VITE_ENV === 'development' ? {
        client: "pg",
        connection: {
             host: 'localhost',
             port: 5432,
             user: process.env.VITE_DB_USER,
             password: process.env.VITE_DB_PASS,
             database: process.env.VITE_DB_NAME,
             charset: 'utf8'
        },
        migrations: {
            directory: './server/db/migrations',
            tableName: "knex_migrations"
        },
        seeds: {
            directory: './server/db/seeds'
        },
  } : {
   client: "pg",
   connection: process.env.DATABASE_URL,
   ssl: { require: true }
}

module.exports = dbMode;

db.js

const knex = require('knex');
const dbConfig = require('../../knexfile');
const db = knex(dbConfig);

module.exports = db;

I also have a session store set up using express-session and connect-pg-simple. I also use Passport.js.

Whenever I try start the server ('node initServer.js') I get the error message:

<project path>/node_modules/pg/lib/sasl.js:24
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string'

I have made sure that all my environment variables are working and are the right type. I have used console.log() to confirm that the variables aren't undefined and used typeof to confirm that the type of the environment variable for the DB password is a string.

I am using the same password details and postgreSQL installation as I used for another recent project, so I am sure that the password is not wrong and that all the details are correct.

I have no idea what I need to do to fix this as the password is (as far as I can tell) being passed correctly. I'd really appreciate your help.

If there's anything you'd like me to show or explain to help you solve this, please let me know.

CodePudding user response:

I found a solution, though I am not entirely sure why this was necessary given that in projects I have done in the past this step was not required in order to connect to my database.

It turns out that the issue was connected to my session.js file. By adding the database connection object from my knexfile to express-session as follows, I was able to get around this error:

const path = require('path');
const connection = require('../../knexfile');
require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env.development') });
const express_session = require('express-session');
const pgSession = require('connect-pg-simple')(express_session);

const theSecret = process.env.VITE_SESSION_SECRET;

const session = express_session({
    store: new pgSession({ tableName: 'sessions', conObject: connection }),
    secret: theSecret,
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 1000 * 60 * 60 * 24 }
})

module.exports = session;

Admittedly, I actually still have another issue despite doing this. Though I can now actually run my server, for some reason I also get the below message:

Failed to prune sessions: con.connect is not a function

I will make a separate question about this.

  • Related