This commit is contained in:
2023-12-05 17:03:01 +00:00
parent aec42feb5e
commit ea9944383f
1246 changed files with 125706 additions and 0 deletions

150
node_modules/http-auth/src/auth/base.js generated vendored Normal file
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;

110
node_modules/http-auth/src/auth/basic.js generated vendored Normal file
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);
};

197
node_modules/http-auth/src/auth/digest.js generated vendored Normal file
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);
};

43
node_modules/http-auth/src/auth/utils.js generated vendored Normal file
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;

48
node_modules/http-auth/src/http-auth.js generated vendored Normal file
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');
}
};

14
node_modules/http-auth/src/server/connect.js generated vendored Normal file
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();
}
});
}
};

32
node_modules/http-auth/src/server/hapi.js generated vendored Normal file
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')
};

50
node_modules/http-auth/src/server/http.js generated vendored Normal file
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;
};

48
node_modules/http-auth/src/server/https.js generated vendored Normal file
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;
};

21
node_modules/http-auth/src/server/koa.js generated vendored Normal file
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;
};
};

38
node_modules/http-auth/src/server/passport.js generated vendored Normal file
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);
};

55
node_modules/http-auth/src/server/proxy.js generated vendored Normal file
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;