UNPKG

node-expose-sspi-strict

Version:

Expose the Microsoft Windows SSPI interface in order to do NTLM and Kerberos authentication.

128 lines (127 loc) 5.22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; exports.__esModule = true; exports.ServerContextHandleManager = void 0; var cookies_1 = require("./cookies"); var debug_1 = __importDefault(require("debug")); var debug = debug_1["default"]('node-expose-sspi:schManager'); var COOKIE_KEY = 'NEGOTIATE_ID'; var COOKIE_PREFIX_VALUE = 'NEGOTIATE_'; var ServerContextHandleManager = /** @class */ (function () { function ServerContextHandleManager(delayMax) { if (delayMax === void 0) { delayMax = 20000; } this.delayMax = delayMax; this.queue = []; this.sessionMap = new Map(); } ServerContextHandleManager.prototype.initCookie = function (req, res) { debug('initCookie'); var cookieToken = cookies_1.parseCookies(req)[COOKIE_KEY]; if (!cookieToken) { cookieToken = COOKIE_PREFIX_VALUE + Math.floor(1e10 * Math.random()); // create a session cookie (without expiration specified) res.setHeader('Set-Cookie', COOKIE_KEY + '=' + cookieToken); } if (!this.sessionMap.has(cookieToken)) { this.sessionMap.set(cookieToken, { method: undefined, serverContextHandle: undefined }); } return cookieToken; }; ServerContextHandleManager.prototype.waitForReleased = function (cookieToken) { var _this = this; if (cookieToken) { return Promise.resolve(); } debug('waitForReleased: start'); return new Promise(function (resolve, reject) { debug('waitForReleased: start promise'); // if nobody else is currently authenticating then go now. var authItem = { resolve: resolve, reject: reject }; var timeout = setTimeout(function () { _this.tooLate(authItem); }, _this.delayMax); if (_this.authItem === undefined) { debug('waitForReleased: no other authentication ongoing: we can start now.'); _this.authItem = { resolve: resolve, reject: reject, timeout: timeout }; return _this.authItem.resolve(); } debug('someone is currently authenticating, go in the queue and wait for your turn.'); _this.queue.push({ resolve: resolve, reject: reject, timeout: timeout }); debug('queue length', _this.queue.length); }); }; ServerContextHandleManager.prototype.set = function (serverContextHandle, cookieToken) { if (cookieToken) { var contextInfo = this.sessionMap.get(cookieToken); contextInfo.serverContextHandle = serverContextHandle; return; } this.serverContextHandle = serverContextHandle; }; ServerContextHandleManager.prototype.getServerContextHandle = function (cookieToken) { if (cookieToken) { var contextInfo = this.sessionMap.get(cookieToken); return contextInfo.serverContextHandle; } return this.serverContextHandle; }; ServerContextHandleManager.prototype.release = function (cookieToken) { if (cookieToken) { this.sessionMap["delete"](cookieToken); return; } if (this.authItem) { clearTimeout(this.authItem.timeout); } this.serverContextHandle = undefined; this.authItem = undefined; if (this.queue.length > 0) { // it means another client B was waiting for authenticating. // so we start authenticating this client B. this.authItem = this.queue.shift(); debug('releasing. queue length', this.queue.length); this.authItem.resolve(); } }; /** * Used only when a negotiate connection * does not go to its final state before timeout. * * Note: Do not interfer with cookies. * * @param {AuthItem} authItem * @returns * @memberof ServerContextHandleManager */ ServerContextHandleManager.prototype.tooLate = function (authItem) { while (this.queue.length > 0) { var ai = this.queue.shift(); clearTimeout(ai.timeout); this.authItem.reject(); } this.authItem = authItem; this.authItem.resolve(); }; ServerContextHandleManager.prototype.setMethod = function (method, cookieToken) { if (cookieToken) { var contextInfo = this.sessionMap.get(cookieToken); contextInfo.method = method; return; } this.method = method; }; ServerContextHandleManager.prototype.getMethod = function (cookieToken) { if (cookieToken) { var contextInfo = this.sessionMap.get(cookieToken); return contextInfo.method; } return this.method; }; return ServerContextHandleManager; }()); exports.ServerContextHandleManager = ServerContextHandleManager;