Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-10-02 23:52:07 +0400
committerisaacs <i@izs.me>2012-10-02 23:52:07 +0400
commit8085a1675b5c9324f1ac92e4da620f34ae11c0e9 (patch)
tree34221ba9d7bf74a2d5d5b5fdaf0ee9f1dabe57c4 /node_modules
parent362fc6272791b9b7d7976d523e24ee5c40470a9a (diff)
couch-login@0.1.14
Diffstat (limited to 'node_modules')
-rw-r--r--node_modules/couch-login/.npmignore4
-rw-r--r--node_modules/couch-login/LICENSE27
-rw-r--r--node_modules/couch-login/couch-login.js35
-rw-r--r--node_modules/couch-login/package.json4
-rw-r--r--node_modules/couch-login/test/00-setup.js100
-rw-r--r--node_modules/couch-login/test/basic.js4
-rw-r--r--node_modules/couch-login/test/fixtures/_replicator.couchbin0 -> 4194 bytes
-rw-r--r--node_modules/couch-login/test/fixtures/couch.ini24
-rw-r--r--node_modules/couch-login/test/fixtures/registry.couchbin0 -> 24674 bytes
-rw-r--r--node_modules/couch-login/test/registry.js6
-rw-r--r--node_modules/couch-login/test/reset-then-signup.js112
-rw-r--r--node_modules/couch-login/test/zz-teardown.js23
12 files changed, 321 insertions, 18 deletions
diff --git a/node_modules/couch-login/.npmignore b/node_modules/couch-login/.npmignore
new file mode 100644
index 000000000..9ed56e7a5
--- /dev/null
+++ b/node_modules/couch-login/.npmignore
@@ -0,0 +1,4 @@
+test/fixtures/couch.log
+test/fixtures/.delete
+test/fixtures/pid
+test/fixtures/_users.couch
diff --git a/node_modules/couch-login/LICENSE b/node_modules/couch-login/LICENSE
new file mode 100644
index 000000000..0c44ae716
--- /dev/null
+++ b/node_modules/couch-login/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) Isaac Z. Schlueter ("Author")
+All rights reserved.
+
+The BSD License
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/node_modules/couch-login/couch-login.js b/node_modules/couch-login/couch-login.js
index a2b323439..f0b2d4388 100644
--- a/node_modules/couch-login/couch-login.js
+++ b/node_modules/couch-login/couch-login.js
@@ -3,6 +3,7 @@ var request = require('request')
, crypto = require('crypto')
, YEAR = (1000 * 60 * 60 * 24 * 365)
, BASIC = {}
+, assert = require('assert')
module.exports = CouchLogin
@@ -63,6 +64,7 @@ Object.defineProperty(CouchLogin.prototype, 'constructor',
{ value: CouchLogin, enumerable: false })
function decorate (req, res) {
+ assert(this instanceof CouchLogin)
req.couch = res.couch = this
// backed by some sort of set(k,v,cb), get(k,cb) session storage.
@@ -86,10 +88,12 @@ function decorate (req, res) {
}
function anon () {
+ assert(this instanceof CouchLogin)
return new CouchLogin(this.couch, NaN)
}
function makeReq (meth, body, f) { return function madeReq (p, d, cb) {
+ assert(this instanceof CouchLogin)
f = f || (this.token !== this.token)
if (!f && !valid(this.token)) {
// lazily get the token.
@@ -129,19 +133,24 @@ function makeReq (meth, body, f) { return function madeReq (p, d, cb) {
req.proxy = this.proxy
}
+ // we're handling cookies, don't do it for us.
+ req.jar = false
+
request(req, function (er, res, data) {
// update cookie.
if (er || res.statusCode !== 200) return cb(er, res, data)
addToken.call(this, res)
- return cb(er, res, data)
+ return cb.call(this, er, res, data)
}.bind(this))
}}
function login (auth, cb) {
+ assert(this instanceof CouchLogin)
if (this.token === BASIC) {
this.auth = new Buffer(auth.name + ':' + auth.password).toString('base64')
this.name = auth.name
- return process.nextTick(cb, null, { statusCode: 200 }, { ok: true })
+ cb = cb.bind(this, null, { statusCode: 200 }, { ok: true })
+ return process.nextTick(cb)
}
var a = { name: auth.name, password: auth.password }
var req = makeReq('post', true, true)
@@ -150,10 +159,11 @@ function login (auth, cb) {
return cb(er, cr, data)
this.name = auth.name
cb(er, cr, data)
- })
+ }.bind(this))
}
function changePass (auth, cb) {
+ assert(this instanceof CouchLogin)
if (!auth.name || !auth.password) return cb(new Error('invalid auth'))
var u = '/_users/org.couchdb.user:' + auth.name
@@ -181,7 +191,6 @@ function changePass (auth, cb) {
data.date = new Date().toISOString()
this.put(u + '?rev=' + data._rev, data, function (er, res, data) {
- console.error('back from changepass', er, data, this.name)
if (er || res.statusCode >= 400)
return cb(er, res, data)
if (this.name && this.name !== auth.name)
@@ -196,6 +205,7 @@ function changePass (auth, cb) {
//
// WATCH OUT!
function deleteAccount (name, cb) {
+ assert(this instanceof CouchLogin)
var u = '/_users/org.couchdb.user:' + name
this.get(u, thenPut.bind(this))
@@ -216,9 +226,11 @@ function deleteAccount (name, cb) {
function signup (auth, cb) {
- if (this.token && this.token !== BASIC)
+ assert(this instanceof CouchLogin)
+ if (this.token && this.token !== BASIC) {
+
return this.logout(function (er, res, data) {
- if (er || res.statusCode !== 200) {
+ if (er || res && res.statusCode !== 200) {
return cb(er, res, data)
}
@@ -228,6 +240,7 @@ function signup (auth, cb) {
this.signup(auth, cb)
}.bind(this))
+ }
// make a new user record.
var newSalt = crypto.randomBytes(30).toString('hex')
@@ -262,6 +275,7 @@ function signup (auth, cb) {
}
function addToken (res) {
+ assert(this instanceof CouchLogin)
// not doing the whole login session cookie thing.
if (this.token === BASIC)
return
@@ -309,9 +323,11 @@ function addToken (res) {
function logout (cb) {
+ assert(this instanceof CouchLogin)
if (!this.token && this.tokenGet) {
return this.tokenGet(function (er, tok) {
- if (er || !tok) return cb()
+ if (er || !tok)
+ return cb(null, { statusCode: 200 }, {})
this.token = tok
this.logout(cb)
}.bind(this))
@@ -320,7 +336,7 @@ function logout (cb) {
if (!valid(this.token)) {
this.token = null
if (this.tokenDel) this.tokenDel()
- return process.nextTick(cb)
+ return process.nextTick(cb.bind(this, null, { statusCode: 200 }, {}))
}
var h = { cookie: 'AuthSession=' + this.token.AuthSession }
@@ -333,7 +349,8 @@ function logout (cb) {
}
this.token = null
- if (this.tokenDel) this.tokenDel()
+ if (this.tokenDel)
+ this.tokenDel()
cb(er, res, data)
}.bind(this))
}
diff --git a/node_modules/couch-login/package.json b/node_modules/couch-login/package.json
index 9ccd561b5..0e10bd38c 100644
--- a/node_modules/couch-login/package.json
+++ b/node_modules/couch-login/package.json
@@ -6,7 +6,7 @@
},
"name": "couch-login",
"description": "A module for doing logged-in requests to a couchdb server",
- "version": "0.1.12",
+ "version": "0.1.14",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/couch-login.git"
@@ -22,6 +22,6 @@
"tap": "~0.2.4"
},
"readme": "# couch-login\n\nThis module lets you log into couchdb to get a session token, then make\nrequests using that session. It is basically just a thin wrapper around\n[@mikeal's request module](https://github.com/mikeal/request).\n\nThis is handy if you want a user to take actions in a couchdb database\non behalf of a user, without having to store their couchdb username and\npassword anywhere. (You do need to store the AuthSession token\nsomewhere, though.)\n\n## Usage\n\n```javascript\nvar CouchLogin = require('couch-login')\n\n// Nothing about this module is http-server specific of course.\n// You could also use it to do authenticated requests against\n// a couchdb using sessions and storing the token somewhere else.\n\nhttp.createServer(function (req, res) {\n var couch = new CouchLogin('http://my-couch.iriscouch.com:5984/')\n\n // .. look up the token in the user's session or whatever ..\n // Look at couch.decorate(req, res) for more on doing that\n // automatically, below.\n\n if (sessionToken) {\n // this user already logged in.\n couch.token = sessionToken\n\n // now we can do things on their behalf, like:\n // 1. View their session info.\n // like doing request.get({ uri: couch + '/_session', ... })\n // but with the cookie and whatnot\n\n couch.get('/_session', function (er, resp, data) {\n // er = some kind of communication error.\n // resp = response object from the couchdb request.\n // data = parsed JSON response body.\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // now we have the session info, we know who this user is.\n // hitting couchdb for this on every request is kinda costly,\n // so maybe you should store the username wherever you're storing\n // the sessionToken. RedSess is a good util for this, if you're\n // into redis. And if you're not into redis, you're crazy,\n // because it is awesome.\n\n // now let's get the user record.\n // note that this will 404 for anyone other than the user,\n // unless they're a server admin.\n couch.get('/_users/org.couchdb.user:' + data.userCtx.name, etc)\n\n // PUTs and DELETEs will also use their session, of course, so\n // your validate_doc_update's will see their info in userCtx\n })\n\n } else {\n // don't have a sessionToken.\n // get a username and password from the post body or something.\n // maybe redirect to a /login page or something to ask for that.\n var login = { name: name, password: password }\n couch.login(login, function (er, resp, data) {\n // again, er is an error, resp is the response obj, data is the json\n if (er || resp.statusCode !== 200) {\n res.statusCode = resp.statusCode || 403\n return res.end('Invalid login or something')\n }\n\n // the data is something like\n // {\"ok\":true,\"name\":\"testuser\",\"roles\":[]}\n // and couch.token is the token you'll need to save somewhere.\n\n // at this point, you can start making authenticated requests to\n // couchdb, or save data in their session, or do whatever it is\n // that you need to do.\n\n res.statusCode = 200\n res.write(\"Who's got two thumbs and just logged you into couch?\\n\")\n setTimeout(function () {\n res.end(\"THIS GUY!\")\n }, 500)\n })\n }\n})\n```\n\n## Class: CouchLogin\n### new CouchLogin(couchdbUrl, token)\n\nCreate a new CouchLogin object bound to the couchdb url.\n\nIn addition to these, the `get`, `post`, `put`, and `del` methods all\nproxy to the associated method on [request](https://github.com/mikeal/request).\n\nHowever, as you'll note in the example above, only the pathname portion\nof the url is required. Urls will be appended to the couchdb url passed\ninto the constructor.\n\nIf you have to talk to more than one couchdb, then you'll need more than\none CouchLogin object, for somewhat obvious reasons.\n\nAll callbacks get called with the following arguments, which are exactly\nidentical to the arguments passed to a `request` callback.\n\n* `er` {Error | null} Set if a communication error happens.\n* `resp` {HTTP Response} The response from the request to couchdb\n* `data` {Object} The parsed JSON data from couch\n\nIf the token is the string \"anonymous\", then it will not attempt to log\nin before making requests. If the token is not \"anonymous\", then it\nmust be an object with the appropriate fields.\n\n### couch.token\n\n* {Object}\n\nAn object representing the couchdb session token. (Basically just a\ncookie and a timeout.)\n\nIf the token has already timed out, then setting it will have no effect.\n\n### couch.tokenSet\n\nIf set, this method is called whenever the token is saved.\n\nFor example, you could assign a function to this method to save the\ntoken into a redis session, a cookie, or in some other database.\n\nTakes a callback which should be called when the token is saved.\n\n### couch.tokenGet\n\nIf set, this method is called to look up the token on demand.\n\nThe inverse of couch.tokenSet. Takes a callback which is called with\nthe `cb(er || null, token)`.\n\n### couch.tokenDel\n\nIf set, this method is called to delete the token when it should be\ndiscarded.\n\nRelated to tokenGet and tokenSet. Takes a callback which should be\ncalled when the token is deleted.\n\n### couch.anonymous()\n\nReturn a new CouchLogin object that points at the same couchdb server,\nbut doesn't try to log in before making requests.\n\nThis is handy for situations where the user is not logged in at the\nmoment, but a request needs to be made anyway, and does not require\nauthorization.\n\n### couch.login(auth, callback)\n\n* `auth` {Object} The login details\n * `name` {String}\n * `password` {String}\n* `callback` {Function}\n\nWhen the callback is called, the `couch.token` will already have been\nset (assuming it worked!), so subsequent requests will be done as that\nuser.\n\n### couch.get(path, callback)\n\nGET the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.del(path, callback)\n\nDELETE the supplied path from the couchdb using the credentials on the\ntoken.\n\nFails if the token is invalid or expired.\n\n### couch.post(path, data, callback)\n\nPOST the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.put(path, data, callback)\n\nPUT the data to the supplied path in the couchdb, using the credentials\non the token.\n\nFails if the token is invalid or expired.\n\n### couch.changePass(newAuth, callback)\n\nMust already be logged in. Updates the `_users` document with new salt\nand hash, and re-logs in with the new credentials. Callback is called\nwith the same arguments as login, or the first step of the process that\nfailed.\n\n### couch.signup(userData, callback)\n\nCreate a new user account. The userData must contain at least a `name`\nand `password` field. Any additional data will be copied to the user\nrecord. The `_id`, `name`, `roles`, `type`, `password_sha`, `salt`, and\n`date` fields are generated.\n\nAlso signs in as the newly created user, on successful account creation.\n\n### couch.deleteAccount(name, callback)\n\nDeletes a user account. If not logged in as the user, or a server\nadmin, then the request will fail.\n\nNote that this immediately invalidates any session tokens for the\ndeleted user account. If you are deleting the user's record, then you\nought to follow this with `couch.logout(callback)` so that it won't try\nto re-use the invalid session.\n\n### couch.logout(callback)\n\nDelete the session out of couchdb. This makes the token permanently\ninvalid, and deletes it.\n\n### couch.decorate(req, res)\n\nSet up `req.couch` and `res.couch` as references to this couch login\ninstance.\n\nAdditionall, if `req.session` or `res.session` is set, then it'll call\n`session.get('couch_token', cb)` as the tokenGet method,\n`session.set('couch_token', token, cb)` as the tokenSet method, and\n`session.del('couch_token', cb)` as the tokenDel method.\n\nThis works really nice with\n[RedSess](https://github.com/isaacs/redsess).\n",
- "_id": "couch-login@0.1.12",
+ "_id": "couch-login@0.1.14",
"_from": "couch-login@~0.1.9"
}
diff --git a/node_modules/couch-login/test/00-setup.js b/node_modules/couch-login/test/00-setup.js
new file mode 100644
index 000000000..d5dcc190d
--- /dev/null
+++ b/node_modules/couch-login/test/00-setup.js
@@ -0,0 +1,100 @@
+// start the couchdb spinning as a detached child process.
+// the zz-teardown.js test kills it.
+//
+// localhost:15985 ==> couchdb
+// 127.0.0.1:15985 ==> npm registry
+
+var spawn = require('child_process').spawn
+var test = require('tap').test
+var path = require('path')
+var fs = require('fs')
+var request = require('request')
+
+// run with the cwd of the main program.
+var cwd = path.dirname(__dirname)
+
+var conf = path.resolve(__dirname, 'fixtures', 'couch.ini')
+var pidfile = path.resolve(__dirname, 'fixtures', 'pid')
+var logfile = path.resolve(__dirname, 'fixtures', 'couch.log')
+var started = /Apache CouchDB has started on http:\/\/127\.0\.0\.1:15985\/\n$/
+
+test('start couch as a zombie child', function (t) {
+ var fd = fs.openSync(pidfile, 'wx')
+
+ try { fs.unlinkSync(logfile) } catch (er) {}
+
+ var child = spawn('couchdb', ['-a', conf], {
+ detached: true,
+ stdio: 'ignore',
+ cwd: cwd
+ })
+ child.unref()
+ t.ok(child.pid)
+ fs.writeSync(fd, child.pid + '\n')
+ fs.closeSync(fd)
+
+ // wait for it to create a log, give it 5 seconds
+ var start = Date.now()
+ fs.readFile(logfile, function R (er, log) {
+ log = log ? log.toString() : ''
+ if (!er && !log.match(started))
+ er = new Error('not started yet')
+ if (er) {
+ if (Date.now() - start < 5000)
+ return setTimeout(function () {
+ fs.readFile(logfile, R)
+ }, 100)
+ else
+ throw er
+ }
+ t.pass('relax')
+ t.end()
+ })
+})
+
+// set up the testuser account that we'll be using everywhere.
+// first delete any existing one, so that we don't end up with
+// some newer copy taking over.
+test('create testuser', function (t) {
+ var u = 'http://admin:admin@localhost:15985/_users/org.couchdb.user:testuser'
+ var rev
+
+ request.get({ url: u, json: true }, function (er, res, data) {
+ if (er)
+ throw er
+ rev = data._rev
+ if (res.statusCode === 404)
+ put()
+ else
+ del()
+ })
+
+ function del () {
+ request.del(u + '?rev=' + rev, function (er, res, data) {
+ if (er)
+ throw er
+ put()
+ })
+ }
+
+ function put () {
+ request.put({
+ url: u,
+ body: {
+ _id: 'org.couchdb.user:testuser',
+ name: 'testuser',
+ roles: [],
+ type: 'user',
+ password_sha: 'e23952b517695e6bb72ecf060e10bf1b35bf7e0b',
+ salt: '83695c9b64d3b48b94c9dda0cd691e72',
+ date: '2012-09-26T16:49:30.175Z'
+ },
+ json: true
+ }, function (er, res, data) {
+ if (er)
+ throw er
+ t.ok(data.ok, 'user created')
+ t.end()
+ })
+ }
+})
diff --git a/node_modules/couch-login/test/basic.js b/node_modules/couch-login/test/basic.js
index 660a24a0f..9e222e143 100644
--- a/node_modules/couch-login/test/basic.js
+++ b/node_modules/couch-login/test/basic.js
@@ -1,11 +1,9 @@
var tap = require('tap')
, CouchLogin = require('../couch-login.js')
-// Yeah, go ahead and abuse my staging server, whatevs.
-
var auth = { name: 'testuser', password: 'test' }
, newAuth = { name: 'testuser', password: 'asdfasdf' }
-, couch = new CouchLogin('https://isaacs-staging.iriscouch.com/')
+, couch = new CouchLogin('http://localhost:15985/')
, u = '/_users/org.couchdb.user:' + auth.name
, userRecordMarker
diff --git a/node_modules/couch-login/test/fixtures/_replicator.couch b/node_modules/couch-login/test/fixtures/_replicator.couch
new file mode 100644
index 000000000..b8dbbebd0
--- /dev/null
+++ b/node_modules/couch-login/test/fixtures/_replicator.couch
Binary files differ
diff --git a/node_modules/couch-login/test/fixtures/couch.ini b/node_modules/couch-login/test/fixtures/couch.ini
new file mode 100644
index 000000000..4579a2f02
--- /dev/null
+++ b/node_modules/couch-login/test/fixtures/couch.ini
@@ -0,0 +1,24 @@
+[couchdb]
+database_dir = test/fixtures
+view_index_dir = test/fixtures
+
+[httpd]
+port = 15985
+bind_address = 127.0.0.1
+secure_rewrites = false
+allow_jsonp = true
+config_whitelist = [{uuids,algorithm},{vhosts,"*"},{admins,"*"},{log,level},{httpd,allow_jsonp},{httpd,secure_rewrites},{httpd,mobile_futon},{httpd,sammy_futon},{httpd,cors},{httpd,x_forwarded_host},{httpd,'WWW-Authenticate'},{cors,"*"},{compactions,"*"},{replicator,db},{attachments,compression_level},{attachments,compressible_types},{couch_httpd_auth,authentication_db},{couch_httpd_auth,allow_persistent_cookies},{couch_httpd_auth,authentication_redirect},{couch_httpd_auth,require_valid_user},{couch_httpd_auth,timeout},{couch_httpd_auth,secret},{couchdb,os_process_timeout},{query_server_config,reduce_limit},{couch_httpd_oauth,"*"},{oauth_token_users,"*"},{oauth_token_secrets,"*"},{oauth_consumer_secrets,"*"},{browserid,enabled},{browserid,hash_secret},{fb,"*"}]
+
+[log]
+file = test/fixtures/couch.log
+
+[admins]
+admin = -hashed-b933598b0ade0e4c2a258d53c95990d5939461dd,a44895e5740b79d14b392ada8021d31d
+
+[couch_httpd_auth]
+secret = cafebad000deadbeef00000019790701
+timeout = 36000
+allow_persistent_cookies = true
+
+[vhosts]
+127.0.0.1:15985 = /registry/_design/ghost/_rewrite
diff --git a/node_modules/couch-login/test/fixtures/registry.couch b/node_modules/couch-login/test/fixtures/registry.couch
new file mode 100644
index 000000000..5806317db
--- /dev/null
+++ b/node_modules/couch-login/test/fixtures/registry.couch
Binary files differ
diff --git a/node_modules/couch-login/test/registry.js b/node_modules/couch-login/test/registry.js
index 56a21f6b1..d99d9f4f6 100644
--- a/node_modules/couch-login/test/registry.js
+++ b/node_modules/couch-login/test/registry.js
@@ -3,11 +3,9 @@
var tap = require('tap')
, CouchLogin = require('../couch-login.js')
-// Yeah, go ahead and abuse my staging server, whatevs.
-
var auth = { name: 'testuser', password: 'test' }
, newAuth = { name: 'testuser', password: 'asdfasdf' }
-, couch = new CouchLogin('https://staging.npmjs.org/')
+, couch = new CouchLogin('http://127.0.0.1:15985/')
, u = '/_users/org.couchdb.user:' + auth.name
, userRecordMarker
@@ -204,7 +202,7 @@ tap.test('change password back easy', function (t) {
t.ok(data, 'data')
t.ok(couch.token, 'token')
t.equal(data.testingCouchLogin, undefined)
- t.equal(data.mustChangePass, false)
+ t.notOk(data.mustChangePass)
userRecord = data
t.end()
})
diff --git a/node_modules/couch-login/test/reset-then-signup.js b/node_modules/couch-login/test/reset-then-signup.js
new file mode 100644
index 000000000..77a5ceda9
--- /dev/null
+++ b/node_modules/couch-login/test/reset-then-signup.js
@@ -0,0 +1,112 @@
+var test = require('tap').test
+var CouchLogin = require('../couch-login.js')
+
+var auth = { name: 'testuser', password: 'test' }
+, newAuth = { name: 'testuser', password: 'asdf', mustChangePass: true }
+, db = 'http://localhost:15985/'
+, couch = new CouchLogin(db)
+, u = '/_users/org.couchdb.user:' + auth.name
+, admin = { name: 'admin', password: 'admin' }
+, newUser = { name: 'testuser', password: 'test' }
+, newUserCouch = null
+, authToken = null
+
+newUser.name += Math.floor(Math.random() * 1E9)
+
+var okGlobal = Object.keys(global)
+
+var adminCouch = new CouchLogin(db, 'basic')
+
+function okStatus (t, res) {
+ var x = { found: res.statusCode, wanted: 'around 200' }
+ var r = res.statusCode
+ x.ok = (r >= 200 && r < 300)
+ return t.ok(x.ok, 'Status code should be 200-ish', x)
+}
+
+test('adminCouch login', function (t) {
+ t.deepEqual(Object.keys(global), okGlobal)
+ console.error('adminCouch login')
+ adminCouch.login(admin, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ t.ok(data)
+ t.end()
+ })
+})
+
+test('get the user data as admin', function (t) {
+ t.deepEqual(Object.keys(global), okGlobal)
+ console.error('2')
+ adminCouch.get(u, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ t.ok(data)
+ t.end()
+ })
+})
+
+test('admin user changes the password for non-admin user', function (t) {
+ console.error(3)
+ t.deepEqual(Object.keys(global), okGlobal)
+ adminCouch.changePass(newAuth, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ t.ok(data)
+ t.end()
+ })
+})
+
+test('testuser logs in', function (t) {
+ console.error(4)
+ t.deepEqual(Object.keys(global), okGlobal)
+ couch.login(newAuth, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ t.deepEqual(data, { ok: true, name: 'testuser', roles: [] })
+ authToken = couch.token
+ t.end()
+ })
+})
+
+// test('testuser changes password', function (t) {
+// couch = new CouchLogin(db)
+// couch.token = authToken
+// couch.changePass(auth, function (er, res, data) {
+// if (er)
+// throw er
+// okStatus(t, res)
+// console.error(data)
+// t.ok(data)
+// t.end()
+// })
+// })
+
+test('new user signup', function (t) {
+ t.deepEqual(Object.keys(global), okGlobal)
+ newUserCouch = new CouchLogin(db)
+ newUserCouch.signup(newUser, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ console.error(data)
+ t.ok(data)
+ t.end()
+ })
+})
+
+test('delete newUser account', function (t) {
+ t.deepEqual(Object.keys(global), okGlobal)
+ newUserCouch.deleteAccount(newUser.name, function (er, res, data) {
+ if (er)
+ throw er
+ okStatus(t, res)
+ console.error(data)
+ t.ok(data)
+ t.end()
+ })
+})
diff --git a/node_modules/couch-login/test/zz-teardown.js b/node_modules/couch-login/test/zz-teardown.js
new file mode 100644
index 000000000..a66e24a10
--- /dev/null
+++ b/node_modules/couch-login/test/zz-teardown.js
@@ -0,0 +1,23 @@
+// kill the couchdb process that's running as a detached child process
+// started by the 00-setup.js test
+
+var fs = require('fs')
+var test = require('tap').test
+var path = require('path')
+var pidfile = path.resolve(__dirname, 'fixtures', 'pid')
+var _users = path.resolve(__dirname, 'fixtures', '_users.couch')
+
+test('kill all the users', function (t) {
+ fs.unlinkSync(_users)
+ t.pass('_users db deleted')
+ t.end()
+})
+
+test('craigslist (well, how do you get rid of YOUR couches?)', function (t) {
+ var pid = fs.readFileSync(pidfile)
+ fs.unlinkSync(pidfile)
+ process.kill(pid)
+ t.pass('couch is no more')
+ t.end()
+})
+