Skip to content

Commit

Permalink
fix(ajax): correctly handle Basic authentication
Browse files Browse the repository at this point in the history
Fixes pouchdb-community#109.

When username and password are present in db url, generate Basic
authentication token and put it in ajax request headers.
  • Loading branch information
ptitjes committed Nov 22, 2017
1 parent d84f03d commit 31983c2
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 8 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"dependencies": {
"inherits": "2.0.3",
"pouchdb-ajax": "6.3.4",
"pouchdb-binary-utils": "6.3.4",
"pouchdb-promise": "6.3.4",
"pouchdb-utils": "6.3.4",
"url-join": "2.0.2",
Expand Down
4 changes: 3 additions & 1 deletion src/admins.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AuthError, getConfigUrl, wrapError } from './utils';
import { AuthError, getBasicAuthHeaders, getConfigUrl, wrapError } from './utils';

import ajaxCore from 'pouchdb-ajax';
import { assign, toPromise } from 'pouchdb-utils';
Expand All @@ -23,6 +23,7 @@ var signUpAdmin = toPromise(function (username, password, opts, callback) {
var ajaxOpts = assign({
method: 'PUT',
url: url,
headers: getBasicAuthHeaders(db),
body: '"' + password + '"',
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
Expand All @@ -45,6 +46,7 @@ var deleteAdmin = toPromise(function (username, opts, callback) {
var ajaxOpts = assign({
method: 'DELETE',
url: url,
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
Expand Down
6 changes: 4 additions & 2 deletions src/authentication.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

import { AuthError, getSessionUrl, wrapError } from './utils';
import { AuthError, getBasicAuthHeaders, getSessionUrl, wrapError } from './utils';

import ajaxCore from 'pouchdb-ajax';
import { assign, toPromise } from 'pouchdb-utils';
Expand All @@ -24,7 +24,7 @@ var logIn = toPromise(function (username, password, opts, callback) {
var ajaxOpts = assign({
method: 'POST',
url: getSessionUrl(db),
headers: {'Content-Type': 'application/json'},
headers: assign({'Content-Type': 'application/json'}, getBasicAuthHeaders(db)),
body: {name: username, password: password},
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
Expand All @@ -39,6 +39,7 @@ var logOut = toPromise(function (opts, callback) {
var ajaxOpts = assign({
method: 'DELETE',
url: getSessionUrl(db),
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
Expand All @@ -54,6 +55,7 @@ var getSession = toPromise(function (opts, callback) {
var ajaxOpts = assign({
method: 'GET',
url: url,
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
Expand Down
7 changes: 6 additions & 1 deletion src/users.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

import { AuthError, getUsersUrl, wrapError } from './utils';
import { AuthError, getBasicAuthHeaders, getUsersUrl, wrapError } from './utils';

import Promise from 'pouchdb-promise';
import ajaxCore from 'pouchdb-ajax';
Expand Down Expand Up @@ -43,6 +43,7 @@ function updateUser(db, user, opts, callback) {
method: 'PUT',
url: url,
body: user,
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
}
Expand Down Expand Up @@ -89,6 +90,7 @@ var getUser = toPromise(function (username, opts, callback) {
var ajaxOpts = assign({
method: 'GET',
url: url + '/' + encodeURIComponent('org.couchdb.user:' + username),
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
Expand Down Expand Up @@ -137,6 +139,7 @@ var deleteUser = toPromise(function (username, opts, callback) {
var ajaxOpts = assign({
method: 'DELETE',
url: url,
headers: getBasicAuthHeaders(db),
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
Expand Down Expand Up @@ -169,6 +172,7 @@ var changePassword = toPromise(function (username, password, opts, callback) {
var ajaxOpts = assign({
method: 'PUT',
url: url,
headers: getBasicAuthHeaders(db),
body: user,
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
Expand All @@ -193,6 +197,7 @@ var changeUsername = toPromise(function (oldUsername, newUsername, opts, callbac
var updateOpts = assign({
method: 'PUT',
url: url,
headers: getBasicAuthHeaders(db),
body: user,
}, opts.ajax);
return ajax(updateOpts);
Expand Down
15 changes: 14 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import urlJoin from 'url-join';
import urlParse from 'url-parse';
import inherits from 'inherits';

import { btoa } from 'pouchdb-binary-utils';

function getBaseUrl(db) {
if (typeof db.getUrl === 'function') { // pouchdb pre-6.0.0
return urlParse(db.getUrl()).origin;
Expand All @@ -26,6 +28,17 @@ function getSessionUrl(db) {
return urlJoin(getBaseUrl(db), '/_session');
}

function getBasicAuthHeaders(db) {
var url = urlParse(db.name);
if (!url.auth) {
return {};
}

var str = url.username + ':' + url.password;
var token = btoa(unescape(encodeURIComponent(str)));
return {Authorization: 'Basic ' + token};
}

function wrapError(callback) {
// provide more helpful error message
return function (err, res) {
Expand All @@ -51,4 +64,4 @@ function AuthError(message) {

inherits(AuthError, Error);

export { AuthError, getConfigUrl, getSessionUrl, getUsersUrl, wrapError };
export { AuthError, getBasicAuthHeaders, getConfigUrl, getSessionUrl, getUsersUrl, wrapError };
8 changes: 5 additions & 3 deletions test/test.issue.109.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ describe('issue-109', function () {
return db.deleteUser('spiderman');
}).then(function () {
return db.deleteAdmin('anna');
}).then(function () {
return db.logOut();
});
});

Expand All @@ -41,9 +43,9 @@ describe('issue-109', function () {
});
});

// Blocked by #109
it.skip('Test admin change user password with basic authentication', function () {
var dbWithBasicAuth = new PouchDB(dbName.replace('http://', 'http://anna:secret@'));
it('Test admin change user password with basic authentication', function () {
var dbNameWithAuth = dbName.replace('http://', 'http://anna:secret@');
var dbWithBasicAuth = new PouchDB(dbNameWithAuth, {skip_setup: true});
return dbWithBasicAuth.changePassword('spiderman', 'will-remember').then(function (res) {
res.ok.should.equal(true);
}).then(function () {
Expand Down

0 comments on commit 31983c2

Please sign in to comment.