-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add dynamic retrieval for client password (#1926)
* feat: Add dynamic retrieval for client password Adds option to specify a function for a client password. When the client is connected, if the value of password is a function then it is invoked to get the password to use for that connection. The function must return either a string or a Promise that resolves to a string. If the function throws or rejects with an error then it will be bubbled up to the client. * test: Add testAsync() helper to Suite Add testAsync() helper function to Suite to simplify running tests that return a Promise. The test action is executed and if a syncronous error is thrown then it is immediately considered failed. If the Promise resolves successfully then the test is considered successful. If the Promise rejects with an Error then the test is considered failed. * test: Add tests for dynamic password * test: Simplify testAsync error handling * fix: Clean up dynamic password error handling and misc style * test: Remove extra semicolons * test: Change testAsync(...) calls to use arrow functions * fix: Wrap self.password() invocation in an arrow function * test: Add a comment to testAsync(...)
- Loading branch information
Showing
3 changed files
with
145 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
'use strict' | ||
const assert = require('assert') | ||
const helper = require('./../test-helper') | ||
const suite = new helper.Suite() | ||
const pg = require('../../../lib/index') | ||
const Client = pg.Client; | ||
|
||
const password = process.env.PGPASSWORD || null | ||
const sleep = millis => new Promise(resolve => setTimeout(resolve, millis)) | ||
|
||
suite.testAsync('Get password from a sync function', () => { | ||
let wasCalled = false | ||
function getPassword() { | ||
wasCalled = true | ||
return password | ||
} | ||
const client = new Client({ | ||
password: getPassword, | ||
}) | ||
return client.connect() | ||
.then(() => { | ||
assert.ok(wasCalled, 'Our password function should have been called') | ||
return client.end() | ||
}) | ||
}) | ||
|
||
suite.testAsync('Throw error from a sync function', () => { | ||
let wasCalled = false | ||
const myError = new Error('Oops!') | ||
function getPassword() { | ||
wasCalled = true | ||
throw myError | ||
} | ||
const client = new Client({ | ||
password: getPassword, | ||
}) | ||
let wasThrown = false | ||
return client.connect() | ||
.catch(err => { | ||
assert.equal(err, myError, 'Our sync error should have been thrown') | ||
wasThrown = true | ||
}) | ||
.then(() => { | ||
assert.ok(wasCalled, 'Our password function should have been called') | ||
assert.ok(wasThrown, 'Our error should have been thrown') | ||
return client.end() | ||
}) | ||
}) | ||
|
||
suite.testAsync('Get password from a function asynchronously', () => { | ||
let wasCalled = false | ||
function getPassword() { | ||
wasCalled = true | ||
return sleep(100).then(() => password) | ||
} | ||
const client = new Client({ | ||
password: getPassword, | ||
}) | ||
return client.connect() | ||
.then(() => { | ||
assert.ok(wasCalled, 'Our password function should have been called') | ||
return client.end() | ||
}) | ||
}) | ||
|
||
suite.testAsync('Throw error from an async function', () => { | ||
let wasCalled = false | ||
const myError = new Error('Oops!') | ||
function getPassword() { | ||
wasCalled = true | ||
return sleep(100).then(() => { | ||
throw myError | ||
}) | ||
} | ||
const client = new Client({ | ||
password: getPassword, | ||
}) | ||
let wasThrown = false | ||
return client.connect() | ||
.catch(err => { | ||
assert.equal(err, myError, 'Our async error should have been thrown') | ||
wasThrown = true | ||
}) | ||
.then(() => { | ||
assert.ok(wasCalled, 'Our password function should have been called') | ||
assert.ok(wasThrown, 'Our error should have been thrown') | ||
return client.end() | ||
}) | ||
}) | ||
|
||
suite.testAsync('Password function must return a string', () => { | ||
let wasCalled = false | ||
function getPassword() { | ||
wasCalled = true | ||
// Return a password that is not a string | ||
return 12345 | ||
} | ||
const client = new Client({ | ||
password: getPassword, | ||
}) | ||
let wasThrown = false | ||
return client.connect() | ||
.catch(err => { | ||
assert.ok(err instanceof TypeError, 'A TypeError should have been thrown') | ||
assert.equal(err.message, 'Password must be a string') | ||
wasThrown = true | ||
}) | ||
.then(() => { | ||
assert.ok(wasCalled, 'Our password function should have been called') | ||
assert.ok(wasThrown, 'Our error should have been thrown') | ||
return client.end() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters