<commit_before>var Buffer   = require('buffer').Buffer,
    dgram    = require('dgram'),
    BitArray = require('node-bitarray'),
    ip       = require('ip'),
    http     = require('http');

// Cat- serving server.
var catServer = http.createServer(function (request, response) {
  // TODO: Serve actual cats.
  response.writeHead(200);
  response.end("= ^__^ =\n");
});
catServer.listen(80);

// DNS Server.
var dnsServer = dgram.createSocket('udp4');
dnsServer.bind(53, 'localhost');

// Fields and their bit sizes in the different message sections, as defined by the DNS spec.
var headerSection = [
  {name:"id", bits: 16},
  {name:"qr", bits: 1},
  {name:"opcode", bits: 4},
  {name:"aa", bits: 1},
  {name:"tc", bits: 1},
  {name:"rd", bits: 1},
  {name:"ra", bits: 1},
  {name:"z", bits: 3},  // Reserved fields, always 0.
  {name:"rcode", bits: 4},
  {name:"qd_count", bits: 16},
  {name:"an_count", bits: 16},
  {name:"ns_count", bits: 16},
  {name:"ar_count", bits: 16}
];

var questionSection = [
  {name:"qname", bits: -1},  // 32 bits from the end :(
  {name:"qtype", bits: 16},
  {name:"qclass", bits: 16}
];

var answerSection = [
  {name:"qname", bits: -1},  // Same as the question qname
  {name:"qtype", bits: 16},
  {name:"qclass", bits: 16},
  {name:"ttl", bits: 32},
  {name:"rlength", bits:16},
  {name:"rdata", bits: 32},
];

dnsServer.on('message', function (msg, rinfo) {
  var query = parseQuestion(new BitArray.fromBuffer(msg));
  console.log(query);
  var cat = createCatAnswer(query);
  console.log(cat);
  var answer = cat.toBuffer();

  dnsServer.send(answer, 0, answer.length, rinfo.port, rinfo.address, function (err, sent) {
    console.log("and you get a cat: ", rinfo.port, rinfo.address);
  });
});

dnsServer.addListener('error', function (e) {
  console.log("Oh no, cat error", e);
  throw e;
});

function DNSMessage() {
  this.header = {};
  this.question = {};
  this.answer = {};
  this.toBuffer = function() {
    var giantBinaryString = "";

    for (var i = 0; i < headerSection.length; i++)
      giantBinaryString += this.header[headerSection[i].name];

    for (var i = 0; i < answerSection.length; i++)
      giantBinaryString += this.answer[answerSection[i].name];

    console.log(giantBinaryString);

    return getBinaryStringAsBuffer(giantBinaryString);
  }
}

function parseQuestion(msg) {
  var query = new DNSMessage();

  // Header section.
  var startBit = 0;
  for (var i = 0; i < headerSection.length; i++) {
    var bitsPerField = headerSection[i].bits;
    var field = headerSection[i].name;
    query.header[field] =  getBitSequenceAsString(msg, startBit, bitsPerField);
    startBit += bitsPerField;
  }

  // Question Section.
  // Calculate the length of the qname field, as it isn't set.
  var qnameLength = msg.length - startBit - 2 * 16;
  questionSection[0].bits = qnameLength;

  for (var i = 0; i < questionSection.length; i++) {
    var bitsPerField = questionSection[i].bits;
    var field = questionSection[i].name;
    query.question[field] = getBitSequenceAsString(msg, startBit, bitsPerField);
    startBit += bitsPerField;
  }

  return query;
}

function createCatAnswer(query) {
  var cat = new DNSMessage();
  cat.header = query.header;
  cat.question = query.question;

  // Hardcoded answer fields.
  cat.header.qr = '1';
  cat.header.aa = '0';
  cat.header.tc = '0';
  cat.header.ra = '0';
  cat.header.rcode = '0000';
  cat.header.an_count = cat.header.qd_count;
  cat.header.qd_count = cat.header.ns_count;

  // Surely there's a better way.
  cat.answer.qname = query.question.qname;
  cat.answer.qtype = '0000000000000001'; // A
  cat.answer.qclass = '0000000000000001'; // Internet
  cat.answer.ttl = '00000000000000000000000000000001'; // Seconds to cache the answer for;
  cat.answer.rlength = '0000000000000100'; // 4 bytes long.

  //var l = ip.toLong("173.236.227.244");
  var l = ip.toLong("127.0.0.1");
  cat.answer.rdata = reverseString(new BitArray.from32Integer(l).toString());

  console.log("------ cat!" , cat);
  return cat;
}

// Utilities to make things less suck.
function getBitSequenceAsString(bitArray, startBit, numBits) {
  var s = "";
  for (var i = 0; i < numBits; i++ ) {
    s += bitArray.get(startBit + i);
  }
  return s;
}

function getBinaryStringAsBuffer(s) {
  // TODO: I don't know why I need this to be reversed. Blerg.
  // Maybe BitArrays save things backwards?
  return BitArray.fromBinary(reverseString(s)).toBuffer();
}

function reverseString(s) {
  return s.split('').reverse().join('');
}

<commit_msg>some refactoring.<commit_after>var Buffer   = require('buffer').Buffer,
    dgram    = require('dgram'),
    BitArray = require('node-bitarray'),
    ip       = require('ip'),
    http     = require('http');

// Cat- serving server.
var catServer = http.createServer(function (request, response) {
  // TODO: Serve actual cats.
  response.writeHead(200);
  response.end("= ^__^ =\n");
});
catServer.listen(80);

// DNS Server.
var dnsServer = dgram.createSocket('udp4');
dnsServer.bind(53, 'localhost');

dnsServer.on('message', function (msg, rinfo) {
  var start = new Date().getTime();
  var query = parseQuestion(new BitArray.fromBuffer(msg));
  var queryEnd = new Date().getTime();

  var answer = createCatAnswer(query);
  var answerEnd = new Date().getTime();

  var buffer = answer.toBuffer();
  var bufferEnd = new Date().getTime();

  console.log("parse question: %s ms, assemble answer %s ms, convert buffer %s ms",
      queryEnd - start, answerEnd - queryEnd, bufferEnd - answerEnd);

  dnsServer.send(buffer, 0, buffer.length, rinfo.port, rinfo.address, function (err, sent) {
    console.log("and you (%s:%s) get a cat after %s ms: ",
       rinfo.address, rinfo.port, (new Date().getTime() - bufferEnd));
  });
});

dnsServer.addListener('error', function (e) {
  console.log("Oh no, cat error", e);
  throw e;
});

function parseQuestion(msg) {
  var query = new DNSMessage();

  var startBit = query.assemble(query.header, DNSSpec.header, msg, 0);

  // Calculate the length of the qname field, as it isn't constant.
  var qnameLength = msg.length - startBit - 2 * 16;
  DNSSpec.question[0].bits = qnameLength;
  query.assemble(query.question, DNSSpec.question, msg, startBit);

  return query;
}

function createCatAnswer(query) {
  var cat = new DNSMessage();
  cat.header = query.header;
  cat.question = query.question;
  cat.answer.qname = query.question.qname;
  cat.transmogrifyIntoAnswer();

  var fakeCat = ip.toLong("127.0.0.1");
  cat.answer.rdata = reverseString(new BitArray.from32Integer(fakeCat).toString());
  return cat;
}

/*
 * DNS Message
 */

// Fields and their bit sizes in the different message sections, as defined by the DNS spec.
var DNSSpec = {
 header: [
  {name:"id", bits: 16},
  {name:"qr", bits: 1},
  {name:"opcode", bits: 4},
  {name:"aa", bits: 1},
  {name:"tc", bits: 1},
  {name:"rd", bits: 1},
  {name:"ra", bits: 1},
  {name:"z", bits: 3},  // Reserved fields, always 0.
  {name:"rcode", bits: 4},
  {name:"qd_count", bits: 16},
  {name:"an_count", bits: 16},
  {name:"ns_count", bits: 16},
  {name:"ar_count", bits: 16}],
question: [
  {name:"qname", bits: -1},  // 32 bits from the end :(
  {name:"qtype", bits: 16},
  {name:"qclass", bits: 16}],
answer: [
  {name:"qname", bits: -1},  // Same as the question qname
  {name:"qtype", bits: 16},
  {name:"qclass", bits: 16},
  {name:"ttl", bits: 32},
  {name:"rlength", bits:16},
  {name:"rdata", bits: 32}]
};

function DNSMessage() {
  this.header = {};
  this.question = {};
  this.answer = {};
  this.toBuffer = function() {
    var giantBinaryString = "";

    for (var i = 0; i < DNSSpec.header.length; i++)
      giantBinaryString += this.header[DNSSpec.header[i].name];

    for (var i = 0; i < DNSSpec.answer.length; i++)
      giantBinaryString += this.answer[DNSSpec.answer[i].name];

    return getBinaryStringAsBuffer(giantBinaryString);
  }

  this.assemble = function(section, fieldNames, msg, startBit) {
    for (var i = 0; i < fieldNames.length; i++) {
      var bitsPerField = fieldNames[i].bits;
      var field = fieldNames[i].name;
      section[field] =  getBitSequenceAsString(msg, startBit, bitsPerField);
      startBit += bitsPerField;
    }
    return startBit;
  }

  this.transmogrifyIntoAnswer = function() {
    // Hardcoded answer fields.
    this.header.qr = '1';
    this.header.aa = '0';
    this.header.tc = '0';
    this.header.ra = '0';
    this.header.rcode = '0000';
    this.header.an_count = this.header.qd_count;
    this.header.qd_count = this.header.ns_count;

    // Surely there's a better way.
    this.answer.qtype = '0000000000000001'; // A
    this.answer.qclass = '0000000000000001'; // Internet
    this.answer.ttl = '00000000000000000000000000000001'; // Seconds to cache the answer for;
    this.answer.rlength = '0000000000000100'; // 4 bytes long.
  }
}

/*
 * Utilities to make things less suck.
 */

function getBitSequenceAsString(bitArray, startBit, numBits) {
  var s = "";
  for (var i = 0; i < numBits; i++ )
    s += bitArray.get(startBit + i);
  return s;
}

function getBinaryStringAsBuffer(s) {
  // TODO: I don't know why I need this to be reversed. Blerg.
  // Maybe BitArrays save things backwards?
  return BitArray.fromBinary(reverseString(s)).toBuffer();
}

function reverseString(s) {
  return s.split('').reverse().join('');
}

<|endoftext|>


<commit_before>let ShortKey = {}
let mapFunctions = {}
let objAvoided = []
let elementAvoided = []

ShortKey.install = function (Vue, options) {
  elementAvoided = [...options.prevent]
  Vue.directive('shortkey', {
    bind: function (el, binding, vnode) {
      // Mapping the commands
      let k = ''
      let b = binding.modifiers
      let pushButton = false
      if (b.hasOwnProperty('shift')) { k += 'shift'; delete b.shift }
      if (b.hasOwnProperty('ctrl')) { k += 'ctrl'; delete b.ctrl }
      if (b.hasOwnProperty('alt')) { k += 'alt'; delete b.alt }
      if (b.hasOwnProperty('altgraph')) { k += 'altgraph'; delete b.altgraph }
      if (b.hasOwnProperty('push')) { pushButton = true; delete b.push }
      if (b.hasOwnProperty('void')) { objAvoided.push(el); delete b.void }
      if (Object.keys(b).length > 0) { k += Object.keys(b)[0].toLowerCase() }
      mapFunctions[k] = {
        'ps': pushButton,
        'fn': vnode.context.$vnode.child[binding.expression],
        'el': vnode.elm
      }
    }
  })
}

ShortKey.decodeKey = function (pKey) {
  let k = ''
  if (pKey.key === 'Shift' || pKey.shiftKey === true) { k += 'shift' }
  if (pKey.key === 'Control' || pKey.ctrlKey === true) { k += 'ctrl' }
  if (pKey.key === 'Alt' || pKey.altKey === true) { k += 'alt' }
  if (pKey.key === 'ArrowUp') { k += 'arrowup' }
  if (pKey.key === 'ArrowLeft') { k += 'arrowleft' }
  if (pKey.key === 'ArrowRight') { k += 'arrowright' }
  if (pKey.key === 'ArrowDown') { k += 'arrowdown' }
  if (pKey.key === 'AltGraph') { k += 'altgraph' }
  if ((pKey.key && pKey.key.length === 1) || /F\d{1,2}/g.test(pKey.key)) k += pKey.key.toLowerCase()
  return k
}

ShortKey.keyDown = function (pKey) {
  if (mapFunctions[pKey]) {
    mapFunctions[pKey].fn()
  }
}
ShortKey.keyUp = function (pKey) {
  if (mapFunctions[pKey]) {
    mapFunctions[pKey].fn()
  }
}

;(function () {
  document.addEventListener('keydown', (pKey) => {
    let decodedKey = ShortKey.decodeKey(pKey)
    if (mapFunctions[decodedKey] && !objAvoided.find(r => r === document.activeElement) && !elementAvoided.find(r => r === document.activeElement.tagName.toLowerCase() )) {
      pKey.preventDefault()
      pKey.stopPropagation()
      if (mapFunctions[decodedKey].fn) {
        ShortKey.keyDown(decodedKey)
      } else {
        mapFunctions[decodedKey].el.focus()
      }
    }
  }, true)
  document.addEventListener('keyup', (pKey) => {
    let decodedKey = ShortKey.decodeKey(pKey)
    if (mapFunctions[decodedKey] && !mapFunctions[decodedKey].fn === 'void') {
      pKey.preventDefault()
      pKey.stopPropagation()
      if (mapFunctions[decodedKey].ps) {
        ShortKey.keyUp(decodedKey)
      }
    }
  }, true)
})()

module.exports = ShortKey
<commit_msg>Fix options array<commit_after>let ShortKey = {}
let mapFunctions = {}
let objAvoided = []
let elementAvoided = []

ShortKey.install = function (Vue, options) {
  elementAvoided = [...(options && options.prevent ? options.prevent : [])]
  Vue.directive('shortkey', {
    bind: function (el, binding, vnode) {
      // Mapping the commands
      let k = ''
      let b = binding.modifiers
      let pushButton = false
      if (b.hasOwnProperty('shift')) { k += 'shift'; delete b.shift }
      if (b.hasOwnProperty('ctrl')) { k += 'ctrl'; delete b.ctrl }
      if (b.hasOwnProperty('alt')) { k += 'alt'; delete b.alt }
      if (b.hasOwnProperty('altgraph')) { k += 'altgraph'; delete b.altgraph }
      if (b.hasOwnProperty('push')) { pushButton = true; delete b.push }
      if (b.hasOwnProperty('void')) { objAvoided.push(el); delete b.void }
      if (Object.keys(b).length > 0) { k += Object.keys(b)[0].toLowerCase() }
      mapFunctions[k] = {
        'ps': pushButton,
        'fn': vnode.context.$vnode.child[binding.expression],
        'el': vnode.elm
      }
    }
  })
}

ShortKey.decodeKey = function (pKey) {
  let k = ''
  if (pKey.key === 'Shift' || pKey.shiftKey === true) { k += 'shift' }
  if (pKey.key === 'Control' || pKey.ctrlKey === true) { k += 'ctrl' }
  if (pKey.key === 'Alt' || pKey.altKey === true) { k += 'alt' }
  if (pKey.key === 'ArrowUp') { k += 'arrowup' }
  if (pKey.key === 'ArrowLeft') { k += 'arrowleft' }
  if (pKey.key === 'ArrowRight') { k += 'arrowright' }
  if (pKey.key === 'ArrowDown') { k += 'arrowdown' }
  if (pKey.key === 'AltGraph') { k += 'altgraph' }
  if ((pKey.key && pKey.key.length === 1) || /F\d{1,2}/g.test(pKey.key)) k += pKey.key.toLowerCase()
  return k
}

ShortKey.keyDown = function (pKey) {
  if (mapFunctions[pKey]) {
    mapFunctions[pKey].fn()
  }
}
ShortKey.keyUp = function (pKey) {
  if (mapFunctions[pKey]) {
    mapFunctions[pKey].fn()
  }
}

;(function () {
  document.addEventListener('keydown', (pKey) => {
    let decodedKey = ShortKey.decodeKey(pKey)
    if (mapFunctions[decodedKey] && !objAvoided.find(r => r === document.activeElement) && !elementAvoided.find(r => r === document.activeElement.tagName.toLowerCase() )) {
      pKey.preventDefault()
      pKey.stopPropagation()
      if (mapFunctions[decodedKey].fn) {
        ShortKey.keyDown(decodedKey)
      } else {
        mapFunctions[decodedKey].el.focus()
      }
    }
  }, true)
  document.addEventListener('keyup', (pKey) => {
    let decodedKey = ShortKey.decodeKey(pKey)
    if (mapFunctions[decodedKey] && !mapFunctions[decodedKey].fn === 'void') {
      pKey.preventDefault()
      pKey.stopPropagation()
      if (mapFunctions[decodedKey].ps) {
        ShortKey.keyUp(decodedKey)
      }
    }
  }, true)
})()

module.exports = ShortKey
<|endoftext|>


<commit_before>var stream   = require('stream');
var util     = require('util');
var strftime = require('strftime');
var aws      = require('aws-sdk');
var branch   = require('git-branch');
var os       = require('os');
var zlib     = require('zlib');

// Constants

var SERVER_SIDE_ENCRYPTION = "AES256";
var CONTENT_TYPE_PLAIN_TEXT = "text/plain";

// Public API

function S3StreamLogger(options){
    stream.Writable.call(this, options);

    if(!(options.bucket || process.env.BUCKET_NAME))
        throw new Error("options.bucket or BUCKET_NAME environment variable is required");

    this.bucket                 = options.bucket || process.env.BUCKET_NAME;
    this.folder                 = options.folder || '';
    this.tags                   = options.tags || {};                  // no tags are assigned by default
    this.name_format            = options.name_format;
    this.rotate_every           = options.rotate_every  || 60*60*1000; // default to 60 minutes
    this.max_file_size          = options.max_file_size || 200000;     // or 200k, whichever is sooner
    this.upload_every           = options.upload_every  || 20*1000;    // default to 20 seconds
    this.buffer_size            = options.buffer_size   || 10000;      // or every 10k, which ever is sooner
    this.server_side_encryption = options.server_side_encryption || false;
    this.acl                    = options.acl || false;
    this.compress               = options.compress || false;

    // Validating input storage_class parameter & setting default storage_class - STANDARD
    options.storage_class = options.storage_class || 'STANDARD';
    if(['STANDARD', 'REDUCED_REDUNDANCY', 'STANDARD_IA', 'ONEZONE_IA','INTELLIGENT_TIERING', 'GLACIER', 'DEEP_ARCHIVE'].indexOf(options.storage_class) > -1){
        this.storage_class = options.storage_class;
    } else {
        this.storage_class = 'STANDARD';
    }

    // Backwards compatible API changes

    options.config = options.config || {};
    if(options.access_key_id) {
      options.config.accessKeyId = options.access_key_id;
    }
    if(options.secret_access_key) {
      options.config.secretAccessKey = options.secret_access_key;
    }
    if(options.config.sslEnabled === undefined) {
      options.config.sslEnabled = true;
    }
    if(options.region) {
      options.config.region = options.region;
    }
    if(!options.name_format) {
        // Get branch and host name for default file name
        var _current_branch;
        try {
            _current_branch = branch.sync();
        } catch (e) {
            _current_branch = 'unknown'
        }
        var _extension = '.log';
        if(this.compress){
            _extension += '.gz';
        }
        this.name_format = `%Y-%m-%d-%H-%M-%S-%L-${_current_branch}-${os.hostname()}${_extension}`;
    }

    this.s3           = new aws.S3(options.config);
    this.timeout      = null;
    this.object_name  = null;
    this.file_started = null;
    this.last_write   = null;
    this.buffers      = [];
    this.unwritten    = 0;

    this._newFile();
}
util.inherits(S3StreamLogger, stream.Writable);

// write anything outstanding to the current file, and start a new one
S3StreamLogger.prototype.flushFile = function(cb){
    this._upload(true, cb);
};

// Override this function to modify the parameters used when uploading to S3
S3StreamLogger.prototype.putObject = function(param, callback) {
    this.s3.putObject(param, callback);
}

// Private API

S3StreamLogger.prototype._upload = function(forceNewFile, cb) {
    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout = null;
    }
    this.last_write = new Date();

    var saved = {
        buffers: undefined,
        unwritten: this.unwritten,
        object_name: this.object_name
    };
    // if we're erasing the data, then take a temporary copy of it until we
    // know the upload has succeeded. If it fails (either due to compression or
    // upload failure) we will re-instate it:

    this.unwritten = 0;
    var elapsed = (new Date()).getTime() - this.file_started.getTime();
    var reset_buffers = false;
    if(forceNewFile ||
       elapsed > this.rotate_every ||
       this._fileSize() > this.max_file_size){
        saved.buffers = this.buffers;
        reset_buffers = true;
    }

    this._prepareBuffer(function(err, buffer){
        if(err){
            this._restoreUnwritten(saved.unwritten, saved.object_name, saved.buffers);
            if(cb) {
                cb(err);
            }
            return this.emit('error', err);
        }

        // constructc the tagging string according to AWS SDK specifications
        var tagging = Object.keys(this.tags).map(function(key) {return key + '=' + this.tags[key];}, this).join('&');

        var param  = {
            Bucket: this.bucket,
            Key: this.object_name,
            Body: buffer,
            Tagging: tagging,
            StorageClass: this.storage_class
        };

        if(this.server_side_encryption){
            param.ServerSideEncryption = SERVER_SIDE_ENCRYPTION;
        }

        if(this.acl){
            param.ACL = this.acl;
        }

    // Setting content type to text/plain allows log files to be
        // previewed natively within browsers without downloading.
        if (!this.compress) {
            param.ContentType = CONTENT_TYPE_PLAIN_TEXT;
        }

        // do everything else before calling putObject to avoid the
        // possibility that this._write is called again, losing data.
        this.putObject(param, function(err, data){
            if(err){
                this._restoreUnwritten(saved.unwritten, saved.object_name, saved.buffers);
                if(cb) {
                    cb(err);
                }
                return this.emit('error', err);
            }
            if(cb) {
                cb(null, data);
            }
        }.bind(this));
    }.bind(this));

    if(reset_buffers){
        this._newFile();
    }
};

S3StreamLogger.prototype._prepareBuffer = function(cb) {
    var buffer = Buffer.concat(this.buffers);
    if(this.compress){
        zlib.gzip(buffer, cb);
    }else{
        cb(null, buffer);
    }
    return null;
};

S3StreamLogger.prototype._fileSize = function(){
    return this.buffers.map(function(b){return b.length;}).reduce(function(s, v){return s + v;}, 0);
};

// _newFile should ONLY be called when there is no un-uploaded data (i.e.
// from _upload or initialization), otherwise data will be lost.
S3StreamLogger.prototype._newFile = function(){
    this.buffers      = [];
    this.file_started = new Date();
    this.last_write   = this.file_started;
    // create a date object with the UTC version of the date to use with
    // strftime, so that the commonly use formatters return the UTC values.
    // This breaks timezone-converting specifiers (as they will convert against
    // the wrong timezone).
    var date_as_utc = new Date(
        this.file_started.getUTCFullYear(),
        this.file_started.getUTCMonth(),
        this.file_started.getUTCDate(),
        this.file_started.getUTCHours(),
        this.file_started.getUTCMinutes(),
        this.file_started.getUTCSeconds(),
        this.file_started.getUTCMilliseconds()
    );
    // make sure there aren't multiple trailing slashes on the folder name.
    var folder = (this.folder ? this.folder + '/' : '').replace(/\/+$/, '/');
    this.object_name = folder + strftime(this.name_format, date_as_utc);

};

// restore unwritten data in the event that a write failed.
S3StreamLogger.prototype._restoreUnwritten = function(unwritten, object_name, buffers){
    // If no data was erased, then only the unwritten counter needs correcting:
    this.unwritten += unwritten;
    // If there is data to restore, then switch back to the previous filename
    // and restore it:
    if(typeof buffers !== 'undefined'){
        this.buffers = buffers.concat(this.buffers);
        this.object_name = object_name;
    }
};

S3StreamLogger.prototype._write = function(chunk, encoding, cb){
    if(typeof chunk === 'string')
        chunk = new Buffer(chunk, encoding);

    if(chunk){
        this.buffers.push(chunk);
        this.unwritten += chunk.length;
    }

    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout = null;
    }

    if((new Date()).getTime() - this.last_write.getTime() > this.upload_every ||
       this.unwritten > this.buffer_size){
        this._upload();
    }else{
        this.timeout = setTimeout(function(){
            this._upload();
        }.bind(this), this.upload_every);
    }

    // Call the callback immediately, as we may not actually write for some
    // time. If there is an upload error, we trigger our 'error' event.
    if(cb && typeof cb === 'function')
        setImmediate(cb);
};

S3StreamLogger.prototype._final = function(cb) {
    this._upload(false, cb);
}

module.exports = {
    S3StreamLogger: S3StreamLogger
};

<commit_msg>removed storage class validation & default class set<commit_after>var stream   = require('stream');
var util     = require('util');
var strftime = require('strftime');
var aws      = require('aws-sdk');
var branch   = require('git-branch');
var os       = require('os');
var zlib     = require('zlib');

// Constants

var SERVER_SIDE_ENCRYPTION = "AES256";
var CONTENT_TYPE_PLAIN_TEXT = "text/plain";

// Public API

function S3StreamLogger(options){
    stream.Writable.call(this, options);

    if(!(options.bucket || process.env.BUCKET_NAME))
        throw new Error("options.bucket or BUCKET_NAME environment variable is required");

    this.bucket                 = options.bucket || process.env.BUCKET_NAME;
    this.folder                 = options.folder || '';
    this.tags                   = options.tags || {};                  // no tags are assigned by default
    this.name_format            = options.name_format;
    this.rotate_every           = options.rotate_every  || 60*60*1000; // default to 60 minutes
    this.max_file_size          = options.max_file_size || 200000;     // or 200k, whichever is sooner
    this.upload_every           = options.upload_every  || 20*1000;    // default to 20 seconds
    this.buffer_size            = options.buffer_size   || 10000;      // or every 10k, which ever is sooner
    this.server_side_encryption = options.server_side_encryption || false;
    this.acl                    = options.acl || false;
    this.compress               = options.compress || false;

    // setting S3 object storage class
    this.storage_class = options.storage_class;

    // Backwards compatible API changes

    options.config = options.config || {};
    if(options.access_key_id) {
      options.config.accessKeyId = options.access_key_id;
    }
    if(options.secret_access_key) {
      options.config.secretAccessKey = options.secret_access_key;
    }
    if(options.config.sslEnabled === undefined) {
      options.config.sslEnabled = true;
    }
    if(options.region) {
      options.config.region = options.region;
    }
    if(!options.name_format) {
        // Get branch and host name for default file name
        var _current_branch;
        try {
            _current_branch = branch.sync();
        } catch (e) {
            _current_branch = 'unknown'
        }
        var _extension = '.log';
        if(this.compress){
            _extension += '.gz';
        }
        this.name_format = `%Y-%m-%d-%H-%M-%S-%L-${_current_branch}-${os.hostname()}${_extension}`;
    }

    this.s3           = new aws.S3(options.config);
    this.timeout      = null;
    this.object_name  = null;
    this.file_started = null;
    this.last_write   = null;
    this.buffers      = [];
    this.unwritten    = 0;

    this._newFile();
}
util.inherits(S3StreamLogger, stream.Writable);

// write anything outstanding to the current file, and start a new one
S3StreamLogger.prototype.flushFile = function(cb){
    this._upload(true, cb);
};

// Override this function to modify the parameters used when uploading to S3
S3StreamLogger.prototype.putObject = function(param, callback) {
    this.s3.putObject(param, callback);
}

// Private API

S3StreamLogger.prototype._upload = function(forceNewFile, cb) {
    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout = null;
    }
    this.last_write = new Date();

    var saved = {
        buffers: undefined,
        unwritten: this.unwritten,
        object_name: this.object_name
    };
    // if we're erasing the data, then take a temporary copy of it until we
    // know the upload has succeeded. If it fails (either due to compression or
    // upload failure) we will re-instate it:

    this.unwritten = 0;
    var elapsed = (new Date()).getTime() - this.file_started.getTime();
    var reset_buffers = false;
    if(forceNewFile ||
       elapsed > this.rotate_every ||
       this._fileSize() > this.max_file_size){
        saved.buffers = this.buffers;
        reset_buffers = true;
    }

    this._prepareBuffer(function(err, buffer){
        if(err){
            this._restoreUnwritten(saved.unwritten, saved.object_name, saved.buffers);
            if(cb) {
                cb(err);
            }
            return this.emit('error', err);
        }

        // constructc the tagging string according to AWS SDK specifications
        var tagging = Object.keys(this.tags).map(function(key) {return key + '=' + this.tags[key];}, this).join('&');

        var param  = {
            Bucket: this.bucket,
            Key: this.object_name,
            Body: buffer,
            Tagging: tagging,
        };

        if(this.storage_class){
            param.StorageClass = this.storage_class;
        }

        if(this.server_side_encryption){
            param.ServerSideEncryption = SERVER_SIDE_ENCRYPTION;
        }

        if(this.acl){
            param.ACL = this.acl;
        }

    // Setting content type to text/plain allows log files to be
        // previewed natively within browsers without downloading.
        if (!this.compress) {
            param.ContentType = CONTENT_TYPE_PLAIN_TEXT;
        }

        // do everything else before calling putObject to avoid the
        // possibility that this._write is called again, losing data.
        this.putObject(param, function(err, data){
            if(err){
                this._restoreUnwritten(saved.unwritten, saved.object_name, saved.buffers);
                if(cb) {
                    cb(err);
                }
                return this.emit('error', err);
            }
            if(cb) {
                cb(null, data);
            }
        }.bind(this));
    }.bind(this));

    if(reset_buffers){
        this._newFile();
    }
};

S3StreamLogger.prototype._prepareBuffer = function(cb) {
    var buffer = Buffer.concat(this.buffers);
    if(this.compress){
        zlib.gzip(buffer, cb);
    }else{
        cb(null, buffer);
    }
    return null;
};

S3StreamLogger.prototype._fileSize = function(){
    return this.buffers.map(function(b){return b.length;}).reduce(function(s, v){return s + v;}, 0);
};

// _newFile should ONLY be called when there is no un-uploaded data (i.e.
// from _upload or initialization), otherwise data will be lost.
S3StreamLogger.prototype._newFile = function(){
    this.buffers      = [];
    this.file_started = new Date();
    this.last_write   = this.file_started;
    // create a date object with the UTC version of the date to use with
    // strftime, so that the commonly use formatters return the UTC values.
    // This breaks timezone-converting specifiers (as they will convert against
    // the wrong timezone).
    var date_as_utc = new Date(
        this.file_started.getUTCFullYear(),
        this.file_started.getUTCMonth(),
        this.file_started.getUTCDate(),
        this.file_started.getUTCHours(),
        this.file_started.getUTCMinutes(),
        this.file_started.getUTCSeconds(),
        this.file_started.getUTCMilliseconds()
    );
    // make sure there aren't multiple trailing slashes on the folder name.
    var folder = (this.folder ? this.folder + '/' : '').replace(/\/+$/, '/');
    this.object_name = folder + strftime(this.name_format, date_as_utc);

};

// restore unwritten data in the event that a write failed.
S3StreamLogger.prototype._restoreUnwritten = function(unwritten, object_name, buffers){
    // If no data was erased, then only the unwritten counter needs correcting:
    this.unwritten += unwritten;
    // If there is data to restore, then switch back to the previous filename
    // and restore it:
    if(typeof buffers !== 'undefined'){
        this.buffers = buffers.concat(this.buffers);
        this.object_name = object_name;
    }
};

S3StreamLogger.prototype._write = function(chunk, encoding, cb){
    if(typeof chunk === 'string')
        chunk = new Buffer(chunk, encoding);

    if(chunk){
        this.buffers.push(chunk);
        this.unwritten += chunk.length;
    }

    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout = null;
    }

    if((new Date()).getTime() - this.last_write.getTime() > this.upload_every ||
       this.unwritten > this.buffer_size){
        this._upload();
    }else{
        this.timeout = setTimeout(function(){
            this._upload();
        }.bind(this), this.upload_every);
    }

    // Call the callback immediately, as we may not actually write for some
    // time. If there is an upload error, we trigger our 'error' event.
    if(cb && typeof cb === 'function')
        setImmediate(cb);
};

S3StreamLogger.prototype._final = function(cb) {
    this._upload(false, cb);
}

module.exports = {
    S3StreamLogger: S3StreamLogger
};

<|endoftext|>


<commit_before>var path = require('path');
var dir = require('node-dir');
var vow = require('vow');
var fs = require('fs');

function DirTransferPlugin(patterns, srcBasePath, destBasePath) {
    this.patterns = patterns || [];
    this.srcBasePath = srcBasePath;
    this.destBasePath = destBasePath;
}

DirTransferPlugin.prototype.apply = function(compiler) {
    var _this = this;
    var srcBasePath = this.srcBasePath || compiler.options.context || null;
    var destBasePath = this.destBasePath || compiler.options.context || null;

    compiler.plugin('emit', function(compilation, cb) {
        if (!srcBasePath) {
            compilation.errors.push(new Error('DirTransferPlugin: no srcBasePath provided'));
            cb();
        }
        if (!destBasePath) {
            compilation.errors.push(new Error('DirTransferPlugin: no destBasePath provided'));
            cb();
        }

        var promises = [];

        _this.patterns.forEach(function(pattern) {
            promises.push(_this.processDir(path.resolve(srcBasePath, pattern.src), path.resolve(destBasePath, pattern.dest), compilation));
        });

        vow.all(promises).then(function() {
            cb();
        }).fail(function(text) {
            compilation.errors.push(new Error(text));
            cb();
        });
    });
};

DirTransferPlugin.prototype.processDir = function(from, to, compilation) {
    var defer = vow.defer();

    dir.files(from, function(err, files) {
        if (err) {
            defer.reject('DirTransferPlugin: ' + err);
            return;
        }

        var allFiles = files.map(function(fullPath) {
            var fileName = fullPath.replace(from, '');
            var distName = to ? path.join(to, fileName) : fileName;

            compilation.assets[distName] = {
                size: function() {
                    return fs.statSync(fullPath).size;
                },
                source: function() {
                    return fs.readFileSync(fullPath);
                },
            };
        });

        defer.resolve(vow.all(allFiles));
    });

    return defer.promise();
};

module.exports = DirTransferPlugin;
<commit_msg>basePaths correction<commit_after>var path = require('path');
var dir = require('node-dir');
var vow = require('vow');
var fs = require('fs');

function DirTransferPlugin(patterns, basePaths) {
    this.patterns = patterns || [];
    if (basePaths) {
        this.srcBasePath = basePaths.srcBasePath;
        this.destBasePath = basePaths.destBasePath;
    }
}

DirTransferPlugin.prototype.apply = function(compiler) {
    var _this = this;
    var srcBasePath = this.srcBasePath || compiler.options.context || null;
    var destBasePath = this.destBasePath || compiler.options.context || null;

    compiler.plugin('emit', function(compilation, cb) {
        if (!srcBasePath) {
            compilation.errors.push(new Error('DirTransferPlugin: no srcBasePath provided'));
            cb();
        }
        if (!destBasePath) {
            compilation.errors.push(new Error('DirTransferPlugin: no destBasePath provided'));
            cb();
        }

        var promises = [];

        _this.patterns.forEach(function(pattern) {
            promises.push(_this.processDir(path.resolve(srcBasePath, pattern.src), path.resolve(destBasePath, pattern.dest), compilation));
        });

        vow.all(promises).then(function() {
            cb();
        }).fail(function(text) {
            compilation.errors.push(new Error(text));
            cb();
        });
    });
};

DirTransferPlugin.prototype.processDir = function(from, to, compilation) {
    var defer = vow.defer();

    dir.files(from, function(err, files) {
        if (err) {
            defer.reject('DirTransferPlugin: ' + err);
            return;
        }

        var allFiles = files.map(function(fullPath) {
            var fileName = fullPath.replace(from, '');
            var distName = to ? path.join(to, fileName) : fileName;

            compilation.assets[distName] = {
                size: function() {
                    return fs.statSync(fullPath).size;
                },
                source: function() {
                    return fs.readFileSync(fullPath);
                },
            };
        });

        defer.resolve(vow.all(allFiles));
    });

    return defer.promise();
};

module.exports = DirTransferPlugin;
<|endoftext|>


<commit_before>var bodyParser = require('body-parser');
var config = require('./config'); // get our config file
var cookieParser = require('cookie-parser');
var debug = require('debug')('backend:server');
var express = require('express');
var session = require('express-session');
var http = require('http');
var jwt = require('jsonwebtoken');
var ldap = require('ldapjs');
var mongoose = require('mongoose');
var morgan = require('morgan');
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
var path = require('path');
var randomstring = require("randomstring");
var favicon = require('serve-favicon');

var RedisStore = require('connect-redis')(session);

var Wss = require('./ws_server');

// Routing
// var routes = require('./routes/index');
// var users = require('./routes/users');

// MongoDB Models
var Session = require('./models/session');
var User = require('./models/user');
var Group = require('./models/group');

// LDAP client
var ldap_client = ldap.createClient({
  url: 'ldap://'+config.ldap_server
});

// Email Configuration
var smtp_transport = nodemailer.createTransport(smtpTransport({
  host: 'mailhost.anl.gov'
}));

// Create the express app instance
var app = express();
var server = http.createServer(app);

// Add session handling
let app_session = session({
  // store: new RedisStore({
  //   host: config.redis_host
  // }),
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
});
app.use(app_session);

// Create the socket.io server
var wss = new Wss({morgan:morgan,
                   server:server});

// Connect to MongoDB
mongoose.connect(config.database);
app.set('superSecret', config.secret);

// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// use morgan to log requests to the console
app.use(morgan('dev'));

// ROUTES FOR OUR API
// =============================================================================
var apiRoutes = express.Router();              // get an instance of the express Router

// middleware to use for all requests
apiRoutes.use(function(req, res, next) {

    // Testing sessions
    req.session.working = 'yes!';
    console.log('working =', req.session.working);
    console.log(req.session);

    // do logging
    console.log('Something is happening.');
    // res.header("Access-Control-Allow-Origin", "*");
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
    res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Authorization, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
    // next(); // make sure we go to the next routes and don't stop here
    // intercepts OPTIONS method from http://johnzhang.io/options-request-in-express
    if ('OPTIONS' === req.method) {
      //respond with 200
      res.send(200);
    }
    else {
    //move on
      next();
    }
});

// route to authenticate a user (POST http://localhost:8080/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {

  console.log('authenticate');
  // console.log(req.body);

  // Authenticate
  ldap_client.bind('uid='+req.body.uid+','+config.ldap_dn, req.body.password, function(err) {
    // REJECTION
    if (err) {
      console.log(err);
      var reason = err.name.toString();
      console.log(reason);
      res.json({ success: false, message: 'Authentication failed. ' + reason});

    // AUTHENTICATED
    } else {

      // Fetch user
      ldap_client.search('uid='+req.body.uid+',ou=People,dc=ser,dc=aps,dc=anl,dc=gov', {
        scope:'sub',
        filter:'objectclass=*',
        sizeLimit:1
      }, function(err, result) {

        // LDAP error
        if (err) {
          console.log(err);
        }

        var user = undefined;

        result.on('searchEntry', function(entry) {

          // The user information
          user = entry.object;
          console.log(user);

          // create a token
          var token = jwt.sign(user, app.get('superSecret'), {
            expiresIn: 86400 // expires in 24 hours
          });

          // return the information including token as JSON
          console.log('returning token');
          res.json({
            success: true,
            message: 'Enjoy your token!',
            token: token,
            pass_force_change: user.pass_force_change
          });
        });
        result.on('searchReference', function(referral) {
          console.log('referral: ' + referral.uris.join());
        });
        result.on('error', function(err) {
          console.error('error: ' + err.message);
        });
        result.on('end', function(end) {
          console.log(user);
          console.log('status: ' + end.status);

        });
      });
    }
  });
});

// route middleware to verify a token
apiRoutes.use(function(req, res, next) {

  console.log(req.body);
  console.log(req.query);
  console.log(req.headers);

  // check header or url parameters or post parameters for token
  var token = req.headers.authorization.replace('Bearer ', '');

  // decode token
  if (token) {

    // verifies secret and checks exp
    jwt.verify(token, app.get('superSecret'), function(err, decoded) {
      if (err) {
        return res.json({ success: false, message: 'Failed to authenticate token.' });
      } else {
        let now = Date.now()/1000;
        console.log(decoded.iat, decoded.exp, (decoded.exp-now)/(60));
        // if everything is good, save to request for use in other routes

        if (decoded.iat <= now && decoded.exp >= now) {
          req.decoded = decoded;
          next();
        }

      }
    });

  } else {

    // if there is no token
    // return an error
    return res.status(403).send({
        success: false,
        message: 'No token provided.'
    });
  }
});

// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
// apiRoutes.use(jwtCheck);

apiRoutes.get('/', function(req, res) {
    res.json({ message: 'Welcome to the RAPD api!' });
});

// on routes that end in /sessions
// ----------------------------------------------------
apiRoutes.route('/sessions')

  // get all the sessions (accessed at GET http://localhost:3000/api/sessions)
  .get(function(req, res) {

    var find_search = { group: { $in: req.decoded._doc.groups}};
    if (req.decoded._doc.role == 'site_admin') {
      find_search = {}
    }

    Session.
      find(find_search).
      populate('group', 'groupname').
      sort({end: -1}).
      exec(function(err, sessions) {
        if (err) {
          res.send(err);
        } else {
          res.json(sessions);
        }
      });
  })

  // create a session (accessed at POST http://localhost:3000/api/sessions)
  .post(function(req, res) {

    var session = new Session(JSON.parse(req.body.session));     // create a new instance of the Session model

    // save the bear and check for errors
    session.save(function(err) {
      if (err) {
        res.send(err);
      } else {
        res.json({ message: 'Session created!' });
      }
    });

  });

// on routes that end in /sessions/:session_id
// ----------------------------------------------------
apiRoutes.route('/sessions/:session_id')

  // get the session with that id (accessed at GET http://localhost:8080/api/sessinos/:session_id)
  .get(function(req, res) {
    Session.findById(req.params.session_id, function(err, session) {
      if (err)
        res.send(err);
      res.json(session);
    });
  })

  // update the bear with this id (accessed at PUT http://localhost:8080/api/sessions/:session_id)
  .put(function(req, res) {

    let session = req.body.session;

    // Make sure group is only an _id
    session.group = session.group._id;

    // use our bear model to find the session we want
    Session.findById(session._id, function(err, saved_session) {

      if (err)
        res.send(err);

      // Update the document
      saved_session.set(session);

      // save the bear
      saved_session.save(function(err) {
        if (err) {
          res.send(err);
        }

        Session.
          findById(session._id).
          populate('group', 'groupname').
          exec(function(err, return_session) {
            console.log(return_session);
            let params = {
              success: true,
              operation: 'edit',
              session: return_session
            };
            res.json(params);
          });
      });
    });
  })

  // delete the session with this id (accessed at DELETE http://localhost:8080/api/sessions/:session_id)
  .delete(function(req, res) {

    console.log(req.params.session_id);

    Session.remove({
      _id: req.params.session_id
    }, function(err, session) {
      if (err) {
        res.send(err);
      } else {
        res.json({ message: 'Successfully deleted' });
      }
    });
  });

// on routes that end in /results
// ----------------------------------------------------
apiRoutes.route('/results/:session_id')

    // get the session with that id (accessed at GET http://localhost:8080/api/bears/:bear_id)
    .get(function(req, res) {
        Session.find({session_id:req.params.session_id}, function(err, sessions) {
            if (err)
                res.send(err);
            console.log(sessions);
            res.json(sessions);
        });
    });

// routes that end with users
// ----------------------------------------------------
// route to return all users (GET http://localhost:8080/api/users)
apiRoutes.route('/users')
  .get(function(req, res) {

    // SERCAT uses LDAP per group
    var users = [];
    ldap_client.search(config.ldap_dn, {  //}"dc=ser,dc=aps,dc=anl,dc=gov", {
      scope:'sub',
      filter:'objectclass=*'
    }, function(err, ldap_result) {
      ldap_result.on('searchEntry', function(entry) {
        console.log('entry: ' + JSON.stringify(entry.object));
        users.push(entry.object);
      });
      ldap_result.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      ldap_result.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      ldap_result.on('end', function(result) {
        console.log('status: ' + result.status);
        res.json(users);
      });
    });
  });

/**
 * @api {get} /users/populate Populate users into MongoDB from LDAP server
 * @apiName PopulateUsers
 * @apiGroup User
 *
 * @apiSuccess {Boolean} success or failure.
 */
apiRoutes.route('/users/populate')
  .get(function(req, res) {

    // Search for all users in LDAP
    var ldap_users = [];
    ldap_client.search("dc=ser,dc=aps,dc=anl,dc=gov", {
      scope:'sub',
      filter:'objectclass=*'
    }, function(err, res) {
      res.on('searchEntry', function(entry) {
        ldap_users.push(entry.object);
        // console.log('entry: ' + JSON.stringify(entry.object));
        // create a group
        var ldap_user = entry.object;
        var new_user = new Group({
          uid: ldap_user.uid,
          uidNumber: ldap_user.uidNumber,
          gidNumber: ldap_user.gidNumber,
        });
        new_user.save(function(err) {});
      });
      res.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      res.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      res.on('end', function(result) {
        console.log('status: ' + result.status);
      });

    });

    // Now process each user
    for (let ldap_user of ldap_users) {
      console.log(ldap_user);

      // create a group
      var new_user = new Group({
        uid: ldap_user.uid,
        uidNumber: ldap_user.uidNumber,
        gidNumber: ldap_user.gidNumber,
      });

      new_user.save(function(err) {
        console.log(err);
      });

      console.log(new_user);
    }
  });

apiRoutes.route('/users/:uid')

  // Retrieve user information by uid
  .get(function(req, res) {

    console.log('GET user');

    // Fetch user
    ldap_client.search('uid='+req.params.uid+',ou=People,dc=ser,dc=aps,dc=anl,dc=gov', {
      scope:'sub',
      filter:'objectclass=*',
      sizeLimit:1
    }, function(err, result) {

      // LDAP error
      if (err) {
        console.log(err);
      }

      var user = undefined;

      result.on('searchEntry', function(entry) {
        // The user information
        user = entry.object;
        console.log(user);
      });
      result.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      result.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      result.on('end', function(end) {
        console.log(user);
        console.log('status: ' + end.status);
        res.json(user);
      });
    });
  });

// REGISTER OUR ROUTES -------------------------------

// basic route
/**
 * @api {get} / Feedback that server is up
 * @apiName Base
 * @apiGroup Admin
 *
 * @apiSuccess {String} message Message in the format "Hello! The API is at http://localhost:3000/api".
 */
app.get('/', function(req, res) {
    res.send('Hello! The API is at http://localhost:' + app.get('port') + '/api');
});

// all of our routes will be prefixed with /api
app.use('/api', apiRoutes);

module.exports = app;

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
<commit_msg>A little logging<commit_after>var bodyParser = require('body-parser');
var config = require('./config'); // get our config file
var cookieParser = require('cookie-parser');
var debug = require('debug')('backend:server');
var express = require('express');
var session = require('express-session');
var http = require('http');
var jwt = require('jsonwebtoken');
var ldap = require('ldapjs');
var mongoose = require('mongoose');
var morgan = require('morgan');
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
var path = require('path');
var randomstring = require("randomstring");
var favicon = require('serve-favicon');

var RedisStore = require('connect-redis')(session);

var Wss = require('./ws_server');

// Routing
// var routes = require('./routes/index');
// var users = require('./routes/users');

// MongoDB Models
var Session = require('./models/session');
var User = require('./models/user');
var Group = require('./models/group');

// LDAP client
var ldap_client = ldap.createClient({
  url: 'ldap://'+config.ldap_server
});

// Email Configuration
var smtp_transport = nodemailer.createTransport(smtpTransport({
  host: 'mailhost.anl.gov'
}));

// Create the express app instance
var app = express();
var server = http.createServer(app);

// Add session handling
let app_session = session({
  // store: new RedisStore({
  //   host: config.redis_host
  // }),
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true
});
app.use(app_session);

// Create the socket.io server
var wss = new Wss({morgan:morgan,
                   server:server});

// Connect to MongoDB
mongoose.connect(config.database);
app.set('superSecret', config.secret);

// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// use morgan to log requests to the console
app.use(morgan('dev'));

// ROUTES FOR OUR API
// =============================================================================
var apiRoutes = express.Router();              // get an instance of the express Router

// middleware to use for all requests
apiRoutes.use(function(req, res, next) {

    // Testing sessions
    req.session.working = 'yes!';
    console.log('working =', req.session.working);
    console.log(req.session);
    console.log(req.url);

    // do logging
    console.log('Something is happening.');
    // res.header("Access-Control-Allow-Origin", "*");
    // res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
    res.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Authorization, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
    // next(); // make sure we go to the next routes and don't stop here
    // intercepts OPTIONS method from http://johnzhang.io/options-request-in-express
    if ('OPTIONS' === req.method) {
      //respond with 200
      res.send(200);
    }
    else {
    //move on
      next();
    }
});

// route to authenticate a user (POST http://localhost:8080/api/authenticate)
apiRoutes.post('/authenticate', function(req, res) {

  console.log('authenticate');
  // console.log(req.body);

  // Authenticate
  ldap_client.bind('uid='+req.body.uid+','+config.ldap_dn, req.body.password, function(err) {
    // REJECTION
    if (err) {
      console.log(err);
      var reason = err.name.toString();
      console.log(reason);
      res.json({ success: false, message: 'Authentication failed. ' + reason});

    // AUTHENTICATED
    } else {

      // Fetch user
      ldap_client.search('uid='+req.body.uid+',ou=People,dc=ser,dc=aps,dc=anl,dc=gov', {
        scope:'sub',
        filter:'objectclass=*',
        sizeLimit:1
      }, function(err, result) {

        // LDAP error
        if (err) {
          console.log(err);
        }

        var user = undefined;

        result.on('searchEntry', function(entry) {

          // The user information
          user = entry.object;
          console.log(user);

          // create a token
          var token = jwt.sign(user, app.get('superSecret'), {
            expiresIn: 86400 // expires in 24 hours
          });

          // return the information including token as JSON
          console.log('returning token');
          res.json({
            success: true,
            message: 'Enjoy your token!',
            token: token,
            pass_force_change: user.pass_force_change
          });
        });
        result.on('searchReference', function(referral) {
          console.log('referral: ' + referral.uris.join());
        });
        result.on('error', function(err) {
          console.error('error: ' + err.message);
        });
        result.on('end', function(end) {
          console.log(user);
          console.log('status: ' + end.status);

        });
      });
    }
  });
});

// route middleware to verify a token
apiRoutes.use(function(req, res, next) {

  console.log(req.body);
  console.log(req.query);
  console.log(req.headers);

  // check header or url parameters or post parameters for token
  var token = req.headers.authorization.replace('Bearer ', '');

  // decode token
  if (token) {

    // verifies secret and checks exp
    jwt.verify(token, app.get('superSecret'), function(err, decoded) {
      if (err) {
        return res.json({ success: false, message: 'Failed to authenticate token.' });
      } else {
        let now = Date.now()/1000;
        console.log(decoded.iat, decoded.exp, (decoded.exp-now)/(60));
        // if everything is good, save to request for use in other routes

        if (decoded.iat <= now && decoded.exp >= now) {
          req.decoded = decoded;
          next();
        }

      }
    });

  } else {

    // if there is no token
    // return an error
    return res.status(403).send({
        success: false,
        message: 'No token provided.'
    });
  }
});

// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
// apiRoutes.use(jwtCheck);

apiRoutes.get('/', function(req, res) {
    res.json({ message: 'Welcome to the RAPD api!' });
});

// on routes that end in /sessions
// ----------------------------------------------------
apiRoutes.route('/sessions')

  // get all the sessions (accessed at GET http://localhost:3000/api/sessions)
  .get(function(req, res) {

    var find_search = { group: { $in: req.decoded._doc.groups}};
    if (req.decoded._doc.role == 'site_admin') {
      find_search = {}
    }

    Session.
      find(find_search).
      populate('group', 'groupname').
      sort({end: -1}).
      exec(function(err, sessions) {
        if (err) {
          res.send(err);
        } else {
          res.json(sessions);
        }
      });
  })

  // create a session (accessed at POST http://localhost:3000/api/sessions)
  .post(function(req, res) {

    var session = new Session(JSON.parse(req.body.session));     // create a new instance of the Session model

    // save the bear and check for errors
    session.save(function(err) {
      if (err) {
        res.send(err);
      } else {
        res.json({ message: 'Session created!' });
      }
    });

  });

// on routes that end in /sessions/:session_id
// ----------------------------------------------------
apiRoutes.route('/sessions/:session_id')

  // get the session with that id (accessed at GET http://localhost:8080/api/sessinos/:session_id)
  .get(function(req, res) {
    Session.findById(req.params.session_id, function(err, session) {
      if (err)
        res.send(err);
      res.json(session);
    });
  })

  // update the bear with this id (accessed at PUT http://localhost:8080/api/sessions/:session_id)
  .put(function(req, res) {

    let session = req.body.session;

    // Make sure group is only an _id
    session.group = session.group._id;

    // use our bear model to find the session we want
    Session.findById(session._id, function(err, saved_session) {

      if (err)
        res.send(err);

      // Update the document
      saved_session.set(session);

      // save the bear
      saved_session.save(function(err) {
        if (err) {
          res.send(err);
        }

        Session.
          findById(session._id).
          populate('group', 'groupname').
          exec(function(err, return_session) {
            console.log(return_session);
            let params = {
              success: true,
              operation: 'edit',
              session: return_session
            };
            res.json(params);
          });
      });
    });
  })

  // delete the session with this id (accessed at DELETE http://localhost:8080/api/sessions/:session_id)
  .delete(function(req, res) {

    console.log(req.params.session_id);

    Session.remove({
      _id: req.params.session_id
    }, function(err, session) {
      if (err) {
        res.send(err);
      } else {
        res.json({ message: 'Successfully deleted' });
      }
    });
  });

// on routes that end in /results
// ----------------------------------------------------
apiRoutes.route('/results/:session_id')

    // get the session with that id (accessed at GET http://localhost:8080/api/bears/:bear_id)
    .get(function(req, res) {
        Session.find({session_id:req.params.session_id}, function(err, sessions) {
            if (err)
                res.send(err);
            console.log(sessions);
            res.json(sessions);
        });
    });

// routes that end with users
// ----------------------------------------------------
// route to return all users (GET http://localhost:8080/api/users)
apiRoutes.route('/users')
  .get(function(req, res) {

    // SERCAT uses LDAP per group
    var users = [];
    ldap_client.search(config.ldap_dn, {  //}"dc=ser,dc=aps,dc=anl,dc=gov", {
      scope:'sub',
      filter:'objectclass=*'
    }, function(err, ldap_result) {
      ldap_result.on('searchEntry', function(entry) {
        console.log('entry: ' + JSON.stringify(entry.object));
        users.push(entry.object);
      });
      ldap_result.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      ldap_result.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      ldap_result.on('end', function(result) {
        console.log('status: ' + result.status);
        res.json(users);
      });
    });
  });

/**
 * @api {get} /users/populate Populate users into MongoDB from LDAP server
 * @apiName PopulateUsers
 * @apiGroup User
 *
 * @apiSuccess {Boolean} success or failure.
 */
apiRoutes.route('/users/populate')
  .get(function(req, res) {

    // Search for all users in LDAP
    var ldap_users = [];
    ldap_client.search("dc=ser,dc=aps,dc=anl,dc=gov", {
      scope:'sub',
      filter:'objectclass=*'
    }, function(err, res) {
      res.on('searchEntry', function(entry) {
        ldap_users.push(entry.object);
        // console.log('entry: ' + JSON.stringify(entry.object));
        // create a group
        var ldap_user = entry.object;
        var new_user = new Group({
          uid: ldap_user.uid,
          uidNumber: ldap_user.uidNumber,
          gidNumber: ldap_user.gidNumber,
        });
        new_user.save(function(err) {});
      });
      res.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      res.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      res.on('end', function(result) {
        console.log('status: ' + result.status);
      });

    });

    // Now process each user
    for (let ldap_user of ldap_users) {
      console.log(ldap_user);

      // create a group
      var new_user = new Group({
        uid: ldap_user.uid,
        uidNumber: ldap_user.uidNumber,
        gidNumber: ldap_user.gidNumber,
      });

      new_user.save(function(err) {
        console.log(err);
      });

      console.log(new_user);
    }
  });

apiRoutes.route('/users/:uid')

  // Retrieve user information by uid
  .get(function(req, res) {

    console.log('GET user');

    // Fetch user
    ldap_client.search('uid='+req.params.uid+',ou=People,dc=ser,dc=aps,dc=anl,dc=gov', {
      scope:'sub',
      filter:'objectclass=*',
      sizeLimit:1
    }, function(err, result) {

      // LDAP error
      if (err) {
        console.log(err);
      }

      var user = undefined;

      result.on('searchEntry', function(entry) {
        // The user information
        user = entry.object;
        console.log(user);
      });
      result.on('searchReference', function(referral) {
        console.log('referral: ' + referral.uris.join());
      });
      result.on('error', function(err) {
        console.error('error: ' + err.message);
      });
      result.on('end', function(end) {
        console.log(user);
        console.log('status: ' + end.status);
        res.json(user);
      });
    });
  });

// REGISTER OUR ROUTES -------------------------------

// basic route
/**
 * @api {get} / Feedback that server is up
 * @apiName Base
 * @apiGroup Admin
 *
 * @apiSuccess {String} message Message in the format "Hello! The API is at http://localhost:3000/api".
 */
app.get('/', function(req, res) {
    res.send('Hello! The API is at http://localhost:' + app.get('port') + '/api');
});

// all of our routes will be prefixed with /api
app.use('/api', apiRoutes);

module.exports = app;

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
<|endoftext|>


<commit_before><commit_msg>Created first version<commit_after>var channeller = {
    messageHandlers: {
      error: function(msg) {
        console.error(msg);
      }
    }
  , on: function(msg, handler) {
      this.messageHandlers[msg] = msg !== 'error' ? handler : this.messageHandlers.error;
    }
  , handle: function(msg) {
      if (this.handlers.hasOwnProperty(msg)) {
        this.handlers[msg]();
      }
      else {
        this.handlers.error();
      }
    }
};

exports.createChanneller = function(obj) {
  obj = obj || {};
  return Object.create(channeller, obj);
};
<|endoftext|>


<commit_before>
module.exports = TabElect

var IdbKvStore = require('idb-kv-store')
var inherits = require('inherits')
var EventEmitter = require('events').EventEmitter

TabElect.SUPPORT = IdbKvStore.INDEXEDDB_SUPPORT && IdbKvStore.BROADCAST_SUPPORT

inherits(TabElect, EventEmitter)
function TabElect (name, opts) {
  var self = this
  if (!TabElect.SUPPORT) throw new Error('No indexDB or BroadcastChannel support')
  if (typeof name === 'undefined') throw new Error('"name" cannot be undefined')
  if (!(self instanceof TabElect)) return new TabElect(name, opts)
  if (!opts) opts = {}

  EventEmitter.call(self)

  self.isLeader = false
  self.currentTerm = 0
  self.electedTerm = 0
  self.destroyed = false

  self._db = new IdbKvStore(name)
  self._db.on('change', function (change) {
    self._onDbChange(change)
  })

  self._db.on('error', function (err) {
    self._destroy(err)
  })

  self._db.on('close', function () {
    self._destroy(new Error('IDB database unexpectedly closed'))
  })

  self.elect()
}

TabElect.prototype._onDbChange = function (change) {
  if (this.destroyed) return
  console.log('CHANGE', change)
  if (change.method === 'add' && change.key > this.currentTerm) {
    // A new leader has rising; a new age of tyranny has begun
    this.currentTerm = change.key
  }

  if (change.method === 'remove') {
    if (this.isLeader && change.key === this.electedTerm) {
      // The new leader has revoked this instance's leadership position
      this.depose()
    } else if (!this.isLeader && change.key === this.currentTerm) {
      // The leader has deposed themself so no one is the leader. Begin the race for election
      this.elect()
    }
  }
}

TabElect.prototype.elect = function (cb) {
  var self = this
  if (self.destroyed) throw new Error('Already destroyed')
  if (self.isLeader) throw new Error('Already the leader')

  var oldTerms
  var newTerm

  self._db.keys()
  .then(function (keys) {
    oldTerms = keys.slice(0) // Copy array
    newTerm = keys.length === 0 ? 1 : keys.sort().pop() + 1
    console.log('GOT_TERMS', newTerm, oldTerms)
    // 'add' operation fails if the key already exists.
    // The key already exists only if multiple instances try to elect themeselves simultaneously
    return self._db.add(newTerm, true)
  })
  .then(function () {
    // Remove all old keys/terms. This notifies the old leader their tyranny has ended
    return Promise.all(oldTerms.map(function (t) { return self._db.remove(t) }))
  })
  .then(function () {
    console.log('PRE_ELECT', self.currentTerm, newTerm)
    if (self.currentTerm > newTerm) {
      // Someone elected themeselves after us and stole the leader position
      if (cb) cb(null, false)
    } else {
      console.log('ELECT', newTerm)
      self.isLeader = true
      self.currentTerm = newTerm
      self.electedTerm = newTerm

      if (cb) cb(null, true)
      self.emit('elected')
    }
  })
  .catch(function (err) {
    console.log('DB ERR', err)
    if (!cb) return
    if (err.name === 'ConstraintError') {
      /*
       * The db 'add' operation failed because another instance added the same key. That
       * instance successfully elected itself. This instance did not.
       */
      cb(null, false)
    } else {
      cb(err)
    }
  })
}

TabElect.prototype.depose = function () {
  if (this.destroyed) throw new Error('Already destroyed')
  if (!this.isLeader) throw new Error('Can not depose when not the leader')

  console.log('DEPOSE', this.electedTerm)
  this._db.remove(this.electedTerm)
  this.isLeader = false
  this.emit('deposed')
}

TabElect.prototype.destroy = function () {
  this._destroy()
}

TabElect.prototype._destroy = function (err) {
  var self = this
  if (self.destroyed) return
  self.destroyed = true
  var wasLeader = self.isLeader
  self.isLeader = false

  if (err) self.emit('error', err)
  self.removeAllListeners()

  if (wasLeader) this._db.remove(this.electedTerm, finished)
  else finished()

  function finished () {
    self._db.close()
    self._db = null
  }
}
<commit_msg>Add handler for beforeunload event<commit_after>/* eslint-env browser */

module.exports = TabElect

var IdbKvStore = require('idb-kv-store')
var inherits = require('inherits')
var EventEmitter = require('events').EventEmitter

TabElect.SUPPORT = IdbKvStore.INDEXEDDB_SUPPORT && IdbKvStore.BROADCAST_SUPPORT

inherits(TabElect, EventEmitter)
function TabElect (name, opts) {
  var self = this
  if (!TabElect.SUPPORT) throw new Error('No indexDB or BroadcastChannel support')
  if (typeof name === 'undefined') throw new Error('"name" cannot be undefined')
  if (!(self instanceof TabElect)) return new TabElect(name, opts)
  if (!opts) opts = {}

  EventEmitter.call(self)

  self.isLeader = false
  self.currentTerm = 0
  self.electedTerm = 0
  self.destroyed = false

  self._db = new IdbKvStore('tab-elect-' + name)
  self._db.on('change', onDbChange)
  self._db.on('error', onDbError)
  self._db.on('close', onDbClose)

  addEventListener('beforeunload', onBeforeUnload)

  self.elect()

  function onDbChange (change) {
    self._onDbChange(change)
  }

  function onDbError (err) {
    self._destroy(err)
  }

  function onDbClose () {
    self._destroy(new Error('IDB database unexpectedly closed'))
  }

  function onBeforeUnload () {
    self._destroy()
  }
}

TabElect.prototype._onDbChange = function (change) {
  if (this.destroyed) return
  console.log('CHANGE', change)
  if (change.method === 'add' && change.key > this.currentTerm) {
    // A new leader has rising; a new age of tyranny has begun
    this.currentTerm = change.key
  }

  if (change.method === 'remove') {
    if (this.isLeader && change.key === this.electedTerm) {
      // The new leader has revoked this instance's leadership position
      this.depose()
    } else if (!this.isLeader && change.key === this.currentTerm) {
      // The leader has deposed themself so no one is the leader. Begin the race for election
      this.elect()
    }
  }
}

TabElect.prototype.elect = function (cb) {
  var self = this
  if (self.destroyed) throw new Error('Already destroyed')
  if (self.isLeader) throw new Error('Already the leader')

  var oldTerms
  var newTerm

  self._db.keys()
  .then(function (keys) {
    oldTerms = keys.slice(0) // Copy array
    newTerm = keys.length === 0 ? 1 : keys.sort().pop() + 1
    console.log('GOT_TERMS', newTerm, oldTerms)
    // 'add' operation fails if the key already exists.
    // The key already exists only if multiple instances try to elect themeselves simultaneously
    return self._db.add(newTerm, true)
  })
  .then(function () {
    // Remove all old keys/terms. This notifies the old leader their tyranny has ended
    return Promise.all(oldTerms.map(function (t) { return self._db.remove(t) }))
  })
  .then(function () {
    console.log('PRE_ELECT', self.currentTerm, newTerm)
    if (self.currentTerm > newTerm) {
      // Someone elected themeselves after us and stole the leader position
      if (cb) cb(null, false)
    } else {
      console.log('ELECT', newTerm)
      self.isLeader = true
      self.currentTerm = newTerm
      self.electedTerm = newTerm

      if (cb) cb(null, true)
      self.emit('elected')
    }
  })
  .catch(function (err) {
    console.log('DB ERR', err)
    if (!cb) return
    if (err.name === 'ConstraintError') {
      /*
       * The db 'add' operation failed because another instance added the same key. That
       * instance successfully elected itself. This instance did not.
       */
      cb(null, false)
    } else {
      cb(err)
    }
  })
}

TabElect.prototype.depose = function () {
  if (this.destroyed) throw new Error('Already destroyed')
  if (!this.isLeader) throw new Error('Can not depose when not the leader')

  console.log('DEPOSE', this.electedTerm)
  this._db.remove(this.electedTerm)
  this.isLeader = false
  this.emit('deposed')
}

TabElect.prototype.destroy = function () {
  this._destroy()
}

TabElect.prototype._destroy = function (err) {
  var self = this
  if (self.destroyed) return
  self.destroyed = true
  var wasLeader = self.isLeader
  self.isLeader = false

  if (err) self.emit('error', err)
  self.removeAllListeners()

  if (wasLeader) this._db.remove(this.electedTerm, finished)
  else finished()

  function finished () {
    self._db.close()
    self._db = null
  }
}
<|endoftext|>


<commit_before>'use strict';
var fs = require('fs');
var path = require('path');
var childProcess = require('child_process');
var minimist = require('minimist');
var arrify = require('arrify');
var argv = require('the-argv');
var pathExists = require('path-exists');
var readPkgUp = require('read-pkg-up');
var writePkg = require('write-pkg');
var Promise = require('pinkie-promise');
var pify = require('pify');
var DEFAULT_TEST_SCRIPT = 'echo "Error: no test specified" && exit 1';

var PLURAL_OPTIONS = [
	'env',
	'global',
	'ignore'
];

var CONFIG_FILES = [
	'.jshintrc',
	'.eslintrc',
	'.jscsrc'
];

function warnConfigFile(pkgCwd) {
	var files = CONFIG_FILES.filter(function (x) {
		return pathExists.sync(path.join(pkgCwd, x));
	});

	if (files.length === 0) {
		return;
	}

	console.log(files.join(' & ') + ' can probably be deleted now that you\'re using XO.');
}

module.exports = function (opts) {
	opts = opts || {};

	var ret = readPkgUp.sync({
		cwd: opts.cwd,
		normalize: false
	});
	var pkg = ret.pkg;
	var pkgPath = ret.path;
	var pkgCwd = path.dirname(pkgPath);
	var s = pkg.scripts = pkg.scripts ? pkg.scripts : {};

	if (s.test && s.test !== DEFAULT_TEST_SCRIPT) {
		// don't add if it's already there
		if (!/^xo( |$)/.test(s.test)) {
			s.test = 'xo && ' + s.test;
		}
	} else {
		s.test = 'xo';
	}

	var cli = minimist(opts.args || argv());
	var unicorn = cli.unicorn;

	delete cli._;
	delete cli.unicorn;
	delete cli.init;

	PLURAL_OPTIONS.forEach(function (option) {
		if (cli[option]) {
			cli[option + 's'] = arrify(cli[option]);
			delete cli[option];
		}
	});

	if (Object.keys(cli).length) {
		pkg.xo = cli;
	} else if (pkg.xo) {
		delete pkg.xo;
	}

	writePkg.sync(pkgPath, pkg);

	return pify(childProcess.execFile, Promise)('npm', ['install', '--save-dev', 'xo'], {
		cwd: pkgCwd
	}).then(function () {
		warnConfigFile(pkgCwd);

		// for personal use
		if (unicorn) {
			var pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
			pkg.devDependencies.xo = '*';
			writePkg.sync(pkgPath, pkg);

			CONFIG_FILES.forEach(function (x) {
				try {
					fs.unlinkSync(path.join(pkgCwd, x));
				} catch (err) {}
			});
		}
	});
};
<commit_msg>add more JSCS config filenames<commit_after>'use strict';
var fs = require('fs');
var path = require('path');
var childProcess = require('child_process');
var minimist = require('minimist');
var arrify = require('arrify');
var argv = require('the-argv');
var pathExists = require('path-exists');
var readPkgUp = require('read-pkg-up');
var writePkg = require('write-pkg');
var Promise = require('pinkie-promise');
var pify = require('pify');
var DEFAULT_TEST_SCRIPT = 'echo "Error: no test specified" && exit 1';

var PLURAL_OPTIONS = [
	'env',
	'global',
	'ignore'
];

var CONFIG_FILES = [
	'.jshintrc',
	'.eslintrc',
	'.jscsrc',
	'.jscs.json',
	'.jscs.yaml'
];

function warnConfigFile(pkgCwd) {
	var files = CONFIG_FILES.filter(function (x) {
		return pathExists.sync(path.join(pkgCwd, x));
	});

	if (files.length === 0) {
		return;
	}

	console.log(files.join(' & ') + ' can probably be deleted now that you\'re using XO.');
}

module.exports = function (opts) {
	opts = opts || {};

	var ret = readPkgUp.sync({
		cwd: opts.cwd,
		normalize: false
	});
	var pkg = ret.pkg;
	var pkgPath = ret.path;
	var pkgCwd = path.dirname(pkgPath);
	var s = pkg.scripts = pkg.scripts ? pkg.scripts : {};

	if (s.test && s.test !== DEFAULT_TEST_SCRIPT) {
		// don't add if it's already there
		if (!/^xo( |$)/.test(s.test)) {
			s.test = 'xo && ' + s.test;
		}
	} else {
		s.test = 'xo';
	}

	var cli = minimist(opts.args || argv());
	var unicorn = cli.unicorn;

	delete cli._;
	delete cli.unicorn;
	delete cli.init;

	PLURAL_OPTIONS.forEach(function (option) {
		if (cli[option]) {
			cli[option + 's'] = arrify(cli[option]);
			delete cli[option];
		}
	});

	if (Object.keys(cli).length) {
		pkg.xo = cli;
	} else if (pkg.xo) {
		delete pkg.xo;
	}

	writePkg.sync(pkgPath, pkg);

	return pify(childProcess.execFile, Promise)('npm', ['install', '--save-dev', 'xo'], {
		cwd: pkgCwd
	}).then(function () {
		warnConfigFile(pkgCwd);

		// for personal use
		if (unicorn) {
			var pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
			pkg.devDependencies.xo = '*';
			writePkg.sync(pkgPath, pkg);

			CONFIG_FILES.forEach(function (x) {
				try {
					fs.unlinkSync(path.join(pkgCwd, x));
				} catch (err) {}
			});
		}
	});
};
<|endoftext|>


<commit_before>var application = ''
var resoureces = ['index', 'store', 'show', 'update', 'destroy']
var http = {
  'index': 'get',
  'store': 'post',
  'show': 'get',
  'update': 'put',
  'destroy': 'delete'
}

var resourceRouter = {
  use: function (app) {
    this.application = app
  },
  resource: function (url, controller) {
    resoureces.forEach(resource => {
      if (controller.hasOwnProperty(resource)) {
        this.application.route(this.routeUriTransformer(url, resource))[http[resource]](controller[resource])
      }
    })
  },
  routeUriTransformer: function(url, resource) {
    var resoureces = ['show', 'update', 'destroy']

    if (resoureces.indexOf(resource) === -1) {
      return url
    }

    return url + '/:id'
  }
}

module.exports = resourceRouter
<commit_msg>bind this to the function<commit_after>var application = ''
var resoureces = ['index', 'store', 'show', 'update', 'destroy']
var http = {
  'index': 'get',
  'store': 'post',
  'show': 'get',
  'update': 'put',
  'destroy': 'delete'
}

var resourceRouter = {
  use: function (app) {
    this.application = app
  },
  resource: function (url, controller) {
    resoureces.forEach(function(resource){
      if (controller.hasOwnProperty(resource)) {
        this.application.route(this.routeUriTransformer(url, resource))[http[resource]](controller[resource])
      }
    }.bind(this))
  },
  routeUriTransformer: function(url, resource) {
    var resoureces = ['show', 'update', 'destroy']

    if (resoureces.indexOf(resource) === -1) {
      return url
    }

    return url + '/:id'
  }
}

module.exports = resourceRouter
<|endoftext|>


<commit_before>var router = require('ramrod')(),
  form = require('formidable').IncomingForm(),
  http = require('http'),
  couchdb = require('felix-couchdb'),
  client = couchdb.createClient(),
  db = client.db('redwah'),
  web = require('./lib/web.js'),
  rwlib = require('./lib/redwah.js'),
  redwah = {
    version: "0.0.1"
  };

// Route handler

router.on('putlist|put', function (req, res) {
  db.getDoc(params.id, function (err, previousDoc) {
    if (err) { return web.sendError(res, 404); }
    db.saveDoc(params, function (err, doc) {
      if (err) { return web.sendError(res, 500);
      res.writeHead(200);
      res.end(JSON.stringify(doc));
      if (previousDoc.rows.toString() != doc.rows.toString()) {
        rwlib.updateItems(doc.rows, doc.items);
      }
    });
  });
});

router.on('postitem|post', function (req, res) {
  form.parse(req, function (err, params) {
  });
});

router.on('putitem|put', function (req, res, params) {
});

router.on('postlist|post', function (req, res) {
  form.parse(req, function (err, params) {
    if (err) { return web.sendError(res, 500); }
    } else {
      var listDocument = {
        "name": params.name,
        "items": [],
        "rows": [],
        "createdAt": new Date().getTime(),
        "lastUpdated": new Date().getTime()
      };
      db.saveDoc(listDocument, function (err, doc) {
        res.writeHead(201);
        res.end(JSON.stringify(doc));
      });
    }
  });
});

router.on('getlist|get', function (req, res, params) {
  res.writeHead(200);
  db.getDoc(params.id, function (err, doc) {
    if (err) { return web.sendError(res, 404); }
    res.writeHead(200);
    res.end(JSON.stringify(doc));
  });
});

router.on('*', function (req, res) {
  res.writeHead(200);
  res.end(JSON.stringify(redwah));
});

// Enumerate routes

['list', 'item'].forEach(function (obj) {
  ['post', 'get', 'put', 'del'].forEach(function (method) {
    router[method](obj, method + obj);
  });
});

db.exists(function (err, dbExists) {
  if (!dbExists) {
    console.log('db does not exist');
    db.create(function (err) {
      if (err) { throw new Error (JSON.stringify(err)); }
      console.log('redwah db created');
    });
  }
});

http.createServer(function (req, res) {
  router.dispatch(req, res);
}).listen(3000);
<commit_msg>api skeleton<commit_after>var router = require('ramrod')(),
  form = require('formidable').IncomingForm(),
  http = require('http'),
  couchdb = require('felix-couchdb'),
  client = couchdb.createClient(),
  db = client.db('redwah'),
  web = require('./lib/web.js'),
  rwlib = require('./lib/redwah.js'),
  redwah = {
    version: "0.0.1"
  };

// Route handler

router.on('putlist|put', function (req, res) {
  db.getDoc(params.id, function (err, previousDoc) {
    if (err) { return web.sendError(res, 404); }
    db.saveDoc(params, function (err, doc) {
      if (err) { return web.sendError(res, 500);
      res.writeHead(200);
      res.end(JSON.stringify(doc));
      if (previousDoc.rows.toString() != doc.rows.toString()) {
        rwlib.updateItems(doc.rows, doc.items);
      }
    });
  });
});

router.on('postitem|post', function (req, res) {
  form.parse(req, function (err, params) {
  });
});

router.on('getitem|get', function (req, res, params) {
});

router.on('putitem|put', function (req, res, params) {
});

router.on('delitem|del', function (req, res, params) {
});

router.on('dellist|del', function (req, res, params) {
});

router.on('postlist|post', function (req, res) {
  form.parse(req, function (err, params) {
    if (err) { return web.sendError(res, 500); }
    } else {
      var listDocument = {
        "name": params.name,
        "items": [],
        "rows": [],
        "createdAt": new Date().getTime(),
        "lastUpdated": new Date().getTime()
      };
      db.saveDoc(listDocument, function (err, doc) {
        res.writeHead(201);
        res.end(JSON.stringify(doc));
      });
    }
  });
});

router.on('getlist|get', function (req, res, params) {
  res.writeHead(200);
  db.getDoc(params.id, function (err, doc) {
    if (err) { return web.sendError(res, 404); }
    res.writeHead(200);
    res.end(JSON.stringify(doc));
  });
});

router.on('*', function (req, res) {
  res.writeHead(200);
  res.end(JSON.stringify(redwah));
});

// Enumerate routes

['list', 'item'].forEach(function (obj) {
  ['post', 'get', 'put', 'del'].forEach(function (method) {
    router[method](obj, method + obj);
  });
});

db.exists(function (err, dbExists) {
  if (!dbExists) {
    console.log('db does not exist');
    db.create(function (err) {
      if (err) { throw new Error (JSON.stringify(err)); }
      console.log('redwah db created');
    });
  }
});

http.createServer(function (req, res) {
  router.dispatch(req, res);
}).listen(3000);
<|endoftext|>


<commit_before>/*
 * require('express-graceful')(app)
 * and when all initialization is done, call app.ready()
 */

module.exports = function(app) {
	var callback;
	var promise = new Promise(function(resolve, reject) {
		callback = function(err) {
			if (err) {
				reject(err);
			} else {
				console.info("%s\n%s", process.title + '-' + app.settings.env, app.settings.site.href);
				resolve();
			}
		};
	});
	app.ready = callback;
	app.use(function(req, res, next) {
		promise = promise.then(next).catch(next);
	});
	return app;
};

<commit_msg>Just don't log something<commit_after>/*
 * require('express-graceful')(app)
 * and when all initialization is done, call app.ready()
 */

module.exports = function(app) {
	var callback;
	var promise = new Promise(function(resolve, reject) {
		callback = function(err) {
			if (err) {
				reject(err);
			} else {
				resolve();
			}
		};
	});
	app.ready = callback;
	app.use(function(req, res, next) {
		promise = promise.then(next).catch(next);
	});
	return app;
};

<|endoftext|>