diff --git a/lib/nano.js b/lib/nano.js index fd85bc0..70a9965 100644 --- a/lib/nano.js +++ b/lib/nano.js @@ -17,7 +17,6 @@ const axios = require('axios').default const axiosCookieJarSupport = require('axios-cookiejar-support').default const tough = require('tough-cookie') axiosCookieJarSupport(axios) -const cookieJar = new tough.CookieJar() const stream = require('stream') const http = require('http') const https = require('https') @@ -73,6 +72,8 @@ module.exports = exports = function dbScope (cfg) { cfg = Object.assign({}, cfg) + cfg.cookieJar = new tough.CookieJar() + serverScope.config = cfg cfg.requestDefaults = cfg.requestDefaults || {} @@ -273,7 +274,7 @@ module.exports = exports = function dbScope (cfg) { const isJar = opts.jar || cfg.jar || (cfg.requestDefaults && cfg.requestDefaults.jar) if (isJar) { - req.jar = cookieJar + req.jar = cfg.cookieJar req.withCredentials = true } @@ -366,7 +367,7 @@ module.exports = exports = function dbScope (cfg) { // ?drilldown=["author","Dickens"]&drilldown=["publisher","Penguin"] req.qsStringifyOptions = { arrayFormat: 'repeat' } - cfg.cookies = cookieJar.getCookiesSync(cfg.url) + cfg.cookies = cfg.cookieJar.getCookiesSync(cfg.url) // This where the HTTP request is made. // Nano used to use the now-deprecated "request" library but now we're going to diff --git a/test/nano.auth.test.js b/test/nano.auth.test.js index f0c71d6..d124dbc 100644 --- a/test/nano.auth.test.js +++ b/test/nano.auth.test.js @@ -13,24 +13,36 @@ const Nano = require('..') const COUCH_URL = 'http://localhost:5984' const nano = Nano({ url: COUCH_URL, jar: true }) +const nano2 = Nano({ url: COUCH_URL, jar: true }) const nock = require('nock') afterEach(() => { nock.cleanAll() }) -test('should be able to authenticate - POST /_session - nano.auth', async () => { +test('should be able to authenticate multiple separate sessions - POST /_session - nano.auth', async () => { // mocks const username = 'u' + const username2 = 'u2' const password = 'p' + const password2 = 'p2' const response = { ok: true, name: 'admin', roles: ['_admin', 'admin'] } + const response2 = { ok: true, name: 'operator', roles: ['_admin'] } const authsession = 'AuthSession=YWRtaW46NUU0MTFBMDE6stHsxYnlDy4mYxwZEcnXHn4fm5w;' + const authsession2 = 'AuthSession=XYZtaW46NUU0MTFBMDE6stHsxYnlDy4mYxwZEcnXHn4123;' const cookie = authsession + ' Version=1; Expires=Mon, 10-Feb-2050 09:03:21 GMT; Max-Age=600; Path=/; HttpOnly' + const cookie2 = authsession2 + ' Version=1; Expires=Fri Jun 10 2022 20:13:00 GMT; Max-Age=300; Path=/; HttpOnly' const scope = nock(COUCH_URL) .post('/_session', 'name=u&password=p', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' }) .reply(200, response, { 'Set-Cookie': cookie }) .get('/_all_dbs') .reply(200, ['a']) + .post('/_session', 'name=u2&password=p2', { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' }) + .reply(200, response2, { 'Set-Cookie': cookie2 }) + .get('/_all_dbs') + .reply(200, ['a']) + .get('/_all_dbs') + .reply(200, ['a']) // test POST /_session const p = await nano.auth(username, password) @@ -38,5 +50,17 @@ test('should be able to authenticate - POST /_session - nano.auth', async () => await nano.db.list() expect(nano.config.cookies.length).toBe(1) expect(nano.config.cookies[0].toString().startsWith(authsession)).toBe(true) + + // test POST /_session + const p2 = await nano2.auth(username2, password2) + expect(p2).toStrictEqual(response2) + await nano2.db.list() + expect(nano2.config.cookies.length).toBe(1) + expect(nano2.config.cookies[0].toString()).toMatch(new RegExp('^' + authsession2)) + + await nano.db.list() + expect(nano.config.cookies.length).toBe(1) + expect(nano.config.cookies[0].toString()).toMatch(new RegExp('^' + authsession)) + expect(scope.isDone()).toBe(true) })