basic-authentication
Version:
http basic authentication
86 lines (77 loc) • 3.77 kB
JavaScript
;
var http = require("http").STATUS_CODES, crypto = require("crypto").createHash, setHeader = require("setheaders").setWritableHeader, reg = new RegExp(/^Basic (.*)$/), basic = new RegExp(/^([^:]*):(.*)$/), end = new RegExp(/(.+)/g);
function end_work(err, next, code, res) {
if (void 0 === code) return !next || next();
var codes = http[code];
void 0 !== res && (res.writeHead(code), res.end(codes)), err(next, codes);
}
function end_check(auth, hash) {
return auth !== hash;
}
function end_check_file(auth, hash, file) {
var hashes = crypto(hash), input = require("fs").readFileSync(file, {
encoding: "utf8"
}).match(end), ii = input.length || 0, request = basic_legacy(auth, !0);
if (!request.user || !request.password) return !0;
var psw = hashes.update(request.password).digest("hex");
request = new RegExp("^" + request.user + ":");
for (var i = 0; i < ii; ++i) if (request.test(input[i])) {
if (input[i].substring(request.source.length - 1) === psw) return !1;
}
return !0;
}
function basic_legacy(req, force) {
var auth;
return !0 === force ? (auth = (auth = new Buffer(req, "base64").toString("utf8")).match(basic)) && auth[1] ? {
user: auth[1],
password: auth[2]
} : Object.create(null) : req.headers && (auth = req.headers.authorization) && (auth = auth.match(reg)) && auth[1] && (auth = new Buffer(auth[1], "base64").toString("utf8").match(basic)) ? {
user: auth[1],
password: auth[2]
} : Object.create(null);
}
function basic_small(req) {
var auth;
return req.headers && (auth = req.headers.authorization) && !0 === reg.test(auth) ? auth.substring(6) : "";
}
function authentication(opt) {
var options = opt || Object.create(null);
if (Boolean(options.legacy)) return basic_legacy;
if (Boolean(options.functions)) return basic_small;
var my = {
file: Boolean(options.file),
agent: String(options.agent || ""),
realm: String(options.realm || "Authorization required"),
suppress: Boolean(options.suppress)
};
my.realms = 'Basic realm="' + my.realm + '"', my.realm = {
"WWW-Authenticate": my.realms
};
var check;
if (my.file) {
if (my.hash = String(options.hash || "md5"), my.file = require("path").resolve(String(options.file)),
!require("fs").existsSync(my.file)) {
var err = my.file + " not exists";
throw new Error(err);
}
check = end_check_file;
} else {
var user = String(options.user || "admin"), password = String(options.password || "password");
my.hash = new Buffer(user + ":" + password).toString("base64"), check = end_check;
}
err = function(next, code) {
var err = new Error(code);
return next ? next(err) : err;
};
my.suppress && (err = function() {});
return !1 === options.ending ? function(req, res, next) {
var auth = basic_small(req);
if ("" !== auth) return !0 === check(auth, my.hash, my.file) ? !0 === setHeader(res, "WWW-Authenticate", my.realms) ? end_work(err, next, 401) : null : "" === my.agent || my.agent === req.headers["user-agent"] ? end_work(err, next) : end_work(err, next, 403);
res.writeHead(401, my.realm), res.end();
} : function(req, res, next) {
var auth = basic_small(req);
return "" !== auth ? !0 === check(auth, my.hash, my.file) ? !0 === setHeader(res, "WWW-Authenticate", my.realms) ? end_work(err, next, 401, res) : null : "" === my.agent || my.agent === req.headers["user-agent"] ? end_work(err, next) : end_work(err, next, 403, res) : (res.writeHead(401, my.realm),
res.end(http[401]));
};
}
module.exports = authentication;