A-PSquestions
A-PSquestions

Reputation: 105

Node, Postgres and Knex: SASL: SCRAM_SERVER_FIRST_MESSAGE: client password must be a string

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.

Upvotes: 2

Views: 2926

Answers (2)

boykland
boykland

Reputation: 144

Couple days I had this same issue running the knex migrate:list cli command. Checking your example, you are doing as the same way I had before. So testing changes and reading the knex documentation I reached to conclusion that:

Its seems like the knex-cli not reading the values from the environment variables

enter image description here


If you still have the issue, these are the steps I follow to fixed it

1. What I did to be sure that the knex-cli was reading the environments variables, I add the client config as static string values. This will validate the reading variable issue.

enter image description here

2. Instead of using path lib and __dirname, I just used the relative path.

enter image description here

3. I tested the fix, running the knex migrate:list, and its work for me.

enter image description here

Maybe you others alternative of solution, but if you reach to fix the issue in ad different way please share it as a comment, so we can exchange knowledge and see a different way how to solve this issue.

Regards

Upvotes: 1

A-PSquestions
A-PSquestions

Reputation: 105

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.

Upvotes: 0

Related Questions