Skip to content

Commit b2ab9fb

Browse files
committed
Add support for dynamic password
1 parent 3f76b98 commit b2ab9fb

File tree

4 files changed

+33
-13
lines changed

4 files changed

+33
-13
lines changed

lib/backend.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,7 @@ function Backend({
153153

154154
function Authentication(x) {
155155
const type = x.readInt32BE(5)
156-
try {
157-
type !== 0 && onauth(type, x, error)
158-
} /* c8 ignore next */ catch (err) { error(err) }
156+
type !== 0 && onauth(type, x, error)
159157
}
160158

161159
function ParameterStatus(x) {

lib/connection.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,14 @@ function Connection(options = {}) {
5656
statements[backend.query.statement.sig] = backend.query.statement
5757
}
5858

59-
function onauth(type, x) {
60-
socket.write(frontend.auth(type, x, options))
59+
function onauth(type, x, onerror) {
60+
Promise.resolve(
61+
typeof options.pass === 'function'
62+
? options.pass()
63+
: options.pass
64+
).then(pass =>
65+
socket.write(frontend.auth(type, x, options, pass))
66+
).catch(onerror)
6167
}
6268

6369
function end() {

lib/frontend.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ function connect({ user, database, connection }) {
5757
.end(0)
5858
}
5959

60-
function auth(type, x, options) {
60+
function auth(type, x, options, pass) {
6161
if (type in auths)
62-
return auths[type](type, x, options)
62+
return auths[type](type, x, options, pass)
6363
/* c8 ignore next */
6464
throw errors.generic({
6565
message: 'Auth type ' + (authNames[type] || type) + ' not implemented',
@@ -68,23 +68,23 @@ function auth(type, x, options) {
6868
})
6969
}
7070

71-
function AuthenticationCleartextPassword(type, x, { pass }) {
71+
function AuthenticationCleartextPassword(type, x, options, pass) {
7272
return bytes
7373
.p()
7474
.str(pass)
7575
.z(1)
7676
.end()
7777
}
7878

79-
function AuthenticationMD5Password(type, x, { user, pass }) {
79+
function AuthenticationMD5Password(type, x, options, pass) {
8080
return bytes
8181
.p()
82-
.str('md5' + md5(Buffer.concat([Buffer.from(md5(pass + user)), x.slice(9)])))
82+
.str('md5' + md5(Buffer.concat([Buffer.from(md5(pass + options.user)), x.slice(9)])))
8383
.z(1)
8484
.end()
8585
}
8686

87-
function SASL(type, x, options) {
87+
function SASL(type, x, options, pass) {
8888
bytes
8989
.p()
9090
.str('SCRAM-SHA-256' + N)
@@ -100,11 +100,11 @@ function SASL(type, x, options) {
100100
.end()
101101
}
102102

103-
function SASLContinue(type, x, options) {
103+
function SASLContinue(type, x, options, pass) {
104104
const res = x.utf8Slice(9).split(',').reduce((acc, x) => (acc[x[0]] = x.slice(2), acc), {})
105105

106106
const saltedPassword = crypto.pbkdf2Sync(
107-
options.pass,
107+
pass,
108108
Buffer.from(res.s, 'base64'),
109109
parseInt(res.i), 32,
110110
'sha256'

tests/index.js

+16
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,22 @@ t('Login using scram-sha-256', async() => {
301301
return [true, (await postgres({ ...options, ...login_scram })`select true as x`)[0].x]
302302
})
303303

304+
t('Support dynamic password function', async() => {
305+
return [true, (await postgres({
306+
...options,
307+
...login_scram,
308+
pass: () => 'postgres_js_test_scram'
309+
})`select true as x`)[0].x]
310+
})
311+
312+
t('Support dynamic async password function', async() => {
313+
return [true, (await postgres({
314+
...options,
315+
...login_scram,
316+
pass: () => Promise.resolve('postgres_js_test_scram')
317+
})`select true as x`)[0].x]
318+
})
319+
304320
t('Point type', async() => {
305321
const sql = postgres({
306322
...options,

0 commit comments

Comments
 (0)