diff --git a/node_modules/http-errors/node_modules/inherits/package.json b/node_modules/http-errors/node_modules/inherits/package.json index facd5fdf1..e685e9fb9 100644 --- a/node_modules/http-errors/node_modules/inherits/package.json +++ b/node_modules/http-errors/node_modules/inherits/package.json @@ -30,6 +30,6 @@ "homepage": "https://github.com/isaacs/inherits", "_id": "inherits@2.0.1", "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", - "_from": "inherits@2", + "_from": "inherits@~2.0.1", "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } diff --git a/node_modules/http-errors/node_modules/statuses/README.md b/node_modules/http-errors/node_modules/statuses/README.md index 2a98a5ac8..cc12794bf 100644 --- a/node_modules/http-errors/node_modules/statuses/README.md +++ b/node_modules/http-errors/node_modules/statuses/README.md @@ -86,6 +86,22 @@ taken from `require('http').STATUS_CODES`. This is saved so that codes are consistent even in older node.js versions. For example, `308` will be added in v0.12. +## Adding Status Codes + +The status codes are primarily sourced from http://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv. +Additionally, custom codes are added from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes. +These are added manually in the `lib/*.json` files. +If you would like to add a status code, add it to the appropriate JSON file. + +To rebuild `codes.json`, run the following: + +```bash +# update src/iana.json +npm run update +# build codes.json +npm run build +``` + [npm-image]: https://img.shields.io/npm/v/statuses.svg?style=flat [npm-url]: https://npmjs.org/package/statuses [node-version-image]: http://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat diff --git a/node_modules/http-errors/node_modules/statuses/codes.json b/node_modules/http-errors/node_modules/statuses/codes.json index a18f08a63..b34a6d7fd 100644 --- a/node_modules/http-errors/node_modules/statuses/codes.json +++ b/node_modules/http-errors/node_modules/statuses/codes.json @@ -1 +1,64 @@ -{"100":"Continue","101":"Switching Protocols","102":"Processing","200":"OK","201":"Created","202":"Accepted","203":"Non-Authoritative Information","204":"No Content","205":"Reset Content","206":"Partial Content","207":"Multi-Status","300":"Multiple Choices","301":"Moved Permanently","302":"Moved Temporarily","303":"See Other","304":"Not Modified","305":"Use Proxy","307":"Temporary Redirect","308":"Permanent Redirect","400":"Bad Request","401":"Unauthorized","402":"Payment Required","403":"Forbidden","404":"Not Found","405":"Method Not Allowed","406":"Not Acceptable","407":"Proxy Authentication Required","408":"Request Time-out","409":"Conflict","410":"Gone","411":"Length Required","412":"Precondition Failed","413":"Request Entity Too Large","414":"Request-URI Too Large","415":"Unsupported Media Type","416":"Requested Range Not Satisfiable","417":"Expectation Failed","418":"I'm a teapot","422":"Unprocessable Entity","423":"Locked","424":"Failed Dependency","425":"Unordered Collection","426":"Upgrade Required","428":"Precondition Required","429":"Too Many Requests","431":"Request Header Fields Too Large","500":"Internal Server Error","501":"Not Implemented","502":"Bad Gateway","503":"Service Unavailable","504":"Gateway Time-out","505":"HTTP Version Not Supported","506":"Variant Also Negotiates","507":"Insufficient Storage","509":"Bandwidth Limit Exceeded","510":"Not Extended","511":"Network Authentication Required"} \ No newline at end of file +{ + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "306": "(Unused)", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a teapot", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Unordered Collection", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required" +} \ No newline at end of file diff --git a/node_modules/http-errors/node_modules/statuses/index.js b/node_modules/http-errors/node_modules/statuses/index.js index 5521e897d..b06182d8b 100644 --- a/node_modules/http-errors/node_modules/statuses/index.js +++ b/node_modules/http-errors/node_modules/statuses/index.js @@ -1,5 +1,5 @@ -var codes = require('./codes'); +var codes = require('./codes.json'); module.exports = status; diff --git a/node_modules/http-errors/node_modules/statuses/package.json b/node_modules/http-errors/node_modules/statuses/package.json index d1d8f26d1..af1327834 100644 --- a/node_modules/http-errors/node_modules/statuses/package.json +++ b/node_modules/http-errors/node_modules/statuses/package.json @@ -1,7 +1,7 @@ { "name": "statuses", "description": "HTTP status utility", - "version": "1.1.1", + "version": "1.2.0", "author": { "name": "Jonathan Ong", "email": "me@jongleberry.com", @@ -23,23 +23,27 @@ "LICENSE" ], "devDependencies": { + "csv-parse": "0.0.6", + "istanbul": "0", "mocha": "1", - "istanbul": "0" + "request": "^2.44.0", + "stream-to-array": "^2.0.2" }, "scripts": { - "update": "node update.js", + "build": "node scripts/build.js", + "update": "node scripts/update.js", "test": "mocha --reporter spec --bail --check-leaks", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks" }, - "readme": "# Statuses\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nHTTP status utility for node.\n\n## API\n\n```js\nvar status = require('statuses');\n```\n\n### var code = status(Integer || String)\n\nIf `Integer` or `String` is a valid HTTP code or status message, then the appropriate `code` will be returned. Otherwise, an error will be thrown.\n\n```js\nstatus(403) // => 403\nstatus('403') // => 403\nstatus('forbidden') // => 403\nstatus('Forbidden') // => 403\nstatus(306) // throws, as it's not supported by node.js\n```\n\n### status.codes\n\nReturns an array of all the status codes as `Integer`s.\n\n### var msg = status[code]\n\nMap of `code` to `status message`. `undefined` for invalid `code`s.\n\n```js\nstatus[404] // => 'Not Found'\n```\n\n### var code = status[msg]\n\nMap of `status message` to `code`. `msg` can either be title-cased or lower-cased. `undefined` for invalid `status message`s.\n\n```js\nstatus['not found'] // => 404\nstatus['Not Found'] // => 404\n```\n\n### status.redirect[code]\n\nReturns `true` if a status code is a valid redirect status.\n\n```js\nstatus.redirect[200] // => undefined\nstatus.redirect[301] // => true\n```\n\n### status.empty[code]\n\nReturns `true` if a status code expects an empty body.\n\n```js\nstatus.empty[200] // => undefined\nstatus.empty[204] // => true\nstatus.empty[304] // => true\n```\n\n### status.retry[code]\n\nReturns `true` if you should retry the rest.\n\n```js\nstatus.retry[501] // => undefined\nstatus.retry[503] // => true\n```\n\n### statuses/codes.json\n\n```js\nvar codes = require('statuses/codes.json');\n```\n\nThis is a JSON file of the status codes\ntaken from `require('http').STATUS_CODES`.\nThis is saved so that codes are consistent even in older node.js versions.\nFor example, `308` will be added in v0.12.\n\n[npm-image]: https://img.shields.io/npm/v/statuses.svg?style=flat\n[npm-url]: https://npmjs.org/package/statuses\n[node-version-image]: http://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/statuses.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/statuses\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/statuses.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/statuses?branch=master\n[downloads-image]: http://img.shields.io/npm/dm/statuses.svg?style=flat\n[downloads-url]: https://npmjs.org/package/statuses\n", + "readme": "# Statuses\n\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node.js Version][node-version-image]][node-version-url]\n[![Build Status][travis-image]][travis-url]\n[![Test Coverage][coveralls-image]][coveralls-url]\n\nHTTP status utility for node.\n\n## API\n\n```js\nvar status = require('statuses');\n```\n\n### var code = status(Integer || String)\n\nIf `Integer` or `String` is a valid HTTP code or status message, then the appropriate `code` will be returned. Otherwise, an error will be thrown.\n\n```js\nstatus(403) // => 403\nstatus('403') // => 403\nstatus('forbidden') // => 403\nstatus('Forbidden') // => 403\nstatus(306) // throws, as it's not supported by node.js\n```\n\n### status.codes\n\nReturns an array of all the status codes as `Integer`s.\n\n### var msg = status[code]\n\nMap of `code` to `status message`. `undefined` for invalid `code`s.\n\n```js\nstatus[404] // => 'Not Found'\n```\n\n### var code = status[msg]\n\nMap of `status message` to `code`. `msg` can either be title-cased or lower-cased. `undefined` for invalid `status message`s.\n\n```js\nstatus['not found'] // => 404\nstatus['Not Found'] // => 404\n```\n\n### status.redirect[code]\n\nReturns `true` if a status code is a valid redirect status.\n\n```js\nstatus.redirect[200] // => undefined\nstatus.redirect[301] // => true\n```\n\n### status.empty[code]\n\nReturns `true` if a status code expects an empty body.\n\n```js\nstatus.empty[200] // => undefined\nstatus.empty[204] // => true\nstatus.empty[304] // => true\n```\n\n### status.retry[code]\n\nReturns `true` if you should retry the rest.\n\n```js\nstatus.retry[501] // => undefined\nstatus.retry[503] // => true\n```\n\n### statuses/codes.json\n\n```js\nvar codes = require('statuses/codes.json');\n```\n\nThis is a JSON file of the status codes\ntaken from `require('http').STATUS_CODES`.\nThis is saved so that codes are consistent even in older node.js versions.\nFor example, `308` will be added in v0.12.\n\n## Adding Status Codes\n\nThe status codes are primarily sourced from http://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv.\nAdditionally, custom codes are added from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes.\nThese are added manually in the `lib/*.json` files.\nIf you would like to add a status code, add it to the appropriate JSON file.\n\nTo rebuild `codes.json`, run the following:\n\n```bash\n# update src/iana.json\nnpm run update\n# build codes.json\nnpm run build\n```\n\n[npm-image]: https://img.shields.io/npm/v/statuses.svg?style=flat\n[npm-url]: https://npmjs.org/package/statuses\n[node-version-image]: http://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat\n[node-version-url]: http://nodejs.org/download/\n[travis-image]: https://img.shields.io/travis/jshttp/statuses.svg?style=flat\n[travis-url]: https://travis-ci.org/jshttp/statuses\n[coveralls-image]: https://img.shields.io/coveralls/jshttp/statuses.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/jshttp/statuses?branch=master\n[downloads-image]: http://img.shields.io/npm/dm/statuses.svg?style=flat\n[downloads-url]: https://npmjs.org/package/statuses\n", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/jshttp/statuses/issues" }, "homepage": "https://github.com/jshttp/statuses", - "_id": "statuses@1.1.1", - "_shasum": "10d1811e1bd3182ea3f566bf6b4745cf8edee6cc", - "_from": "statuses@~1.1.0", - "_resolved": "https://registry.npmjs.org/statuses/-/statuses-1.1.1.tgz" + "_id": "statuses@1.2.0", + "_shasum": "4445790d65bec29184f50d54810f67e290c1679e", + "_from": "statuses@1", + "_resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.0.tgz" } diff --git a/node_modules/http-errors/package.json b/node_modules/http-errors/package.json index 315c0ff18..6fd3186cf 100644 --- a/node_modules/http-errors/package.json +++ b/node_modules/http-errors/package.json @@ -1,7 +1,7 @@ { "name": "http-errors", "description": "Create HTTP error objects", - "version": "1.2.4", + "version": "1.2.5", "author": { "name": "Jonathan Ong", "email": "me@jongleberry.com", @@ -14,7 +14,7 @@ }, "dependencies": { "inherits": "~2.0.1", - "statuses": "~1.1.0" + "statuses": "1" }, "devDependencies": { "istanbul": "0", @@ -42,8 +42,8 @@ "url": "https://github.com/jshttp/http-errors/issues" }, "homepage": "https://github.com/jshttp/http-errors", - "_id": "http-errors@1.2.4", - "_shasum": "5d7d6d2d27b1917777ad1869bab742b6c53699d2", + "_id": "http-errors@1.2.5", + "_shasum": "61da92170b47c12bd11083653e9ed44a9b7abe92", "_from": "http-errors@~1.2.0", - "_resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.2.4.tgz" + "_resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.2.5.tgz" } diff --git a/node_modules/sinopia-htpasswd/index.js b/node_modules/sinopia-htpasswd/index.js index eb52c7f54..bc64dac11 100644 --- a/node_modules/sinopia-htpasswd/index.js +++ b/node_modules/sinopia-htpasswd/index.js @@ -18,11 +18,15 @@ function HTPasswd(config, stuff) { self._sinopia_config = stuff.config // all this "sinopia_config" stuff is for b/w compatibility only - self._maxusers = self._config.max_users || self._sinopia_config.max_users + self._maxusers = self._config.max_users + if (self._maxusers == null) self._maxusers = self._sinopia_config.max_users + // set maxusers to Infinity if not specified + if (self._maxusers == null) self._maxusers = Infinity self._last_time = null - var file = self._config.file || self._sinopia_config.users_file - if (!file) throw new Error('should specify "file" in config') + var file = self._config.file + if (file == null) file = self._sinopia_config.users_file + if (file == null) throw new Error('should specify "file" in config') self._path = Path.resolve(Path.dirname(self._sinopia_config.self_path), file) return self } @@ -99,10 +103,17 @@ HTPasswd.prototype.adduser = function(user, password, real_cb) { }) } -HTPasswd.prototype._reload = function(callback) { +HTPasswd.prototype._reload = function(_callback) { var self = this fs.open(self._path, 'r', function(err, fd) { + function callback(err) { + if (!fd) return _callback(err) + fs.close(fd, function(err2) { + _callback(err || err2) + }) + } + if (err) return callback(err) fs.fstat(fd, function(err, st) { @@ -111,15 +122,16 @@ HTPasswd.prototype._reload = function(callback) { self._last_time = st.mtime var buffer = new Buffer(st.size) - fs.read(fd, buffer, 0, st.size, null, function(err, bytesRead, buffer) { + if (st.size === 0) return onRead(null, 0, buffer) + fs.read(fd, buffer, 0, st.size, null, onRead) + + function onRead(err, bytesRead, buffer) { if (err) return callback(err) if (bytesRead != st.size) return callback(new Error('st.size != bytesRead')) self._users = utils.parse_htpasswd(buffer.toString('utf8')) - fs.close(fd, function() { - callback() - }) - }) + callback() + } }) }) } diff --git a/node_modules/sinopia-htpasswd/package.json b/node_modules/sinopia-htpasswd/package.json index d2af607ee..adf168e78 100644 --- a/node_modules/sinopia-htpasswd/package.json +++ b/node_modules/sinopia-htpasswd/package.json @@ -1,6 +1,6 @@ { "name" : "sinopia-htpasswd", - "version" : "0.4.3", + "version" : "0.4.4", "description" : "auth plugin for sinopia supporting htpasswd format", "author" : { "name": "Alex Kocharin" @@ -32,8 +32,7 @@ "crypt3": ">=0.1.5 <1.0.0-0", "fs-ext": "*" }, - "_id" : "sinopia-htpasswd@0.4.3", - "_shasum" : "f69cbfe9bd347359a0ed591f66f08a60cc4ee982", - "_from" : "sinopia-htpasswd@>= 0.4.3", - "_resolved" : "https://registry.npmjs.org/sinopia-htpasswd/-/sinopia-htpasswd-0.4.3.tgz" + "_id" : "sinopia-htpasswd@0.4.4", + "_shasum" : "f4b3f4da2b7869fcd1e2a631aa7eb26a380a560d", + "_from" : "sinopia-htpasswd@>= 0.4.3" } diff --git a/node_modules/sinopia-htpasswd/tests/acceptance.js b/node_modules/sinopia-htpasswd/tests/acceptance.js index 6a2f4eef6..5bd239ab6 100644 --- a/node_modules/sinopia-htpasswd/tests/acceptance.js +++ b/node_modules/sinopia-htpasswd/tests/acceptance.js @@ -90,5 +90,44 @@ describe('acc', function() { }) }) }) + + describe('zero htpasswd', function() { + before(function(cb) { + require('fs').unlink(__dirname + '/zero-htpasswd', function() { + require('fs').writeFile(__dirname + '/zero-htpasswd', '', cb) + }) + }) + + it('should not authenticate', function(cb) { + var p = plugin({file: './zero-htpasswd', max_users: 1}, stuff) + p.authenticate('blah', 'wow', function(err, groups) { + assert(!err) + assert(!groups) + cb() + }) + }) + + it('should not add user with max_users=0', function(cb) { + var p = plugin({file: './zero-htpasswd', max_users: 0}, stuff) + p.adduser('foo1', 'bar1', function(err, ok) { + assert(err) + cb() + }) + }) + + it('should add user', function(cb) { + var p = plugin({file: './zero-htpasswd'}, stuff) + p.adduser('foo1', 'bar1', function(err, ok) { + assert(!err) + assert(ok) + + p.authenticate('foo1', 'bar1', function(err, ok) { + assert(!err) + assert(ok) + cb() + }) + }) + }) + }) }) diff --git a/node_modules/sinopia-htpasswd/utils.js b/node_modules/sinopia-htpasswd/utils.js index 31efb753a..8e90e54f1 100644 --- a/node_modules/sinopia-htpasswd/utils.js +++ b/node_modules/sinopia-htpasswd/utils.js @@ -44,20 +44,33 @@ function open_flock(name, opmod, flmod, tries, backoff, cb) { // this function neither unlocks file nor closes it // it'll have to be done manually later -function lock_and_read(name, callback) { +function lock_and_read(name, _callback) { open_flock(name, 'r', 'exnb', 4, 10, function(err, fd) { + function callback(err) { + if (err && fd) { + fs.close(fd, function(err2) { + _callback(err) + }) + } else { + _callback.apply(null, arguments) + } + } + if (err) return callback(err, fd) fs.fstat(fd, function(err, st) { if (err) return callback(err, fd) var buffer = new Buffer(st.size) - fs.read(fd, buffer, 0, st.size, null, function(err, bytesRead, buffer) { - if (err) return callback(err) + if (st.size === 0) return onRead(null, 0, buffer) + fs.read(fd, buffer, 0, st.size, null, onRead) + + function onRead(err, bytesRead, buffer) { + if (err) return callback(err, fd) if (bytesRead != st.size) return callback(new Error('st.size != bytesRead'), fd) callback(null, fd, buffer) - }) + } }) }) }