From 71a66dd2d47fb35f54d10e83aaaa89310fc1c56e Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 12:45:44 -0600 Subject: [PATCH 1/6] Pass connection parameters to password callback --- packages/pg/Makefile | 1 + packages/pg/lib/client.js | 2 +- .../unit/client/password-callback-tests.js | 66 +++++++++++++++++++ packages/pg/test/unit/client/test-helper.js | 4 +- 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 packages/pg/test/unit/client/password-callback-tests.js diff --git a/packages/pg/Makefile b/packages/pg/Makefile index 5575acfd8..a66c107ae 100644 --- a/packages/pg/Makefile +++ b/packages/pg/Makefile @@ -27,6 +27,7 @@ bench: @find benchmark -name "*-bench.js" | $(node-command) test-unit: + @chmod 600 test/unit/client/pgpass.file @find test/unit -name "*-tests.js" | $(node-command) test-connection: diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 459439037..0168ce637 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -249,7 +249,7 @@ class Client extends EventEmitter { if (typeof this.password === 'function') { this._Promise .resolve() - .then(() => this.password()) + .then(() => this.password(this.connectionParameters)) .then((pass) => { if (pass !== undefined) { if (typeof pass !== 'string') { diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js new file mode 100644 index 000000000..b1851fc78 --- /dev/null +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -0,0 +1,66 @@ +'use strict' +const helper = require('./test-helper') +const assert = require('assert') +const suite = new helper.Suite() +const pgpass = require('pgpass') + +class Wait { + constructor() { + this.promise = new Promise((resolve) => { + this.resolve = resolve + }) + } + + until() { + return this.promise + } + + done(time) { + if (time) { + setTimeout(this.resolve.bind(this), time) + } else { + this.resolve() + } + } +} + +suite.test('password callback is called with conenction params', async function () { + const wait = new Wait() + const client = helper.client({ + user: 'foo', + database: 'bar', + host: 'baz', + password: async () => { + wait.done(1) + return 'password' + }, + }) + client.connection.emit('authenticationCleartextPassword') + await wait.until() + assert.equal(client.user, 'foo') + assert.equal(client.database, 'bar') + assert.equal(client.host, 'baz') + assert.equal(client.connectionParameters.password, 'password') +}) + +suite.test('cleartext password auth does not crash with null password using pg-pass', async function () { + process.env.PGPASSFILE = `${__dirname}/pgpass.file` + const wait = new Wait() + const client = helper.client({ + host: 'foo', + port: 5432, + database: 'bar', + user: 'baz', + password: (params) => { + return new Promise((resolve) => { + pgpass(params, (pass) => { + wait.done(1) + resolve(pass) + }) + }) + }, + }) + client.connection.emit('authenticationCleartextPassword') + await wait.until() + assert.equal(client.password, 'quz') +}) diff --git a/packages/pg/test/unit/client/test-helper.js b/packages/pg/test/unit/client/test-helper.js index 3e8f75c31..4a3fa9687 100644 --- a/packages/pg/test/unit/client/test-helper.js +++ b/packages/pg/test/unit/client/test-helper.js @@ -3,7 +3,7 @@ const helper = require('../test-helper') const Connection = require('../../../lib/connection') const { Client } = helper -const makeClient = function () { +const makeClient = function (config) { const connection = new Connection({ stream: 'no' }) connection.startup = function () {} connection.connect = function () {} @@ -11,7 +11,7 @@ const makeClient = function () { this.queries.push(text) } connection.queries = [] - const client = new Client({ connection: connection }) + const client = new Client({ connection: connection, ...config }) client.connect() client.connection.emit('connect') return client From 50ca5fa712914171fc0c754b4e058fdd17609e05 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 12:52:02 -0600 Subject: [PATCH 2/6] Works on my machine - adding logging for gh actions --- .../pg/test/unit/client/password-callback-tests.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js index b1851fc78..af3e6eee2 100644 --- a/packages/pg/test/unit/client/password-callback-tests.js +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -3,6 +3,7 @@ const helper = require('./test-helper') const assert = require('assert') const suite = new helper.Suite() const pgpass = require('pgpass') +const fs = require('fs') class Wait { constructor() { @@ -31,7 +32,7 @@ suite.test('password callback is called with conenction params', async function database: 'bar', host: 'baz', password: async () => { - wait.done(1) + wait.done(10) return 'password' }, }) @@ -46,15 +47,24 @@ suite.test('password callback is called with conenction params', async function suite.test('cleartext password auth does not crash with null password using pg-pass', async function () { process.env.PGPASSFILE = `${__dirname}/pgpass.file` const wait = new Wait() + console.log() + console.log('hit hit hit') + console.log('PGPASSFILE', process.env.PGPASSFILE) + // check if file exists + if (!fs.existsSync(process.env.PGPASSFILE)) { + throw new Error('PGPASSFILE does not exist') + } const client = helper.client({ host: 'foo', port: 5432, database: 'bar', user: 'baz', password: (params) => { + console.log('in password callback') return new Promise((resolve) => { pgpass(params, (pass) => { - wait.done(1) + console.log('in pgpass callback. read password:', pass) + wait.done(10) resolve(pass) }) }) From bc8b8f594c2a328349070f088a4281f9be821220 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 13:03:25 -0600 Subject: [PATCH 3/6] More debugging logging in tests --- packages/pg/test/unit/client/password-callback-tests.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js index af3e6eee2..63c09c619 100644 --- a/packages/pg/test/unit/client/password-callback-tests.js +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -54,6 +54,10 @@ suite.test('cleartext password auth does not crash with null password using pg-p if (!fs.existsSync(process.env.PGPASSFILE)) { throw new Error('PGPASSFILE does not exist') } + // print the contents of the file + console.log('contents of the file:', fs.readFileSync(process.env.PGPASSFILE, 'utf8')) + // print the mode of the file + console.log('stats of the file:', fs.statSync(process.env.PGPASSFILE)) const client = helper.client({ host: 'foo', port: 5432, From fc8d735e65035db271a881acd0d4f27c2e529c79 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 13:46:39 -0600 Subject: [PATCH 4/6] Blank out password in unit test --- packages/pg/test/unit/client/password-callback-tests.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js index 63c09c619..f28a00118 100644 --- a/packages/pg/test/unit/client/password-callback-tests.js +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -46,6 +46,8 @@ suite.test('password callback is called with conenction params', async function suite.test('cleartext password auth does not crash with null password using pg-pass', async function () { process.env.PGPASSFILE = `${__dirname}/pgpass.file` + // set this to undefined so pgpass will use the file + process.env.PGPASSWORD = undefined const wait = new Wait() console.log() console.log('hit hit hit') From 282f385ca98b2d140335995bc364f4136e4966d7 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 13:55:11 -0600 Subject: [PATCH 5/6] Try again... --- packages/pg/test/unit/client/password-callback-tests.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js index f28a00118..6f17fc130 100644 --- a/packages/pg/test/unit/client/password-callback-tests.js +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -31,7 +31,10 @@ suite.test('password callback is called with conenction params', async function user: 'foo', database: 'bar', host: 'baz', - password: async () => { + password: async (params) => { + assert.equal(params.user, 'foo') + assert.equal(params.database, 'bar') + assert.equal(params.host, 'baz') wait.done(10) return 'password' }, @@ -47,7 +50,7 @@ suite.test('password callback is called with conenction params', async function suite.test('cleartext password auth does not crash with null password using pg-pass', async function () { process.env.PGPASSFILE = `${__dirname}/pgpass.file` // set this to undefined so pgpass will use the file - process.env.PGPASSWORD = undefined + delete process.env.PGPASSWORD const wait = new Wait() console.log() console.log('hit hit hit') @@ -66,7 +69,6 @@ suite.test('cleartext password auth does not crash with null password using pg-p database: 'bar', user: 'baz', password: (params) => { - console.log('in password callback') return new Promise((resolve) => { pgpass(params, (pass) => { console.log('in pgpass callback. read password:', pass) From 2db4bcb2f6d18d014f9bf6c46328c7b3348392a1 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Wed, 11 Feb 2026 14:04:00 -0600 Subject: [PATCH 6/6] Remove debugging --- .../pg/test/unit/client/password-callback-tests.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/pg/test/unit/client/password-callback-tests.js b/packages/pg/test/unit/client/password-callback-tests.js index 6f17fc130..bf1885e94 100644 --- a/packages/pg/test/unit/client/password-callback-tests.js +++ b/packages/pg/test/unit/client/password-callback-tests.js @@ -1,9 +1,7 @@ -'use strict' const helper = require('./test-helper') const assert = require('assert') const suite = new helper.Suite() const pgpass = require('pgpass') -const fs = require('fs') class Wait { constructor() { @@ -52,17 +50,6 @@ suite.test('cleartext password auth does not crash with null password using pg-p // set this to undefined so pgpass will use the file delete process.env.PGPASSWORD const wait = new Wait() - console.log() - console.log('hit hit hit') - console.log('PGPASSFILE', process.env.PGPASSFILE) - // check if file exists - if (!fs.existsSync(process.env.PGPASSFILE)) { - throw new Error('PGPASSFILE does not exist') - } - // print the contents of the file - console.log('contents of the file:', fs.readFileSync(process.env.PGPASSFILE, 'utf8')) - // print the mode of the file - console.log('stats of the file:', fs.statSync(process.env.PGPASSFILE)) const client = helper.client({ host: 'foo', port: 5432, @@ -71,7 +58,6 @@ suite.test('cleartext password auth does not crash with null password using pg-p password: (params) => { return new Promise((resolve) => { pgpass(params, (pass) => { - console.log('in pgpass callback. read password:', pass) wait.done(10) resolve(pass) })