🐛 Update: Added support for the 'find' command in settings.local.json. Enhanced logging for various modules, including initialization and performance metrics. Improved SQLite database optimization and ensured better tracking of user interactions and system processes. 📚

This commit is contained in:
2025-06-14 16:26:43 +02:00
parent ee54bc273c
commit 89037861e3
2472 changed files with 691099 additions and 1 deletions

View File

@@ -0,0 +1,11 @@
.gitignore
node_modules
.project
http-auth.iml
.idea
.settings
_site
test
examples
.travis.yml
data

20
network-visualization/node_modules/http-auth/LICENSE generated vendored Normal file
View 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
network-visualization/node_modules/http-auth/README.md generated vendored Normal file
View File

@@ -0,0 +1,323 @@
# http-auth
[Node.js](http://nodejs.org/) package for HTTP basic and digest access authentication.
[![Build Status](https://api.travis-ci.org/http-auth/http-auth.png)](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.

View 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"
]
}

View 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;

View 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);
};

View 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);
};

View 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;

View 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');
}
};

View 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();
}
});
}
};

View 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')
};

View 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;
};

View 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;
};

View 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;
};
};

View 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);
};

View 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;