Skip to content

Commit cb8991d

Browse files
committed
feat(admins): add signUpAdmin and deleteAdmin
1 parent 1bcbe6c commit cb8991d

File tree

4 files changed

+184
-1
lines changed

4 files changed

+184
-1
lines changed

src/admins.js

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { AuthError, getBaseUrl, getConfigUrl, wrapError } from './utils';
2+
3+
import ajaxCore from 'pouchdb-ajax';
4+
import { assign, toPromise } from 'pouchdb-utils';
5+
6+
var getMembership = toPromise(function (opts, callback) {
7+
var db = this;
8+
if (typeof callback === 'undefined') {
9+
callback = opts;
10+
opts = {};
11+
}
12+
13+
var url = getBaseUrl(db) + '/_membership';
14+
var ajaxOpts = assign({
15+
method: 'GET',
16+
url: url,
17+
}, opts.ajax || {});
18+
ajaxCore(ajaxOpts, wrapError(callback));
19+
});
20+
21+
var signUpAdmin = toPromise(function (username, password, opts, callback) {
22+
var db = this;
23+
if (typeof callback === 'undefined') {
24+
callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
25+
username : password) : opts;
26+
opts = {};
27+
}
28+
if (['http', 'https'].indexOf(db.type()) === -1) {
29+
return callback(new AuthError('This plugin only works for the http/https adapter. ' +
30+
'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
31+
} else if (!username) {
32+
return callback(new AuthError('You must provide a username'));
33+
} else if (!password) {
34+
return callback(new AuthError('You must provide a password'));
35+
}
36+
37+
db.getMembership(opts, function (error, membership) {
38+
var nodeName;
39+
if (error) {
40+
if (error.error !== 'illegal_database_name') {
41+
return callback(error);
42+
} else {
43+
// Some couchdb-1.x-like server
44+
nodeName = undefined;
45+
}
46+
} else {
47+
// Some couchdb-2.x-like server
48+
nodeName = membership.all_nodes[0];
49+
}
50+
51+
var configUrl = getConfigUrl(db, nodeName);
52+
var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
53+
var ajaxOpts = assign({
54+
method: 'PUT',
55+
url: url,
56+
processData: false,
57+
body: '"' + password + '"',
58+
}, opts.ajax || {});
59+
ajaxCore(ajaxOpts, wrapError(callback));
60+
});
61+
});
62+
63+
var deleteAdmin = toPromise(function (username, opts, callback) {
64+
var db = this;
65+
if (typeof callback === 'undefined') {
66+
callback = typeof opts === 'undefined' ? username : opts;
67+
opts = {};
68+
}
69+
if (['http', 'https'].indexOf(db.type()) === -1) {
70+
return callback(new AuthError('This plugin only works for the http/https adapter. ' +
71+
'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
72+
} else if (!username) {
73+
return callback(new AuthError('You must provide a username'));
74+
}
75+
76+
db.getMembership(opts, function (error, membership) {
77+
var nodeName;
78+
if (error) {
79+
if (error.error !== 'illegal_database_name') {
80+
return callback(error);
81+
} else {
82+
// Some couchdb-1.x-like server
83+
nodeName = undefined;
84+
}
85+
} else {
86+
// Some couchdb-2.x-like server
87+
nodeName = membership.all_nodes[0];
88+
}
89+
90+
var configUrl = getConfigUrl(db, nodeName);
91+
var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
92+
var ajaxOpts = assign({
93+
method: 'DELETE',
94+
url: url,
95+
processData: false,
96+
}, opts.ajax || {});
97+
ajaxCore(ajaxOpts, wrapError(callback));
98+
});
99+
});
100+
101+
export { getMembership, deleteAdmin, signUpAdmin };

src/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
import { deleteAdmin, getMembership, signUpAdmin } from "./admins";
34
import { getSession, logIn, logOut } from "./authentication";
45
import {
56
changePassword,
@@ -19,6 +20,10 @@ plugin.logout = logOut;
1920
plugin.logOut = logOut;
2021
plugin.getSession = getSession;
2122

23+
plugin.getMembership = getMembership;
24+
plugin.signUpAdmin = signUpAdmin;
25+
plugin.deleteAdmin = deleteAdmin;
26+
2227
plugin.getUsersDatabaseUrl = getUsersDatabaseUrl;
2328
plugin.signup = signUp;
2429
plugin.signUp = signUp;

src/utils.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ function getBaseUrl(db) {
1414
}
1515
}
1616

17+
function getConfigUrl(db, nodeName) {
18+
return urlJoin(getBaseUrl(db), (nodeName ? '/_node/' + nodeName : '') + '/_config');
19+
}
20+
1721
function getUsersUrl(db) {
1822
return urlJoin(getBaseUrl(db), '/_users');
1923
}
@@ -47,4 +51,4 @@ function AuthError(message) {
4751

4852
inherits(AuthError, Error);
4953

50-
export { AuthError, getSessionUrl, getUsersUrl, wrapError };
54+
export { AuthError, getBaseUrl, getConfigUrl, getSessionUrl, getUsersUrl, wrapError };

test/test.admins.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict';
2+
3+
var PouchDB = require('pouchdb-memory');
4+
var Authentication = require('../lib');
5+
PouchDB.plugin(Authentication);
6+
7+
var utils = require('./test-utils');
8+
var chai = require('chai');
9+
var should = chai.should();
10+
11+
describe('admins', function () {
12+
13+
var dbHost = 'http://localhost:5984';
14+
var dbName = dbHost + '/testdb';
15+
16+
var db;
17+
18+
beforeEach(function () {
19+
db = new PouchDB(dbName);
20+
return utils.ensureUsersDatabaseExists(db);
21+
});
22+
23+
afterEach(function () {
24+
return db.logOut().then(function () {
25+
return db.destroy();
26+
});
27+
});
28+
29+
it('Create and delete admin', function () {
30+
return testCreateDeleteAdmin({});
31+
});
32+
33+
it('Create and delete admin with config url', function () {
34+
return db.getMembership().then(function (membership) {
35+
// Some couchdb-2.x-like server
36+
return membership.all_nodes[0];
37+
}).catch(function () {
38+
// Some couchdb-1.x-like server
39+
return undefined;
40+
}).then(function (nodeName) {
41+
var opts = {
42+
configUrl: dbHost + (nodeName ? '/_node/' + nodeName : '') + '/_config',
43+
};
44+
45+
return testCreateDeleteAdmin(opts);
46+
});
47+
});
48+
49+
function testCreateDeleteAdmin(opts) {
50+
return db.signUpAdmin('anna', 'secret', opts).then(function (res) {
51+
should.exist(res);
52+
53+
return db.logIn('anna', 'secret').then(function (res) {
54+
res.ok.should.equal(true);
55+
56+
return db.deleteAdmin('anna', opts).then(function (res) {
57+
should.exist(res);
58+
59+
return db.logOut().then(function () {
60+
61+
return db.logIn('anna', 'secret').then(function () {
62+
should.fail('shouldn\'t have worked');
63+
}, function (err) {
64+
should.exist(err);
65+
err.error.should.equal('unauthorized');
66+
err.reason.should.equal('Name or password is incorrect.');
67+
});
68+
});
69+
});
70+
});
71+
});
72+
}
73+
});

0 commit comments

Comments
 (0)