"use strict";
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
Object.defineProperty(exports, "__esModule", { value: true });
const http = require("http");
const https = require("https");
const _ = require("underscore");
const ntlm = require("../opensource/Node-SMB/lib/ntlm");
class NtlmCredentialHandler {
    constructor(username, password, workstation, domain) {
        this._ntlmOptions = {};
        this._ntlmOptions.username = username;
        this._ntlmOptions.password = password;
        this._ntlmOptions.domain = domain || '';
        this._ntlmOptions.workstation = workstation || '';
    }
    prepareRequest(options) {
        // No headers or options need to be set.  We keep the credentials on the handler itself.
        // If a (proxy) agent is set, remove it as we don't support proxy for NTLM at this time
        if (options.agent) {
            delete options.agent;
        }
    }
    canHandleAuthentication(response) {
        if (response && response.message && response.message.statusCode === 401) {
            // Ensure that we're talking NTLM here
            // Once we have the www-authenticate header, split it so we can ensure we can talk NTLM
            const wwwAuthenticate = response.message.headers['www-authenticate'];
            return wwwAuthenticate && (wwwAuthenticate.split(', ').indexOf("NTLM") >= 0);
        }
        return false;
    }
    handleAuthentication(httpClient, requestInfo, objs) {
        return new Promise((resolve, reject) => {
            const callbackForResult = function (err, res) {
                if (err) {
                    reject(err);
                }
                // We have to readbody on the response before continuing otherwise there is a hang.
                res.readBody().then(() => {
                    resolve(res);
                });
            };
            this.handleAuthenticationPrivate(httpClient, requestInfo, objs, callbackForResult);
        });
    }
    handleAuthenticationPrivate(httpClient, requestInfo, objs, finalCallback) {
        // Set up the headers for NTLM authentication
        requestInfo.options = _.extend(requestInfo.options, {
            username: this._ntlmOptions.username,
            password: this._ntlmOptions.password,
            domain: this._ntlmOptions.domain,
            workstation: this._ntlmOptions.workstation
        });
        requestInfo.options.agent = httpClient.isSsl ?
            new https.Agent({ keepAlive: true }) :
            new http.Agent({ keepAlive: true });
        let self = this;
        // The following pattern of sending the type1 message following immediately (in a setImmediate) is
        // critical for the NTLM exchange to happen.  If we removed setImmediate (or call in a different manner)
        // the NTLM exchange will always fail with a 401.
        this.sendType1Message(httpClient, requestInfo, objs, function (err, res) {
            if (err) {
                return finalCallback(err, null, null);
            }
            /// We have to readbody on the response before continuing otherwise there is a hang.
            res.readBody().then(() => {
                // It is critical that we have setImmediate here due to how connection requests are queued.
                // If setImmediate is removed then the NTLM handshake will not work.
                // setImmediate allows us to queue a second request on the same connection. If this second
                // request is not queued on the connection when the first request finishes then node closes
                // the connection. NTLM requires both requests to be on the same connection so we need this.
                setImmediate(function () {
                    self.sendType3Message(httpClient, requestInfo, objs, res, finalCallback);
                });
            });
        });
    }
    // The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
    sendType1Message(httpClient, requestInfo, objs, finalCallback) {
        const type1HexBuffer = ntlm.encodeType1(this._ntlmOptions.workstation, this._ntlmOptions.domain);
        const type1msg = `NTLM ${type1HexBuffer.toString('base64')}`;
        const type1options = {
            headers: {
                'Connection': 'keep-alive',
                'Authorization': type1msg
            },
            timeout: requestInfo.options.timeout || 0,
            agent: requestInfo.httpModule,
        };
        const type1info = {};
        type1info.httpModule = requestInfo.httpModule;
        type1info.parsedUrl = requestInfo.parsedUrl;
        type1info.options = _.extend(type1options, _.omit(requestInfo.options, 'headers'));
        return httpClient.requestRawWithCallback(type1info, objs, finalCallback);
    }
    // The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
    sendType3Message(httpClient, requestInfo, objs, res, callback) {
        if (!res.message.headers && !res.message.headers['www-authenticate']) {
            throw new Error('www-authenticate not found on response of second request');
        }
        /**
         * Server will respond with challenge/nonce
         * assigned to response's "WWW-AUTHENTICATE" header
         * and should adhere to RegExp /^NTLM\s+(.+?)(,|\s+|$)/
         */
        const serverNonceRegex = /^NTLM\s+(.+?)(,|\s+|$)/;
        const serverNonce = Buffer.from((res.message.headers['www-authenticate'].match(serverNonceRegex) || [])[1], 'base64');
        let type2msg;
        /**
         * Wrap decoding the Server's challenge/nonce in
         * try-catch block to throw more comprehensive
         * Error with clear message to consumer
         */
        try {
            type2msg = ntlm.decodeType2(serverNonce);
        }
        catch (error) {
            throw new Error(`Decoding Server's Challenge to Obtain Type2Message failed with error: ${error.message}`);
        }
        const type3msg = ntlm.encodeType3(this._ntlmOptions.username, this._ntlmOptions.workstation, this._ntlmOptions.domain, type2msg, this._ntlmOptions.password).toString('base64');
        const type3options = {
            headers: {
                'Authorization': `NTLM ${type3msg}`,
                'Connection': 'Close'
            },
            agent: requestInfo.httpModule,
        };
        const type3info = {};
        type3info.httpModule = requestInfo.httpModule;
        type3info.parsedUrl = requestInfo.parsedUrl;
        type3options.headers = _.extend(type3options.headers, requestInfo.options.headers);
        type3info.options = _.extend(type3options, _.omit(requestInfo.options, 'headers'));
        return httpClient.requestRawWithCallback(type3info, objs, callback);
    }
}
exports.NtlmCredentialHandler = NtlmCredentialHandler;
