"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.authenticate = void 0;
const binary_1 = __importDefault(require("binary"));
const domain_1 = __importDefault(require("domain"));
const constants_1 = require("./constants");
/**
 * +----+------+----------+------+----------+
 * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
 * +----+------+----------+------+----------+
 * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
 * +----+------+----------+------+----------+
 *
 *
 * @param {Buffer} buffer - a buffer
 * @returns {undefined}
 **/
function authenticate({ socket, buffer, options, connect, end, onAuthenticated, onFailed, }) {
    const authDomain = domain_1.default.create();
    binary_1.default
        .stream(buffer)
        .word8('version')
        .word8('ulen')
        .buffer('username', 'ulen')
        .word8('plen')
        .buffer('password', 'plen')
        .tap((args) => {
        // capture the raw buffer
        args.requestBuffer = buffer;
        // verify version is appropriate
        if (args.version !== constants_1.RFC_1929_VERSION) {
            return end(constants_1.RFC_1929_REPLIES.GENERAL_FAILURE, args);
        }
        authDomain.on('error', (err) => {
            // emit failed authentication event
            onFailed(args, err);
            // respond with auth failure
            return end(constants_1.RFC_1929_REPLIES.GENERAL_FAILURE, args);
        });
        // perform authentication
        options.authenticate(args.username.toString(), args.password.toString(), socket, authDomain.intercept(() => {
            // emit successful authentication event
            onAuthenticated(args);
            // respond with success...
            const responseBuffer = Buffer.allocUnsafe(2);
            responseBuffer[0] = constants_1.RFC_1929_VERSION;
            responseBuffer[1] = constants_1.RFC_1929_REPLIES.SUCCEEDED;
            // respond then listen for cmd and dst info
            socket.write(responseBuffer, () => {
                // now listen for more details
                socket.once('data', connect);
            });
        }));
    });
}
exports.authenticate = authenticate;
//# sourceMappingURL=authenticate.js.map