test
This commit is contained in:
11
node_modules/http-auth/.npmignore
generated
vendored
Normal file
11
node_modules/http-auth/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
.gitignore
|
||||
node_modules
|
||||
.project
|
||||
http-auth.iml
|
||||
.idea
|
||||
.settings
|
||||
_site
|
||||
test
|
||||
examples
|
||||
.travis.yml
|
||||
data
|
||||
20
node_modules/http-auth/LICENSE
generated
vendored
Normal file
20
node_modules/http-auth/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Gevorg Harutyunyan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
323
node_modules/http-auth/README.md
generated
vendored
Normal file
323
node_modules/http-auth/README.md
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
# http-auth
|
||||
[Node.js](http://nodejs.org/) package for HTTP basic and digest access authentication.
|
||||
|
||||
[](https://travis-ci.org/http-auth/http-auth)
|
||||
|
||||
## Installation
|
||||
|
||||
Via git (or downloaded tarball):
|
||||
|
||||
```bash
|
||||
$ git clone git://github.com/http-auth/http-auth.git
|
||||
```
|
||||
Via [npm](http://npmjs.org/):
|
||||
|
||||
```bash
|
||||
$ npm install http-auth
|
||||
```
|
||||
|
||||
## Basic example
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Creating new HTTP server.
|
||||
http.createServer(basic, (req, res) => {
|
||||
res.end(`Welcome to private area - ${req.user}!`);
|
||||
}).listen(1337);
|
||||
|
||||
```
|
||||
## Custom authentication
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area."
|
||||
}, (username, password, callback) => {
|
||||
// Custom authentication
|
||||
// Use callback(error) if you want to throw async error.
|
||||
callback(username === "Tina" && password === "Bullock");
|
||||
}
|
||||
);
|
||||
|
||||
// Creating new HTTP server.
|
||||
http.createServer(basic, (req, res) => {
|
||||
res.end(`Welcome to private area - ${req.user}!`);
|
||||
}).listen(1337);
|
||||
```
|
||||
|
||||
## [express framework](http://expressjs.com/) integration
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Application setup.
|
||||
var app = express();
|
||||
app.use(auth.connect(basic));
|
||||
|
||||
// Setup route.
|
||||
app.get('/', (req, res) => {
|
||||
res.send(`Hello from express - ${req.user}!`);
|
||||
});
|
||||
```
|
||||
|
||||
## [koa framework](http://koajs.com/) integration
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Final handler.
|
||||
app.use(function *(next) {
|
||||
yield next;
|
||||
this.body = `Hello from koa - ${this.req.user}!`;
|
||||
});
|
||||
|
||||
// Enable auth.
|
||||
app.use(auth.koa(basic));
|
||||
```
|
||||
|
||||
## For [koa@next](https://github.com/koajs/koa/tree/v2.x) you can use [http-auth-koa](https://github.com/http-auth/http-auth-koa)
|
||||
```javascript
|
||||
// Authentication module.
|
||||
import auth from 'http-auth'
|
||||
import koaAuth from 'http-auth-koa'
|
||||
const basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Koa setup.
|
||||
import Koa from 'koa'
|
||||
const app = new Koa();
|
||||
|
||||
// Setup basic handler.
|
||||
app.use(async (ctx, next) => {
|
||||
await next();
|
||||
ctx.body = `Welcome to koa ${ctx.req.user}!`;
|
||||
});
|
||||
|
||||
// Setup auth.
|
||||
app.use(koaAuth(basic));
|
||||
```
|
||||
|
||||
## [hapi framework](http://hapijs.com/) integration
|
||||
```javascript
|
||||
// Authentication module.
|
||||
const auth = require('http-auth');
|
||||
|
||||
// Setup auth.
|
||||
const basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Create server.
|
||||
const server = new Hapi.Server();
|
||||
server.connection({ port: 1337 });
|
||||
|
||||
// Register auth plugin.
|
||||
server.register(auth.hapi());
|
||||
|
||||
// Setup strategy.
|
||||
server.auth.strategy('http-auth', 'http', basic);
|
||||
|
||||
// Setup route.
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/',
|
||||
config: {
|
||||
auth: 'http-auth',
|
||||
handler: (request, reply) => {
|
||||
reply(`Welcome from Hapi - ${request.auth.credentials.name}!`);
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Protecting specific path
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Application setup.
|
||||
var app = express();
|
||||
|
||||
// Setup route.
|
||||
app.get('/admin', auth.connect(basic), (req, res) => {
|
||||
res.send(`Hello from admin area - ${req.user}!`);
|
||||
});
|
||||
|
||||
// Setup route.
|
||||
app.get('/', (req, res) => {
|
||||
res.send("Not protected area!");
|
||||
});
|
||||
```
|
||||
|
||||
## [passport](http://passportjs.org/) integration
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Application setup.
|
||||
var app = express();
|
||||
|
||||
// Setup strategy.
|
||||
var passport = require('passport');
|
||||
passport.use(auth.passport(basic));
|
||||
|
||||
// Setup route.
|
||||
app.get('/', passport.authenticate('http', {session: false}),
|
||||
(req, res) => {
|
||||
res.end(`Welcome to private area - ${req.user}!`);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## [http-proxy](https://github.com/nodejitsu/node-http-proxy/) integration
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
// Create your proxy server.
|
||||
httpProxy.createServer(basic, {
|
||||
target: 'http://localhost:1338'
|
||||
}).listen(1337);
|
||||
|
||||
// Create your target server.
|
||||
http.createServer((req, res) => {
|
||||
res.end("Request successfully proxied!");
|
||||
}).listen(1338);
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
The auth middleware emits three types of events: **error**, **fail** and **success**. Each event passes the result object (the error in case of `fail`) and the http request `req` to the listener function.
|
||||
|
||||
```javascript
|
||||
// Authentication module.
|
||||
var auth = require('http-auth');
|
||||
var basic = auth.basic({
|
||||
realm: "Simon Area.",
|
||||
file: __dirname + "/../data/users.htpasswd"
|
||||
});
|
||||
|
||||
basic.on('success', (result, req) => {
|
||||
console.log(`User authenticated: ${result.user}`);
|
||||
});
|
||||
|
||||
basic.on('fail', (result, req) => {
|
||||
console.log(`User authentication failed: ${result.user}`);
|
||||
});
|
||||
|
||||
basic.on('error', (error, req) => {
|
||||
console.log(`Authentication error: ${error.code + " - " + error.message}`);
|
||||
});
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
- `realm` - Authentication realm, by default it is **Users**.
|
||||
- `file` - File where user details are stored.
|
||||
- Line format is **{user:pass}** or **{user:passHash}** for basic access.
|
||||
- Line format is **{user:realm:passHash}** for digest access.
|
||||
- `algorithm` - Algorithm that will be used only for **digest** access authentication.
|
||||
- **MD5** by default.
|
||||
- **MD5-sess** can be set.
|
||||
- `qop` - Quality of protection that is used only for **digest** access authentication.
|
||||
- **auth** is set by default.
|
||||
- **none** this option is disabling protection.
|
||||
- `msg401` - Message for failed authentication 401 page.
|
||||
- `msg407` - Message for failed authentication 407 page.
|
||||
- `contentType` - Content type for failed authentication page.
|
||||
- `skipUser` - Set this to **true**, if you don't want req.user to be filled with authentication info.
|
||||
|
||||
## Running tests
|
||||
|
||||
It uses [mocha](https://mochajs.org/), so just run following command in package directory:
|
||||
|
||||
```bash
|
||||
$ npm test
|
||||
```
|
||||
|
||||
## Issues
|
||||
|
||||
You can find list of issues using **[this link](http://github.com/http-auth/http-auth/issues)**.
|
||||
|
||||
## Questions
|
||||
|
||||
You can also use [stackoverflow](http://stackoverflow.com/questions/tagged/http-auth) to ask questions using **[http-auth](http://stackoverflow.com/tags/http-auth/info)** tag.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **[Node.js](http://nodejs.org)** - Event-driven I/O server-side JavaScript environment based on V8.
|
||||
- **[npm](http://npmjs.org)** - Package manager. Installs, publishes and manages node programs.
|
||||
|
||||
## Utilities
|
||||
|
||||
- **[htpasswd](https://github.com/http-auth/htpasswd/)** - Node.js package for HTTP Basic Authentication password file utility.
|
||||
- **[htdigest](https://github.com/http-auth/htdigest/)** - Node.js package for HTTP Digest Authentication password file utility.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **[uuid](https://github.com/broofa/node-uuid/)** - Generate RFC4122(v4) UUIDs, and also non-RFC compact ids.
|
||||
- **[apache-md5](https://github.com/http-auth/apache-md5)** - Node.js module for Apache style password encryption using md5.
|
||||
- **[apache-crypt](https://github.com/http-auth/apache-crypt)** - Node.js module for Apache style password encryption using crypt(3).
|
||||
- **[bcrypt.js](https://github.com/dcodeIO/bcrypt.js)** - Optimized bcrypt in plain JavaScript with zero dependencies.
|
||||
|
||||
## Development dependencies
|
||||
|
||||
- **[mocha](https://mochajs.org/)** - simple, flexible, fun javascript test framework for node.js & the browser.
|
||||
- **[chai](http://chaijs.com/)** - BDD / TDD assertion framework for node.js and the browser that can be paired with any testing framework.
|
||||
- **[express](http://expressjs.com/)** - Sinatra inspired web development framework for node.js -- insanely fast, flexible, and simple.
|
||||
- **[http-proxy](https://github.com/nodejitsu/node-http-proxy/)** - A full-featured http proxy for node.js.
|
||||
- **[request](https://github.com/request/request/)** - Simplified HTTP request client.
|
||||
- **[passport](http://passportjs.org/)** - Simple, unobtrusive authentication for Node.js.
|
||||
- **[koa](http://koajs.com/)** - next generation web framework for node.js.
|
||||
- **[hapi](http://hapijs.com/)** - A rich framework for building applications and services.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Gevorg Harutyunyan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
node_modules/http-auth/node_modules/.bin/uuid
generated
vendored
Symbolic link
1
node_modules/http-auth/node_modules/.bin/uuid
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../uuid/bin/uuid
|
||||
57
node_modules/http-auth/package.json
generated
vendored
Normal file
57
node_modules/http-auth/package.json
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "http-auth",
|
||||
"description": "Node.js package for HTTP basic and digest access authentication.",
|
||||
"version": "3.1.3",
|
||||
"author": "Gevorg Harutyunyan (http://github.com/gevorg)",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "gevorg",
|
||||
"email": "gevorg.ha@gmail.com"
|
||||
}
|
||||
],
|
||||
"homepage": "http://http-auth.info",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/http-auth/http-auth.git"
|
||||
},
|
||||
"main": "./src/http-auth.js",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "http://github.com/http-auth/http-auth/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "http://github.com/http-auth/http-auth/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"apache-crypt": "^1.1.2",
|
||||
"apache-md5": "^1.0.6",
|
||||
"bcryptjs": "^2.3.0",
|
||||
"uuid": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^3.5.0",
|
||||
"express": "^4.13.4",
|
||||
"http-proxy": "^1.13.3",
|
||||
"koa": "^1.2.0",
|
||||
"hapi": "^15.0.3",
|
||||
"mocha": "^3.1.2",
|
||||
"passport": "^0.3.2",
|
||||
"request": "^2.72.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.6.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"keywords": [
|
||||
"http",
|
||||
"basic",
|
||||
"digest",
|
||||
"access",
|
||||
"authentication"
|
||||
]
|
||||
}
|
||||
150
node_modules/http-auth/src/auth/base.js
generated
vendored
Normal file
150
node_modules/http-auth/src/auth/base.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
"use strict";
|
||||
|
||||
// File system module.
|
||||
const fs = require('fs');
|
||||
|
||||
// Event module.
|
||||
const events = require('events');
|
||||
|
||||
// Base authentication.
|
||||
class Base extends events.EventEmitter {
|
||||
// Constructor.
|
||||
constructor(options, checker) {
|
||||
super();
|
||||
|
||||
if (!options.msg401) {
|
||||
options.msg401 = "401 Unauthorized";
|
||||
}
|
||||
|
||||
if (!options.msg407) {
|
||||
options.msg407 = "407 Proxy authentication required";
|
||||
}
|
||||
|
||||
if (!options.contentType) {
|
||||
options.contentType = "text/plain";
|
||||
}
|
||||
|
||||
if (!options.realm) {
|
||||
options.realm = "users";
|
||||
}
|
||||
|
||||
// Assign values.
|
||||
this.options = options;
|
||||
this.checker = checker;
|
||||
|
||||
// Loading users from file, if file is set.
|
||||
this.options.users = [];
|
||||
|
||||
if (!checker && options.file) {
|
||||
this.loadUsers();
|
||||
}
|
||||
}
|
||||
|
||||
// Processing user line.
|
||||
processLine(userLine) {
|
||||
throw new Error('Not defined!');
|
||||
}
|
||||
|
||||
// Parse auth header.
|
||||
parseAuthorization(header) {
|
||||
throw new Error('Not defined!');
|
||||
}
|
||||
|
||||
// Find user.
|
||||
findUser(req, clientOptions, callback) {
|
||||
throw new Error('Not defined!');
|
||||
}
|
||||
|
||||
// Generates header.
|
||||
generateHeader(result) {
|
||||
throw new Error('Not defined!');
|
||||
}
|
||||
|
||||
// Ask for authentication.
|
||||
ask(res, result) {
|
||||
let header = this.generateHeader(result);
|
||||
res.setHeader("Content-Type", this.options.contentType);
|
||||
|
||||
if (this.proxy) {
|
||||
res.setHeader("Proxy-Authenticate", header);
|
||||
res.writeHead(407);
|
||||
res.end(this.options.msg407);
|
||||
} else {
|
||||
res.setHeader("WWW-Authenticate", header);
|
||||
res.writeHead(401);
|
||||
res.end(this.options.msg401);
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if user is authenticated.
|
||||
check(req, res, callback) {
|
||||
let self = this;
|
||||
this.isAuthenticated(req, (result) => {
|
||||
if (result instanceof Error) {
|
||||
self.emit('error', result, req);
|
||||
|
||||
if (callback) {
|
||||
callback.apply(self, [req, res, result]);
|
||||
}
|
||||
} else if (!result.pass) {
|
||||
self.emit('fail', result, req);
|
||||
self.ask(res, result);
|
||||
} else {
|
||||
self.emit('success', result, req);
|
||||
|
||||
if (!this.options.skipUser) {
|
||||
req.user = result.user;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback.apply(self, [req, res]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Is authenticated method.
|
||||
isAuthenticated(req, callback) {
|
||||
let self = this;
|
||||
let header = undefined;
|
||||
if (this.proxy) {
|
||||
header = req.headers["proxy-authorization"];
|
||||
} else {
|
||||
header = req.headers["authorization"];
|
||||
}
|
||||
|
||||
// Searching for user.
|
||||
let searching = false;
|
||||
|
||||
// If header is sent.
|
||||
if (header) {
|
||||
let clientOptions = this.parseAuthorization(header);
|
||||
if (clientOptions) {
|
||||
searching = true;
|
||||
this.findUser(req, clientOptions, (result) => {
|
||||
callback.apply(self, [result]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Only if not searching call callback.
|
||||
if (!searching) {
|
||||
callback.apply(this, [{}]);
|
||||
}
|
||||
}
|
||||
|
||||
// Loading files with user details.
|
||||
loadUsers() {
|
||||
let users = fs.readFileSync(this.options.file, 'UTF-8').replace(/\r\n/g, "\n").split("\n");
|
||||
|
||||
// Process all users.
|
||||
users.forEach(u => {
|
||||
if(u && !u.match(/^\s*#.*/)) {
|
||||
this.processLine(u);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Export base.
|
||||
module.exports = Base;
|
||||
110
node_modules/http-auth/src/auth/basic.js
generated
vendored
Normal file
110
node_modules/http-auth/src/auth/basic.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
"use strict";
|
||||
|
||||
// Base class.
|
||||
const Base = require('./base');
|
||||
|
||||
// Utility module.
|
||||
const utils = require('./utils');
|
||||
|
||||
// Importing apache-md5 module.
|
||||
const md5 = require('apache-md5');
|
||||
|
||||
// Importing apache-crypt module.
|
||||
const crypt = require('apache-crypt');
|
||||
|
||||
// Bcrypt.
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
// Crypto.
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Define basic auth.
|
||||
class Basic extends Base {
|
||||
// Constructor.
|
||||
constructor(options, checker) {
|
||||
super(options, checker);
|
||||
}
|
||||
|
||||
// Verifies if password is correct.
|
||||
validate (hash, password) {
|
||||
if (hash.substr(0, 5) === '{SHA}') {
|
||||
hash = hash.substr(5);
|
||||
return hash === utils.sha1(password);
|
||||
} else if (hash.substr(0, 6) === '$apr1$' || hash.substr(0, 3) === '$1$') {
|
||||
return hash === md5(password, hash);
|
||||
} else if (hash.substr(0, 4) === '$2y$' || hash.substr(0, 4) === '$2a$') {
|
||||
return bcrypt.compareSync(password, hash);
|
||||
} else if (hash === crypt(password, hash)) {
|
||||
return true;
|
||||
} else if (hash.length === password.length) {
|
||||
return crypto.timingSafeEqual ?
|
||||
crypto.timingSafeEqual(new Buffer(hash), new Buffer(password)) : hash === password;
|
||||
}
|
||||
}
|
||||
|
||||
// Processes line from authentication file.
|
||||
processLine (userLine) {
|
||||
let lineSplit = userLine.split(":");
|
||||
let username = lineSplit.shift();
|
||||
let hash = lineSplit.join(":");
|
||||
|
||||
// Push user.
|
||||
this.options.users.push({username: username, hash: hash});
|
||||
}
|
||||
|
||||
// Generates request header.
|
||||
generateHeader () {
|
||||
return `Basic realm=\"${this.options.realm}\"`;
|
||||
}
|
||||
|
||||
// Parsing authorization header.
|
||||
parseAuthorization (header) {
|
||||
let tokens = header.split(" ");
|
||||
if (tokens[0] === "Basic") {
|
||||
return tokens[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Searching for user.
|
||||
findUser(req, hash, callback) {
|
||||
// Decode base64.
|
||||
let splitHash = utils.decodeBase64(hash).split(":");
|
||||
let username = splitHash.shift();
|
||||
let password = splitHash.join(":");
|
||||
|
||||
let self = this;
|
||||
|
||||
if (this.checker) {
|
||||
// Custom auth.
|
||||
this.checker.apply(this, [username, password, (result) => {
|
||||
let params = undefined;
|
||||
|
||||
if (result instanceof Error) {
|
||||
params = [result]
|
||||
} else {
|
||||
params = [{ user: username, pass: !!result }];
|
||||
}
|
||||
|
||||
callback.apply(self, params);
|
||||
}, req]);
|
||||
} else {
|
||||
// File based auth.
|
||||
let pass = false;
|
||||
|
||||
// Loop users to find the matching one.
|
||||
this.options.users.forEach(user => {
|
||||
if (user.username === username && this.validate(user.hash, password)) {
|
||||
pass = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Call final callback.
|
||||
callback.apply(this, [{user: username, pass: pass}]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export basic auth.
|
||||
module.exports = (options, checker) => {
|
||||
return new Basic(options, checker);
|
||||
};
|
||||
197
node_modules/http-auth/src/auth/digest.js
generated
vendored
Normal file
197
node_modules/http-auth/src/auth/digest.js
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
"use strict";
|
||||
|
||||
// Base class.
|
||||
const Base = require('./base');
|
||||
|
||||
// Utility module.
|
||||
const utils = require('./utils');
|
||||
|
||||
// Unique id.
|
||||
const uuid = require('uuid');
|
||||
|
||||
// Define digest auth.
|
||||
class Digest extends Base {
|
||||
// Constructor.
|
||||
constructor(options, checker) {
|
||||
super(options, checker);
|
||||
|
||||
// Array of random strings sent to clients.
|
||||
this.nonces = [];
|
||||
|
||||
// Algorithm of encryption, could be MD5 or MD5-sess, default is MD5.
|
||||
if ('MD5-sess' !== options.algorithm) {
|
||||
this.options.algorithm = "MD5";
|
||||
}
|
||||
|
||||
// Quality of protection is by default auth.
|
||||
if (options.qop === 'none') {
|
||||
this.options.qop = '';
|
||||
} else {
|
||||
this.options.qop = 'auth';
|
||||
}
|
||||
}
|
||||
|
||||
// Process user line.
|
||||
processLine(line) {
|
||||
let tokens = line.split(":");
|
||||
|
||||
// We need only users for given realm.
|
||||
if (this.options.realm === tokens[1]) {
|
||||
this.options.users.push({username: tokens[0], hash: tokens[2]});
|
||||
}
|
||||
}
|
||||
|
||||
// Parse authorization heder.
|
||||
parseAuthorization(header) {
|
||||
let opts = {};
|
||||
let parts = header.split(' ');
|
||||
let params = parts.slice(1).join(' ');
|
||||
|
||||
// Split the parameters by comma.
|
||||
let tokens = params.split(/,(?=(?:[^"]|"[^"]*")*$)/);
|
||||
if (parts[0].substr(0, 6) === "Digest") {
|
||||
// Parse parameters.
|
||||
let i = 0;
|
||||
let len = tokens.length;
|
||||
|
||||
while (i < len) {
|
||||
// Strip quotes and whitespace.
|
||||
let param = /(\w+)=["]?([^"]*)["]?$/.exec(tokens[i]);
|
||||
if (param) {
|
||||
opts[param[1]] = param[2];
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Return options.
|
||||
return opts;
|
||||
}
|
||||
|
||||
// Validating hash.
|
||||
validate(ha2, co, hash) {
|
||||
let ha1 = hash;
|
||||
|
||||
// Algorithm.
|
||||
if (co.algorithm === 'MD5-sess') {
|
||||
ha1 = utils.md5(`${ha1}:${co.nonce}:${co.cnonce}`);
|
||||
}
|
||||
|
||||
let response = undefined;
|
||||
|
||||
// Quality of protection.
|
||||
if (co.qop) {
|
||||
response = utils.md5(`${ha1}:${co.nonce}:${co.nc}:${co.cnonce}:${co.qop}:${ha2}`);
|
||||
} else {
|
||||
response = utils.md5(`${ha1}:${co.nonce}:${ha2}`);
|
||||
}
|
||||
|
||||
// If calculated response is equal to client's response.
|
||||
return response === co.response;
|
||||
}
|
||||
|
||||
// Searching for user.
|
||||
findUser(req, co, callback) {
|
||||
let self = this;
|
||||
|
||||
if (this.validateNonce(co.nonce, co.qop, co.nc)) {
|
||||
let ha2 = utils.md5(`${req.method}:${co.uri}`);
|
||||
if (this.checker) {
|
||||
// Custom authentication.
|
||||
this.checker.apply(this, [co.username, (hash) => {
|
||||
let params = undefined;
|
||||
|
||||
if (hash instanceof Error) {
|
||||
params = [hash];
|
||||
} else {
|
||||
params = [{user: co.username, pass: !!self.validate(ha2, co, hash)}];
|
||||
}
|
||||
|
||||
// Call callback.
|
||||
callback.apply(this, params);
|
||||
}, req]);
|
||||
} else {
|
||||
let pass = false;
|
||||
|
||||
// File based, loop users to find the matching one.
|
||||
this.options.users.forEach(user => {
|
||||
if (user.username === co.username && this.validate(ha2, co, user.hash)) {
|
||||
pass = true;
|
||||
}
|
||||
});
|
||||
|
||||
callback.apply(this, [{user: co.username, pass: pass}]);
|
||||
}
|
||||
} else {
|
||||
callback.apply(this, [{stale: true}]);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove nonces.
|
||||
removeNonces(noncesToRemove) {
|
||||
noncesToRemove.forEach(nonce => {
|
||||
let index = this.nonces.indexOf(nonce);
|
||||
if (index != -1) {
|
||||
this.nonces.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Validate nonce.
|
||||
validateNonce(nonce, qop, nc) {
|
||||
let found = false;
|
||||
|
||||
// Current time.
|
||||
let now = Date.now();
|
||||
|
||||
// Nonces for removal.
|
||||
let noncesToRemove = [];
|
||||
|
||||
// Searching for not expired ones.
|
||||
this.nonces.forEach(serverNonce => {
|
||||
if ((serverNonce[1] + 3600000) > now) {
|
||||
if (serverNonce[0] === nonce) {
|
||||
if (qop) {
|
||||
if (nc > serverNonce[2]) {
|
||||
found = true;
|
||||
++ serverNonce[2];
|
||||
}
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
noncesToRemove.push(serverNonce);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove expired nonces.
|
||||
this.removeNonces(noncesToRemove);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// Generates and returns new random nonce.
|
||||
askNonce() {
|
||||
let nonce = utils.md5(uuid());
|
||||
this.nonces.push([nonce, Date.now(), 0]);
|
||||
|
||||
return nonce;
|
||||
}
|
||||
|
||||
// Generates request header.
|
||||
generateHeader(result) {
|
||||
let nonce = this.askNonce();
|
||||
let stale = result.stale ? true : false;
|
||||
|
||||
// Returning it.
|
||||
return `Digest realm=\"${this.options.realm}\", qop=\"${this.options.qop}\", nonce=\"${nonce}\", algorithm=\"${this.options.algorithm}\", stale=\"${stale}\"`;
|
||||
}
|
||||
}
|
||||
|
||||
// Export digest auth.
|
||||
module.exports = (options, checker) => {
|
||||
return new Digest(options, checker);
|
||||
};
|
||||
43
node_modules/http-auth/src/auth/utils.js
generated
vendored
Normal file
43
node_modules/http-auth/src/auth/utils.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
// Importing crypto module.
|
||||
const crypto = require('crypto');
|
||||
const utils = {};
|
||||
|
||||
// Generates md5 hash of input.
|
||||
utils.md5 = (input) => {
|
||||
let hash = crypto.createHash('MD5');
|
||||
hash.update(input);
|
||||
|
||||
return hash.digest('hex');
|
||||
};
|
||||
|
||||
// Generates sha1 hash of input.
|
||||
utils.sha1 = (input) => {
|
||||
let hash = crypto.createHash('sha1');
|
||||
hash.update(input);
|
||||
|
||||
return hash.digest('base64');
|
||||
};
|
||||
|
||||
// Encode to base64 string.
|
||||
utils.base64 = (input) => {
|
||||
return new Buffer(input, 'utf8').toString('base64');
|
||||
};
|
||||
|
||||
// Decodes base64 string.
|
||||
utils.decodeBase64 = (input) => {
|
||||
return new Buffer(input, 'base64').toString('utf8');
|
||||
};
|
||||
|
||||
// Check if module is available.
|
||||
utils.isAvailable = (path) => {
|
||||
try {
|
||||
return !!require.resolve(path);
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Export utils.
|
||||
module.exports = utils;
|
||||
48
node_modules/http-auth/src/http-auth.js
generated
vendored
Normal file
48
node_modules/http-auth/src/http-auth.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
// Utils.
|
||||
const utils = require('./auth/utils');
|
||||
|
||||
// http integration.
|
||||
require('./server/http');
|
||||
|
||||
// https integration.
|
||||
require('./server/https');
|
||||
|
||||
// http-proxy integration.
|
||||
if (utils.isAvailable('http-proxy')) {
|
||||
require('./server/proxy');
|
||||
}
|
||||
|
||||
// Exports.
|
||||
module.exports = {
|
||||
// Basic authentication.
|
||||
basic: (options, checker) => {
|
||||
return require('./auth/basic')(options, checker);
|
||||
},
|
||||
|
||||
// Digest authentication.
|
||||
digest: (options, checker) => {
|
||||
return require('./auth/digest')(options, checker);
|
||||
},
|
||||
|
||||
// Connect.
|
||||
connect: (auth) => {
|
||||
return require('./server/connect')(auth);
|
||||
},
|
||||
|
||||
// Koa.
|
||||
koa: (auth) => {
|
||||
return require('./server/koa')(auth);
|
||||
},
|
||||
|
||||
// Passport.
|
||||
passport: (auth) => {
|
||||
return require('./server/passport')(auth);
|
||||
},
|
||||
|
||||
// Hapi.
|
||||
hapi: () => {
|
||||
return require('./server/hapi');
|
||||
}
|
||||
};
|
||||
14
node_modules/http-auth/src/server/connect.js
generated
vendored
Normal file
14
node_modules/http-auth/src/server/connect.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
// Exporting connect integration.
|
||||
module.exports = (auth) => {
|
||||
return (req, res, next) => {
|
||||
auth.check(req, res, (req, res, err) => {
|
||||
if (err) {
|
||||
next(err);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
32
node_modules/http-auth/src/server/hapi.js
generated
vendored
Normal file
32
node_modules/http-auth/src/server/hapi.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
|
||||
// HTTP authentication scheme.
|
||||
const httpScheme = (server, auth) => {
|
||||
return {
|
||||
authenticate: (request, reply) => {
|
||||
// Is auth.
|
||||
auth.isAuthenticated(request, (result) => {
|
||||
if (result instanceof Error) {
|
||||
return reply(result, null, { credentials: null });
|
||||
} else if (!result.pass) {
|
||||
let header = auth.generateHeader(result);
|
||||
return reply(auth.options.msg401).code(401).header('WWW-Authenticate', header);
|
||||
} else {
|
||||
return reply.continue({credentials: { name: result.user }});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Export plugin.
|
||||
exports.register = (plugin, options, next) => {
|
||||
plugin.auth.scheme('http', httpScheme);
|
||||
next();
|
||||
};
|
||||
|
||||
// Export attributes.
|
||||
exports.register.attributes = {
|
||||
pkg: require('../../package.json')
|
||||
};
|
||||
50
node_modules/http-auth/src/server/http.js
generated
vendored
Normal file
50
node_modules/http-auth/src/server/http.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
|
||||
// HTTP module.
|
||||
const http = require('http');
|
||||
|
||||
// Base module.
|
||||
const Base = require('../auth/base');
|
||||
|
||||
// Backup old server creation.
|
||||
const oldCreateServer = http.createServer;
|
||||
|
||||
// Add authentication method.
|
||||
http.createServer = function() {
|
||||
let server = undefined;
|
||||
|
||||
// Mutated mode.
|
||||
if (arguments[0] instanceof Base) {
|
||||
let auth = arguments[0];
|
||||
|
||||
// With listener.
|
||||
if (arguments[1]) {
|
||||
let listener = arguments[1];
|
||||
let newListener = (req, res) => {
|
||||
auth.check(req, res, (req, res, err) => {
|
||||
if (err) {
|
||||
console.error (err);
|
||||
res.statusCode = 400;
|
||||
res.end(err.message);
|
||||
} else {
|
||||
listener(req, res);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Mutate server.
|
||||
server = oldCreateServer.apply(http, [newListener]);
|
||||
} else {
|
||||
// Without listener.
|
||||
server = oldCreateServer.apply(http, []);
|
||||
server.on('request', (req, res) => {
|
||||
auth.check(req, res);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
server = oldCreateServer.apply(http, arguments);
|
||||
}
|
||||
|
||||
// Return server.
|
||||
return server;
|
||||
};
|
||||
48
node_modules/http-auth/src/server/https.js
generated
vendored
Normal file
48
node_modules/http-auth/src/server/https.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
// HTTPS module.
|
||||
const https = require('https');
|
||||
|
||||
// Base module.
|
||||
const Base = require('../auth/base');
|
||||
|
||||
// Backup old server creation.
|
||||
let oldCreateServer = https.createServer;
|
||||
|
||||
// Mutate server.
|
||||
https.createServer = function() {
|
||||
let server = undefined;
|
||||
|
||||
if (arguments[0] instanceof Base) {
|
||||
let auth = arguments[0];
|
||||
|
||||
if (arguments[2]) {
|
||||
let listener = arguments[2];
|
||||
let newListener = (req, res) => {
|
||||
auth.check(req, res, (req, res, err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.statusCode = 400;
|
||||
res.end(err.message);
|
||||
} else {
|
||||
listener(req, res);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// HTTPS options and listener.
|
||||
server = oldCreateServer.apply(https, [arguments[1], newListener]);
|
||||
} else {
|
||||
// Only HTTPS options.
|
||||
server = oldCreateServer.apply(https, [arguments[1]]);
|
||||
server.on('request', (req, res) => {
|
||||
auth.check(req, res);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
server = oldCreateServer.apply(https, arguments);
|
||||
}
|
||||
|
||||
// Return server.
|
||||
return server;
|
||||
};
|
||||
21
node_modules/http-auth/src/server/koa.js
generated
vendored
Normal file
21
node_modules/http-auth/src/server/koa.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
// Export middleware.
|
||||
module.exports = (auth) => {
|
||||
// Middleware for koa.
|
||||
const koa = (req, res, next) => {
|
||||
auth.check(req, res, (req, res, err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Return middleware.
|
||||
return function *(next) {
|
||||
yield koa.bind(null, this.req, this.res);
|
||||
yield next;
|
||||
};
|
||||
};
|
||||
38
node_modules/http-auth/src/server/passport.js
generated
vendored
Normal file
38
node_modules/http-auth/src/server/passport.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
// Imports.
|
||||
const passport = require('passport');
|
||||
const util = require('util');
|
||||
|
||||
// Define strategy.
|
||||
function HttpStrategy(auth) {
|
||||
this.name = 'http';
|
||||
this.authentication = auth;
|
||||
|
||||
passport.Strategy.call(this);
|
||||
}
|
||||
|
||||
// Inherit basic strategy.
|
||||
util.inherits(HttpStrategy, passport.Strategy);
|
||||
|
||||
// Define auth method.
|
||||
HttpStrategy.prototype.authenticate = function (req) {
|
||||
let self = this;
|
||||
|
||||
// Is auth.
|
||||
this.authentication.isAuthenticated(req, (result) => {
|
||||
if (result instanceof Error) {
|
||||
self.error(result);
|
||||
} else if (!result.pass) {
|
||||
let header = self.authentication.generateHeader(result);
|
||||
self.fail(header);
|
||||
} else {
|
||||
self.success(result.user);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Export.
|
||||
module.exports = (auth) => {
|
||||
return new HttpStrategy(auth);
|
||||
};
|
||||
55
node_modules/http-auth/src/server/proxy.js
generated
vendored
Normal file
55
node_modules/http-auth/src/server/proxy.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
|
||||
// Proxy module.
|
||||
const httpProxy = require('http-proxy');
|
||||
|
||||
// Base module.
|
||||
const Base = require('../auth/base');
|
||||
|
||||
// Backup old server creation.
|
||||
const oldCreateServer = httpProxy.createServer;
|
||||
|
||||
// New create server.
|
||||
const newCreateServer = function(auth, options) {
|
||||
// Mutated mode.
|
||||
if (auth instanceof Base) {
|
||||
// Set proxy flag.
|
||||
auth.proxy = true;
|
||||
} else {
|
||||
// Set correct options.
|
||||
options = auth;
|
||||
|
||||
// Clear authentication value.
|
||||
auth = null;
|
||||
}
|
||||
|
||||
// Default listener plus authentication check.
|
||||
let server = oldCreateServer.apply(httpProxy, [options]);
|
||||
|
||||
// Authentication provided.
|
||||
if (auth) {
|
||||
// Override proxyRequest.
|
||||
let oldProxyRequest = server.web;
|
||||
server.web = function (req, res) {
|
||||
// Fetch external arguments.
|
||||
let externalArguments = arguments;
|
||||
|
||||
// Check for authentication.
|
||||
auth.check(req, res, (req, res, err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
res.statusCode = 400;
|
||||
res.end (err.message);
|
||||
} else {
|
||||
oldProxyRequest.apply(server, externalArguments)
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Return server.
|
||||
return server;
|
||||
};
|
||||
|
||||
// Add authentication method.
|
||||
httpProxy.createServer = httpProxy.createProxyServer = httpProxy.createProxy = newCreateServer;
|
||||
Reference in New Issue
Block a user