<commit_before>var async = require('async'),
	constants = require('./constants'),
	https = require('https'),
	querystring = require('querystring'),
	readline = require('readline');

exports.die = function die() {
	var args = Array.prototype.slice.call(arguments, 0);
	if (args[0]) {
		args[0] = 'error: ' + args[0];
	}
	console.error.apply(console, args);
	process.exit(1);
};

exports.maybeCallback = function maybeCallback(cb) {
	return cb && exports.isFunction(cb) ? cb : function(err) { if (err) { throw err; } };
};

['Function','String'].forEach(function(type) {
	exports['is' + type] = function(o) {
		return Object.prototype.toString.call(o) === '[object ' + type + ']';
	};
});

exports.authenticate = function authenticate(opts, callback) {
	var funcs = [];
	callback = exports.maybeCallback(arguments[arguments.length-1]);
	if (!opts || exports.isFunction(opts)) {
		opts = {};
	}

	if (typeof opts.prompt === 'undefined') {
		opts.prompt = true;
	}

	// validate input
	if (!opts.prompt) {
		if (!opts.username || !exports.isString(opts.username)) {
			return callback('username required and must be a string');
		} else if (!opts.password || !exports.isString(opts.password)) {
			return callback('password required and must be a string');
		}
	}

	// pass opts into async
	funcs.push(function(cb) { return cb(null, opts); });

	// prompt for username and password, if necessary
	['username','password'].forEach(function(field) {
		if (!opts[field]) {
			funcs.push(function(opts, cb) {
				promptFor(field, function(data) {
					opts[field] = data;
					return cb(null, opts);
				});
			});
		}
	});

	// authenticate
	funcs.push(function(opts, callback) {
		return exports.doRequest(
			constants.AUTH_API,
			{
				host: opts.host,
				port: opts.port,
				postObject: {
					username: opts.username,
					password: <PASSWORD>
				},
				success: function(res) {
					try {
						opts.cookie = res.headers['set-cookie'][0];
						return callback(null, opts);
					} catch (e) {
						e.message = 'failed to retrieve cookie from response headers.\n';
						e.headers = res.headers;
						return callback(e);
					}
				}
			},
			callback
		);
	});

	// auth then enable app
	async.waterfall(funcs, callback);

};

exports.doRequest = function doRequest(api, opts, callback) {
	var postData = querystring.stringify(opts.postObject || {}),
		method = opts.method || 'POST',
		httpsOpts = {
			host: opts.host || constants.MW_HOST,
			port: opts.port || constants.MW_PORT,
			method: method,
			path: api,
			headers: method === 'POST' ? {
				'Content-Type': 'application/x-www-form-urlencoded',
				'Content-Length': postData.length
			} : {}
		};

	// add cookie, if present
	if (opts.cookie) {
		httpsOpts.headers.Cookie = opts.cookie;
	}

	// make https auth call
	var req = https.request(httpsOpts, function(res) {

		// compose date from request
		var data = '';
		res.on('data', function(chunk) {
			data += chunk;
		});

		// handle request
		res.on('end', function() {

			// handle error codes
			if (res.statusCode !== 200) {
				res.data = data;
				return callback(res);
			}

			// process data in success handler
			return opts.success(res, data);
		});

	});

	// error with request
	req.on('error', function(e) {
		return callback(e);
	});

	req.write(postData);
	req.end();
};

function promptFor(field, callback) {
	var stdin = process.openStdin(),
		query = field + ': ',
		rl = readline.createInterface({
			input: process.stdin,
			output: process.stdout
		});

	process.stdin.setEncoding('utf8');
	process.stdin.on('data', function(char) {
		switch(char) {
			case '\n':
			case '\r':
			case '\u0004':
				stdin.pause();
				break;
			default:
				if (field === 'password') {
					process.stdout.write("\033[2K\033[200D" + query);
				}
				break;
		}
	});
	rl.question(query, callback);
}
<commit_msg>use environment variables for auth<commit_after>var async = require('async'),
	constants = require('./constants'),
	https = require('https'),
	querystring = require('querystring'),
	readline = require('readline');

exports.die = function die() {
	var args = Array.prototype.slice.call(arguments, 0);
	if (args[0]) {
		args[0] = 'error: ' + args[0];
	}
	console.error.apply(console, args);
	process.exit(1);
};

exports.maybeCallback = function maybeCallback(cb) {
	return cb && exports.isFunction(cb) ? cb : function(err) { if (err) { throw err; } };
};

['Function','String'].forEach(function(type) {
	exports['is' + type] = function(o) {
		return Object.prototype.toString.call(o) === '[object ' + type + ']';
	};
});

exports.authenticate = function authenticate(opts, callback) {
	var funcs = [];
	callback = exports.maybeCallback(arguments[arguments.length-1]);
	if (!opts || exports.isFunction(opts)) {
		opts = {};
	}

	opts.username = opts.username || process.env.APPC_360_USERNAME;
	opts.password = opts.password || <PASSWORD>;
	if (typeof opts.prompt === 'undefined') {
		opts.prompt = true;
	}

	// validate input
	if (!opts.prompt) {
		if (!opts.username || !exports.isString(opts.username)) {
			return callback('username required and must be a string');
		} else if (!opts.password || !exports.isString(opts.password)) {
			return callback('password required and must be a string');
		}
	}

	// pass opts into async
	funcs.push(function(cb) { return cb(null, opts); });

	// prompt for username and password, if necessary
	['username','password'].forEach(function(field) {
		if (!opts[field]) {
			funcs.push(function(opts, cb) {
				promptFor(field, function(data) {
					opts[field] = data;
					return cb(null, opts);
				});
			});
		}
	});

	// authenticate
	funcs.push(function(opts, callback) {
		return exports.doRequest(
			constants.AUTH_API,
			{
				host: opts.host,
				port: opts.port,
				postObject: {
					username: opts.username,
					password: <PASSWORD>
				},
				success: function(res) {
					try {
						opts.cookie = res.headers['set-cookie'][0];
						return callback(null, opts);
					} catch (e) {
						e.message = 'failed to retrieve cookie from response headers.\n';
						e.headers = res.headers;
						return callback(e);
					}
				}
			},
			callback
		);
	});

	// auth then enable app
	async.waterfall(funcs, callback);

};

exports.doRequest = function doRequest(api, opts, callback) {
	var postData = querystring.stringify(opts.postObject || {}),
		method = opts.method || 'POST',
		httpsOpts = {
			host: opts.host || constants.MW_HOST,
			port: opts.port || constants.MW_PORT,
			method: method,
			path: api,
			headers: method === 'POST' ? {
				'Content-Type': 'application/x-www-form-urlencoded',
				'Content-Length': postData.length
			} : {}
		};

	// add cookie, if present
	if (opts.cookie) {
		httpsOpts.headers.Cookie = opts.cookie;
	}

	// make https auth call
	var req = https.request(httpsOpts, function(res) {

		// compose date from request
		var data = '';
		res.on('data', function(chunk) {
			data += chunk;
		});

		// handle request
		res.on('end', function() {

			// handle error codes
			if (res.statusCode !== 200) {
				res.data = data;
				return callback(res);
			}

			// process data in success handler
			return opts.success(res, data);
		});

	});

	// error with request
	req.on('error', function(e) {
		return callback(e);
	});

	req.write(postData);
	req.end();
};

function promptFor(field, callback) {
	var stdin = process.openStdin(),
		query = field + ': ',
		rl = readline.createInterface({
			input: process.stdin,
			output: process.stdout
		});

	process.stdin.setEncoding('utf8');
	process.stdin.on('data', function(char) {
		switch(char) {
			case '\n':
			case '\r':
			case '\u0004':
				stdin.pause();
				break;
			default:
				if (field === 'password') {
					process.stdout.write("\033[2K\033[200D" + query);
				}
				break;
		}
	});
	rl.question(query, callback);
}

{'fraction_non_alphanumeric': 0.17020732019452264, 'fraction_numerical': 0.006782697722037369, 'mean_word_length': 3.3152954168967423, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5847446', 'n_tokens_mistral': 3031, 'n_tokens_neox': 2580, 'n_words': 576}