UNPKG

basic-authentication

Version:
86 lines (77 loc) 3.77 kB
"use strict"; 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;