<commit_before>'use strict';

module.exports = function() {

  var path = require('path'),
      fs = require('fs'),
      async = require('async'),
      forever = require('forever-monitor'),
      pidsPath = path.resolve(__dirname, '../../.pids'),
      _this = this,
      _ids = -1,
      _children = [{
        name: 'Allons-y',
        id: ++_ids,
        type: 'main',
        startDate: new Date()
      }];

  function _logDate(date) {
    if (!date) {
      return '';
    }

    var day = date.getDate(),
        month = date.getMonth() + 1,
        hours = date.getHours(),
        minutes = date.getMinutes();

    return (day < 10 ? '0' + day : day) + '/' + (month < 10 ? '0' + month : month) + ' ' +
        (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes);
  }

  function _cleanPids() {
    if (fs.existsSync(pidsPath)) {
      try {
        _this.log('allons-y', 'processes-clean-pids');

        fs.unlinkSync(pidsPath);
      }
      catch (err) {
        _this.logWarning('allons-y', 'processes-clean-pids-error', {
          error: err
        });
      }
    }
  }

  function _pids() {
    var pids = (fs.existsSync(pidsPath) ? fs.readFileSync(pidsPath, 'utf-8') : '').split('\n');

    for (var i = pids.length - 1; i >= 0; i--) {
      if (!pids[i]) {
        pids.splice(i, 1);
      }
      else {
        pids[i] = pids[i].split(':');
      }
    }

    return pids;
  }

  function _savePid(pid, processName) {
    if (!pid || !processName) {
      return false;
    }

    _this.log('allons-y', 'processes-pid-save:' + pid + ',' + processName);

    var pids = fs.existsSync(pidsPath) ? fs.readFileSync(pidsPath, 'utf-8') : '';
    pids += (pids ? '\n' : '') + pid + ':' + processName;

    fs.writeFileSync(pidsPath, pids);

    return true;
  }

  _this.liveCommand(['processes', 'p'], 'output the live processes list', function() {
    _this.outputInfo('\n► processes:\n\n');

    _children.forEach(function(child) {
      console.log([
        '  ■ [' + _logDate(child.startDate) + ']',
        _this.textInfo(child.name),
        (child.processes ? '(' + child.processes.length + ')' : ''),
        '#' + _this.textWarning(child.id)
      ].join(' '));

      if (child.processes) {
        child.processes.forEach(function(p) {
          console.log([
            '    ∙ [' + _logDate(p.restartDate) + ']',
            _this.textInfo(p.name),
            '(' + child.type + ')',
            '(' + p.forever.times + ' restarts)',
            '#' + _this.textWarning(p.id)
          ].join(' '));
        });
      }
    });

    console.log('');
  });

  function _findProcesses($args, splice) {
    $args = $args || [];
    $args[0] = ($args[0] || '')
      .toString()
      .replace('#', '');

    if (!$args[0]) {
      return null;
    }

    var id = $args[0],
        found = false;

    if (id.indexOf('0') === 0) {
      return false;
    }

    for (var i = 0; i < _children.length; i++) {
      var child = _children[i];

      if (child.id.toString() === id) {
        found = {
          id: id,
          name: child.name,
          processes: child.processes
        };

        if (splice) {
          _children.splice(i, 1);
        }

        break;
      }

      if (child.processes) {
        for (var j = 0; j < child.processes.length; j++) {
          if (child.processes[j].id.toString() === id) {
            found = {
              id: id,
              name: child.processes[j].name,
              processes: [child.processes[j]]
            };

            if (splice) {
              child.processes.splice(j, 1);
            }

            if (!child.processes.length) {
              _children.splice(i, 1);
            }

            break;
          }
        }
      }
    }

    return found === false ? -1 : found;
  }

  this.childByName = function(name) {
    for (var i = 0; i < _children.length; i++) {
      console.log(name, _children[i]);
      if (_children[i].name == name) {
        return _children[i];
      }
    }

    return null;
  };

  _this.liveCommand('restart [process]', 'restart a process', function($args) {
    _this.outputInfo('\n► restart:\n\n');

    var found = _findProcesses($args);

    if (found === null) {
      return _this.outputWarning('\n  Set a process id for the "restart" command: restart [process]\n\n');
    }
    else if (found === false) {
      return _this.outputWarning('\n  You cannot restart Allons-y from the Live Commands\n\n');
    }
    else if (found === -1 || !found.processes) {
      return _this.outputWarning('\n  There is no process for this id\n\n');
    }

    for (var i = 0; i < found.processes.length; i++) {
      var p = found.processes[i];

      if (p.forever) {
        _this.log('allons-y', 'processes-restart:' + p.id + ',' + p.name);

        p.forever.restart();
      }
    }

    _this.outputSuccess('\n► process "' + found.name + '" (#' + found.id + ') restarted\n\n');
  });

  _this.liveCommand('kill [process]', 'shutdown a process', function($args) {
    _this.outputInfo('\n► kill:\n\n');

    var found = _findProcesses($args, true);

    if (found === null) {
      return _this.outputWarning('\n  Set a process id for the "kill" command: kill [process]\n\n');
    }
    else if (found === false) {
      return _this.outputWarning('\n  Use the "exit" command to shutdown Allons-y\n\n');
    }
    else if (found === -1 || !found.processes) {
      return _this.outputWarning('\n  There is no process for this id\n\n');
    }

    found.processes.forEach(function(p) {
      if (p.forever) {
        _this.log('allons-y', 'processes-stop:' + p.id + ',' + p.name);

        p.forever.stop();
      }
      if (p.watcher) {
        p.watcher.stop();
      }
    });

    _this.outputSuccess('\n► process "' + found.name + '" (#' + found.id + ') terminated\n\n');
  });

  _this.liveCommand('exit', 'shutdown allons-y', function() {
    _this.outputInfo('\n► exit\n\n');

    for (var i = 0; i < _children.length; i++) {
      var child = _children[i];

      if (child.processes && child.processes.length) {
        for (var j = 0; j < child.processes.length; j++) {
          if (child.processes[j].forever) {
            _this.log('allons-y', 'processes-stop:' + child.processes[j].id + ',' + child.processes[j].name);

            child.processes[j].forever.stop();
          }
          if (child.processes[j].watcher) {
            child.processes[j].watcher.stop();
          }
        }
      }
    }

    _cleanPids();

    _this.log('allons-y', 'exit');

    process.exit();
  });

  function _callModule(startModule, index, nextFile) {
    index = parseInt(index, 10);

    DependencyInjection.injector.controller.invoke(null, startModule.module, {
      controller: {
        $index: function() {
          return index;
        },

        $done: function() {
          return nextFile;
        }
      }
    });
  }

  function _processEvents(p) {
    p.forever.on('restart', function() {
      p.restartDate = new Date();
    });

    p.forever.on('exit', function() {
      _findProcesses([p.id], true);
    });

    p.forever.on('watch:restart', function() {
      p.restartDate = new Date();
      _this.outputInfo('► [Watch] Restart "' + p.name + '" (#' + _this.outputWarning(p.id) + ')\n');
    });

    p.watcher.on('change', function() {
      _this.outputInfo('► [Watch] Restart "' + p.name + '" (#' + p.id + ')\n');
      p.forever.times--;
      p.forever.restart();
    });

    _savePid(p.forever.child.pid, p.name);
  }

  this.start = function(dontStopBefore) {
    if (!dontStopBefore) {
      return _this.stop(function() {
        _this.start(true);
      }, true);
    }

    _this.outputBanner();

    _savePid(process.pid, 'Allons-y');

    if (!process.env.ALLONSY_LIVE_COMMANDS || process.env.ALLONSY_LIVE_COMMANDS == 'true') {
      _this.outputInfo('  Live Commands is enabled. Use "help" to display the available commands.\n\n');
    }

    _this.bootstrap({
      owner: 'start'
    }, function() {
      var files = _this.findInFeaturesSync('*-allons-y-start.js');

      _this.log('allons-y', 'start', {
        files: files
      });

      async.mapSeries(files, function(file, nextFile) {
        var startModule = require(path.resolve(file));

        if (typeof startModule.enabled == 'boolean' && startModule.enabled === false) {
          return nextFile();
        }

        if (startModule.fork || startModule.spawn) {
          if (startModule.fork) {
            startModule.forkCount = startModule.forkCount || 1;
            startModule.forkMaxRestarts = startModule.forkMaxRestarts || 10;
          }
          else if (startModule.spawn) {
            startModule.spawnCount = startModule.spawnCount || 1;
            startModule.spawnArgs = startModule.spawnArgs || [];
            startModule.spawnMaxRestarts = startModule.spawnMaxRestarts || 10;
          }

          var count = startModule.fork ? startModule.forkCount : startModule.spawnCount,
              child = {
                name: startModule.name,
                id: ++_ids,
                ids: -1,
                type: startModule.fork ? 'fork' : 'spawn',
                startDate: new Date(),
                processes: []
              };

          _children.push(child);

          for (var i = 0; i < count; i++) {
            var pId = child.id + '.' + (++child.ids);

            _this.log('allons-y', 'processes-' + child.type + '-start:' + pId + ',' + child.name);

            _this.outputInfo('► Starting "' + child.name + '" (' + child.type + ')' + ' [' + (i + 1) + '/' + count + ']\n');

            var p = {
              name: child.name,
              id: pId,
              startDate: new Date(),
              restartDate: new Date(),
              watcher: _this.watcher(startModule.name, startModule.watch || null),
              forever: startModule.fork ?
                new (forever.Monitor)('./node_modules/allons-y/fork.js', {
                  max: startModule.forkMaxRestarts,
                  args: [file, i]
                }).start() :
                forever.start(startModule.spawnCommands, {
                  max: startModule.spawnMaxRestarts
                })
            };

            _processEvents(p);

            child.processes.push(p);
          }

          return nextFile();
        }

        _callModule(startModule, 0, nextFile);
      }, function() {

        _this.waitLiveCommand();

      });
    });
  };

  this.stop = function(callback, fromStart) {
    _this.bootstrap({
      owner: 'stop'
    }, function() {
      _this.log('allons-y', 'stop');

      var pids = _pids();

      if (!fromStart) {
        _this.outputBanner();

        _this.outputInfo('► stop\n\n');
      }

      pids.forEach(function(pid) {
        if (!pid) {
          return;
        }

        if (!fromStart) {
          _this.outputSuccess('  kill "' + pid[1] + '" (#' + pid[0] + ')\n');
        }

        _this.log('allons-y', 'processes-stop:' + pid[0] + ',' + pid[1]);

        forever.kill(pid[0]);
      });

      _cleanPids();

      if (!fromStart) {
        console.log('');
      }

      if (callback) {
        callback();
      }
    });
  };

  this.fork = function() {
    _this.bootstrap({
      owner: 'fork'
    }, function() {
      if (process.argv.length < 4) {
        return;
      }

      var startModule = require(path.resolve(process.argv[2]));

      _this.log('allons-y', 'fork-exec:' + process.argv[3]);

      _callModule(startModule, process.argv[3], function() { });
    });
  };

};
<commit_msg>feat(allons-y processes): add possibility to send messages between children<commit_after>'use strict';

module.exports = function() {

  var path = require('path'),
      fs = require('fs'),
      async = require('async'),
      forever = require('forever-monitor'),
      uuid = require('node-uuid'),
      pidsPath = path.resolve(__dirname, '../../.pids'),
      _this = this,
      _isMain = false,
      _isFork = false,
      _ids = -1,
      _messagesCallbacks = {},
      _children = [{
        name: 'Allons-y',
        id: ++_ids,
        type: 'main',
        startDate: new Date()
      }];

  function _logDate(date) {
    if (!date) {
      return '';
    }

    var day = date.getDate(),
        month = date.getMonth() + 1,
        hours = date.getHours(),
        minutes = date.getMinutes();

    return (day < 10 ? '0' + day : day) + '/' + (month < 10 ? '0' + month : month) + ' ' +
        (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes);
  }

  function _cleanPids() {
    if (fs.existsSync(pidsPath)) {
      try {
        _this.log('allons-y', 'processes-clean-pids');

        fs.unlinkSync(pidsPath);
      }
      catch (err) {
        _this.logWarning('allons-y', 'processes-clean-pids-error', {
          error: err
        });
      }
    }
  }

  function _pids() {
    var pids = (fs.existsSync(pidsPath) ? fs.readFileSync(pidsPath, 'utf-8') : '').split('\n');

    for (var i = pids.length - 1; i >= 0; i--) {
      if (!pids[i]) {
        pids.splice(i, 1);
      }
      else {
        pids[i] = pids[i].split(':');
      }
    }

    return pids;
  }

  function _savePid(pid, processName) {
    if (!pid || !processName) {
      return false;
    }

    _this.log('allons-y', 'processes-pid-save:' + pid + ',' + processName);

    var pids = fs.existsSync(pidsPath) ? fs.readFileSync(pidsPath, 'utf-8') : '';
    pids += (pids ? '\n' : '') + pid + ':' + processName;

    fs.writeFileSync(pidsPath, pids);

    return true;
  }

  _this.liveCommand(['processes', 'p'], 'output the live processes list', function() {
    _this.outputInfo('\n► processes:\n\n');

    _children.forEach(function(child) {
      console.log([
        '  ■ [' + _logDate(child.startDate) + ']',
        _this.textInfo(child.name),
        (child.processes ? '(' + child.processes.length + ')' : ''),
        '#' + _this.textWarning(child.id)
      ].join(' '));

      if (child.processes) {
        child.processes.forEach(function(p) {
          console.log([
            '    ∙ [' + _logDate(p.restartDate) + ']',
            _this.textInfo(p.name),
            '(' + child.type + ')',
            '(' + p.forever.times + ' restarts)',
            '#' + _this.textWarning(p.id)
          ].join(' '));
        });
      }
    });

    console.log('');
  });

  function _findProcesses($args, splice) {
    $args = $args || [];
    $args[0] = ($args[0] || '')
      .toString()
      .replace('#', '');

    if (!$args[0]) {
      return null;
    }

    var id = $args[0],
        found = false;

    if (id.indexOf('0') === 0) {
      return false;
    }

    for (var i = 0; i < _children.length; i++) {
      var child = _children[i];

      if (child.id.toString() === id) {
        found = {
          id: id,
          name: child.name,
          processes: child.processes
        };

        if (splice) {
          _children.splice(i, 1);
        }

        break;
      }

      if (child.processes) {
        for (var j = 0; j < child.processes.length; j++) {
          if (child.processes[j].id.toString() === id) {
            found = {
              id: id,
              name: child.processes[j].name,
              processes: [child.processes[j]]
            };

            if (splice) {
              child.processes.splice(j, 1);
            }

            if (!child.processes.length) {
              _children.splice(i, 1);
            }

            break;
          }
        }
      }
    }

    return found === false ? -1 : found;
  }

  this.childByName = function(name) {
    for (var i = 0; i < _children.length; i++) {
      if (_children[i].name == name) {
        return _children[i];
      }
    }

    return null;
  };

  this.sendMessage = function(message, callback) {
    message = message || {};
    message = typeof message == 'object' ? message : {
      event: message
    };

    if (callback) {
      message.messageId = uuid.v1();
      _messagesCallbacks[message.messageId] = callback;
    }

    if (_isMain) {
      _children.forEach(function(child) {
        if (!child.processes) {
          return;
        }

        child.processes.forEach(function(p) {
          p.forever.send(message);
        });
      });
    }
    else if (_isFork) {
      process.send(message);
    }
  };

  _this.liveCommand('restart [process]', 'restart a process', function($args) {
    _this.outputInfo('\n► restart:\n\n');

    var found = _findProcesses($args);

    if (found === null) {
      return _this.outputWarning('\n  Set a process id for the "restart" command: restart [process]\n\n');
    }
    else if (found === false) {
      return _this.outputWarning('\n  You cannot restart Allons-y from the Live Commands\n\n');
    }
    else if (found === -1 || !found.processes) {
      return _this.outputWarning('\n  There is no process for this id\n\n');
    }

    for (var i = 0; i < found.processes.length; i++) {
      var p = found.processes[i];

      if (p.forever) {
        _this.log('allons-y', 'processes-restart:' + p.id + ',' + p.name);

        p.forever.restart();
      }
    }

    _this.outputSuccess('\n► process "' + found.name + '" (#' + found.id + ') restarted\n\n');
  });

  _this.liveCommand('kill [process]', 'shutdown a process', function($args) {
    _this.outputInfo('\n► kill:\n\n');

    var found = _findProcesses($args, true);

    if (found === null) {
      return _this.outputWarning('\n  Set a process id for the "kill" command: kill [process]\n\n');
    }
    else if (found === false) {
      return _this.outputWarning('\n  Use the "exit" command to shutdown Allons-y\n\n');
    }
    else if (found === -1 || !found.processes) {
      return _this.outputWarning('\n  There is no process for this id\n\n');
    }

    found.processes.forEach(function(p) {
      if (p.forever) {
        _this.log('allons-y', 'processes-stop:' + p.id + ',' + p.name);

        p.forever.stop();
      }
      if (p.watcher) {
        p.watcher.stop();
      }
    });

    _this.outputSuccess('\n► process "' + found.name + '" (#' + found.id + ') terminated\n\n');
  });

  _this.liveCommand('exit', 'shutdown allons-y', function() {
    _this.outputInfo('\n► exit\n\n');

    for (var i = 0; i < _children.length; i++) {
      var child = _children[i];

      if (child.processes && child.processes.length) {
        for (var j = 0; j < child.processes.length; j++) {
          if (child.processes[j].forever) {
            _this.log('allons-y', 'processes-stop:' + child.processes[j].id + ',' + child.processes[j].name);

            child.processes[j].forever.stop();
          }
          if (child.processes[j].watcher) {
            child.processes[j].watcher.stop();
          }
        }
      }
    }

    _cleanPids();

    _this.log('allons-y', 'exit');

    process.exit();
  });

  function _callModule(startModule, index, nextFile) {
    index = parseInt(index, 10);

    DependencyInjection.injector.controller.invoke(null, startModule.module, {
      controller: {
        $index: function() {
          return index;
        },

        $done: function() {
          return nextFile;
        }
      }
    });
  }

  function _messageReceived(message, child, p) {
    message = message || {};
    if (typeof message != 'object') {
      message = {
        event: message
      };
    }

    if (child) {
      message.child = child;
      message.p = p;
    }

    if (message.messageId && _messagesCallbacks[message.messageId]) {
      _messagesCallbacks[message.messageId](message);

      delete _messagesCallbacks[message.messageId];
    }

    _this.fire('message', message);
  }

  function _processEvents(p, child) {
    p.forever.on('restart', function() {
      p.restartDate = new Date();
    });

    p.forever.on('exit', function() {
      _findProcesses([p.id], true);
    });

    p.forever.on('watch:restart', function() {
      p.restartDate = new Date();
      _this.outputInfo('► [Watch] Restart "' + p.name + '" (#' + _this.outputWarning(p.id) + ')\n');
    });

    p.forever.on('message', function(message) {
      _messageReceived(message, child, p);
    });

    p.watcher.on('change', function() {
      _this.outputInfo('► [Watch] Restart "' + p.name + '" (#' + p.id + ')\n');
      p.forever.times--;
      p.forever.restart();
    });

    _savePid(p.forever.child.pid, p.name);
  }

  process.on('message', _messageReceived);

  this.start = function(dontStopBefore) {
    _isMain = true;

    if (!dontStopBefore) {
      return _this.stop(function() {
        _this.start(true);
      }, true);
    }

    _this.outputBanner();

    _savePid(process.pid, 'Allons-y');

    if (!process.env.ALLONSY_LIVE_COMMANDS || process.env.ALLONSY_LIVE_COMMANDS == 'true') {
      _this.outputInfo('  Live Commands is enabled. Use "help" to display the available commands.\n\n');
    }

    _this.bootstrap({
      owner: 'start'
    }, function() {
      var files = _this.findInFeaturesSync('*-allons-y-start.js');

      _this.log('allons-y', 'start', {
        files: files
      });

      async.mapSeries(files, function(file, nextFile) {
        var startModule = require(path.resolve(file));

        if (typeof startModule.enabled == 'boolean' && startModule.enabled === false) {
          return nextFile();
        }

        if (startModule.fork || startModule.spawn) {
          if (startModule.fork) {
            startModule.forkCount = startModule.forkCount || 1;
            startModule.forkMaxRestarts = startModule.forkMaxRestarts || 10;
          }
          else if (startModule.spawn) {
            startModule.spawnCount = startModule.spawnCount || 1;
            startModule.spawnArgs = startModule.spawnArgs || [];
            startModule.spawnMaxRestarts = startModule.spawnMaxRestarts || 10;
          }

          var count = startModule.fork ? startModule.forkCount : startModule.spawnCount,
              child = {
                name: startModule.name,
                id: ++_ids,
                ids: -1,
                type: startModule.fork ? 'fork' : 'spawn',
                startDate: new Date(),
                processes: []
              };

          _children.push(child);

          for (var i = 0; i < count; i++) {
            var pId = child.id + '.' + (++child.ids);

            _this.log('allons-y', 'processes-' + child.type + '-start:' + pId + ',' + child.name);

            _this.outputInfo('► Starting "' + child.name + '" (' + child.type + ')' + ' [' + (i + 1) + '/' + count + ']\n');

            var p = {
              name: child.name,
              id: pId,
              startDate: new Date(),
              restartDate: new Date(),
              watcher: _this.watcher(startModule.name, startModule.watch || null),
              forever: startModule.fork ?
                new (forever.Monitor)('./node_modules/allons-y/fork.js', {
                  fork: true,
                  max: startModule.forkMaxRestarts,
                  args: [file, i]
                }).start() :
                forever.start(startModule.spawnCommands, {
                  max: startModule.spawnMaxRestarts
                })
            };

            _processEvents(p, child);

            child.processes.push(p);
          }

          return nextFile();
        }

        _callModule(startModule, 0, nextFile);
      }, function() {

        _this.waitLiveCommand();

      });
    });
  };

  this.stop = function(callback, fromStart) {
    _this.bootstrap({
      owner: 'stop'
    }, function() {
      _this.log('allons-y', 'stop');

      var pids = _pids();

      if (!fromStart) {
        _this.outputBanner();

        _this.outputInfo('► stop\n\n');
      }

      pids.forEach(function(pid) {
        if (!pid) {
          return;
        }

        if (!fromStart) {
          _this.outputSuccess('  kill "' + pid[1] + '" (#' + pid[0] + ')\n');
        }

        _this.log('allons-y', 'processes-stop:' + pid[0] + ',' + pid[1]);

        forever.kill(pid[0]);
      });

      _cleanPids();

      if (!fromStart) {
        console.log('');
      }

      if (callback) {
        callback();
      }
    });
  };

  this.fork = function() {
    _isFork = true;

    _this.bootstrap({
      owner: 'fork'
    }, function() {
      if (process.argv.length < 4) {
        return;
      }

      var startModule = require(path.resolve(process.argv[2]));

      _this.log('allons-y', 'fork-exec:' + process.argv[3]);

      _callModule(startModule, process.argv[3], function() { });
    });
  };

};
<|endoftext|>


<commit_before>module.exports = function (sails) {

	/**
	 * Module dependencies.
	 */

	var util	= require('../../../util'),
		crypto	= require("crypto"),
		uuid	= require('node-uuid'),
		cookie				= require('express/node_modules/cookie'),
		parseSignedCookie	= require('express/node_modules/connect').utils.parseSignedCookie,
		ConnectSession		= require('express/node_modules/connect').middleware.session.Session;

	//////////////////////////////////////////////////////////////////////////////
	// TODO:
	//
	// All of this craziness can be replaced by making the socket.io interpreter
	// 100% connect-compatible (it's close!).  Then, the connect cookie parser
	// can be used directly with Sails' simulated req and res objects.
	//
	//////////////////////////////////////////////////////////////////////////////

	// Prototype for pseudo connect session store wrapper
	// include method to trigger a save() of the session data
	function SocketIOSession (options) {
		var sid = options.sid,
			data = options.data;

		this.save = function (cb) {

			if (!sid) {
				sails.log.error('Could not save session, since socket is not associated with a session id.');
				sails.log.error('(this probably means the socket did not send a cookie-- is this a cross-origin socket?)');
				if (cb) cb('Could not save session.');
				return;
			}

			// Merge data directly into instance to allow easy access on `req.session` later
			util.defaults(this, data);

			// Persist session
			Session.set(sid, data, function (err) {
				if (err) {
					sails.log.error('Could not save session:');
					sails.log.error(err);
				}
				if (cb) cb(err);
			});
		};

		// Set the data on this object, since it will be used as req.session
		util.extend(this, options.data);
	}

	// Session hook
	var Session = {

		defaults: {
			session: {
	            adapter: 'memory',
				key: "sails.sid"
			}
		},

		/**
		 * Normalize and validate configuration for this hook.
		 * Then fold any modifications back into `sails.config`
		 */
		configure: function () {

			// Validate config
			// Ensure that secret is specified if a custom session store is used
			if(sails.config.session) {
				if(!util.isObject(sails.config.session)) {
					throw new Error('Invalid custom session store configuration!\n' +
						'\n' +
						'Basic usage ::\n' +
						'{ session: { adapter: "memory", secret: "someVerySecureString", /* ...if applicable: host, port, etc... */ } }' +
						'\n\nCustom usage ::\n' +
						'{ session: { store: { /* some custom connect session store instance */ }, secret: "someVerySecureString", /* ...custom settings.... */ } }'
					);
				}

			}

			// If session config is set, but secret is undefined, set a secure, one-time use secret
			if(!sails.config.session || !sails.config.session.secret) {

				sails.log.warn('Session secret must be identified!');
				sails.log.warn('Automatically generating one for now...');
				if (sails.config.environment === 'production') {
					sails.log.error('But this generated session secret is not OK for production!');
					sails.log.error('It will change each time the server starts and break multi-instance deployments.');
					console.log();
					sails.log.error('To set up a session secret, add or update it in `config/session.js`:');
					sails.log.error('module.exports.session = { secret: "keyboardcat" }');
					console.log();
				}

				sails.config.session.secret = Session.generateSecret();
			}
		},

		/**
		 * Create a connection to the configured session store
		 * and keep it around
		 *
		 * @api private
		 */
		initialize: function (cb) {
			var sessionConfig = sails.config.session;

			// Intepret session adapter config and "new up" a session store
			if (util.isObject(sessionConfig) && !util.isObject(sessionConfig.store)) {
				switch (sessionConfig.adapter) {

					// Session explicitly disabled
					case null:
						// Do nothing...
						break;

					// Supported session adapters
					case 'memory':
						sessionConfig.store = new(require('express').session.MemoryStore)();
						break;
					case 'redis':
						sessionConfig.store = new(require('connect-redis')(require('express')))(sessionConfig);
						break;
					case 'mongo':
						sessionConfig.store = new(require('connect-mongo')(require('express')))(sessionConfig);
						break;

					// Unknown session adapter
					default:
						return cb( new Error('Invalid session adapter :: ' + sessionConfig.adapter) );
				}
			}

			// Save reference in `sails.session`
			sails.session = Session;

			return cb();
		},

		/**
		 * Create a new sid and build an empty session for it.
		 *
		 * @param {Object} handshake - a socket "handshake" -- basically, this is like `req`
		 * @param {Function} cb
		 * @returns live session, with `id` property === new sid
		 */
		generate: function (handshake, cb) {

			// Generate a session object w/ sid
			// This is important since we need this sort of object as the basis for the data
			// we'll save directly into the session store.
			// (handshake is a pretend `req` object, and 2nd argument is cookie config)
			var session = new ConnectSession(handshake, {
				cookie: {
					// Prevent access from client-side javascript
					httpOnly: true,

					// Restrict to path
					path: '/'
				}
			});

			// Next, persist the new session
			Session.set(session.id, session, function (err) {
				if (err) return cb(err);
				sails.log.verbose('Generated new session (',session.id,') for socket....');

				// Pass back final session object
				return cb(null, session);
			});

		},

		/**
		 * @param {String} sessionId
		 * @param {Function} cb
		 *
		 * @api private
		 */
		get: function (sessionId, cb) {
			if ( !util.isFunction(cb) ) {
				throw new Error('Invalid usage :: `Session.get(sessionId, cb)`');
			}
			return sails.config.session.store.get(sessionId, cb);
		},

		/**
		 * @param {String} sessionId
		 * @param {} data
		 * @param {Function} [cb] - optional
		 *
		 * @api private
		 */
		set: function (sessionId, data, cb) {
			cb = util.optional(cb);
			return sails.config.session.store.set(sessionId, data, cb);
		},

		// Generate session secret
		generateSecret: function () {

			// Combine random and case-specific factors into a base string
			var factors = {
				creationDate: (new Date()).getTime(),
				random: Math.random() * (Math.random() * 1000),
				nodeVersion: process.version
			};
			var basestring = '';
			util.each(factors, function (val) { basestring += val; });

			// Build hash
			var hash =	crypto.
						createHash("md5").
						update(basestring).
						digest("hex");

			return hash;
		},

		/**
		 * Create a session transaction
		 *
		 * Load the Connect session data using the sessionID in the socket.io handshake object
		 * Mix-in the session.save() method for persisting the data back to the session store.
		 *
		 * Functionally equivalent to connect's sessionStore middleware.
		 */

		fromSocket: function (socket, cb) {

			// If a socket makes it here, even though its associated session is not specified,
			// it's authorized as far as the app is concerned, so no need to do that again.
			// Instead, use the cookie to look up the sid, and then the sid to look up the session data

			// If sid doesn't exit in socket, we have to do a little work first to get it
			// (or generate a new one-- and therefore a new empty session as well)
			if ( !socket.handshake.sessionID && !socket.handshake.headers.cookie ) {

				// If no cookie exists, generate a random one (this will create a new session!)
				var generatedCookie = sails.config.session.key + '=' + uuid.v1();
				socket.handshake.headers.cookie = generatedCookie;
				sails.log.warn('Could not fetch session, since connecting socket (',socket.id,') has no cookie.');
				sails.log.warn('Is this a cross-origin socket..?)');
				sails.log.verbose('Generated a one-time-use cookie:',generatedCookie);
				sails.log.verbose('This will result in an empty session, i.e. (req.session === {})');

				// Convert cookie into `sid` using session secret
				// Maintain sid in socket so that the session can be queried before processing each incoming message
				socket.handshake.cookie = cookie.parse(generatedCookie);
				// Parse and decrypt cookie and save it in the socket.handshake
				socket.handshake.sessionID = parseSignedCookie(socket.handshake.cookie[sails.config.session.key], sails.config.session.secret);

				// Generate and persist a new session in the store
				Session.generate(socket.handshake, function (err, sessionData) {
					if (err) return cb(err);
					sails.log.silly('socket.handshake.sessionID is now :: ',socket.handshake.sessionID);

					// Provide access to adapter-agnostic `.save()`
					return cb(null, new SocketIOSession({
						sid: sessionData.id,
						data: sessionData
					}));
				});
				return;
			}

			// Convert cookie into `sid` using session secret
			// Maintain sid in socket so that the session can be queried before processing each incoming message
			socket.handshake.cookie = cookie.parse(socket.handshake.headers.cookie);
			// Parse and decrypt cookie and save it in the socket.handshake
			socket.handshake.sessionID = parseSignedCookie(socket.handshake.cookie[sails.config.session.key], sails.config.session.secret);

			// If sid DOES exist, it's easy to look up in the socket
			var sid = socket.handshake.sessionID;

			// Retrieve session data from store
			Session.get(sid, function (err, sessionData) {
				if (err) {
					sails.log.error('Error retrieving session from socket.');
					return cb(err);
				}

				// sid is not known-- the session secret probably changed
				// Or maybe server restarted and it was:
				// (a) using an auto-generated secret, or
				// (b) using the session memory store
				// and so it doesn't recognize the socket's session ID.
				else if (!sessionData) {
					sails.log.verbose('A socket ('+sid+') is trying to connect with an invalid or expired session ID (' + sid + ').');
					sails.log.verbose('Regnerating empty session...');

					Session.generate(socket.handshake, function (err, sessionData) {
						if (err) return cb(err);

						// Provide access to adapter-agnostic `.save()`
						return cb(null, new SocketIOSession({
							sid: sessionData.id,
							data: sessionData
						}));
					});
				}

				// Otherwise session exists and everything is ok.

				// Instantiate SocketIOSession (provides .save() method)
				// And extend it with session data
				return cb(null, new SocketIOSession({
					data: sessionData,
					sid: sid
				}));
			});
		}
	};

	return Session;
};
<commit_msg>Silence session secret warning in development env.<commit_after>module.exports = function (sails) {

	/**
	 * Module dependencies.
	 */

	var util	= require('../../../util'),
		crypto	= require("crypto"),
		uuid	= require('node-uuid'),
		cookie				= require('express/node_modules/cookie'),
		parseSignedCookie	= require('express/node_modules/connect').utils.parseSignedCookie,
		ConnectSession		= require('express/node_modules/connect').middleware.session.Session;

	//////////////////////////////////////////////////////////////////////////////
	// TODO:
	//
	// All of this craziness can be replaced by making the socket.io interpreter
	// 100% connect-compatible (it's close!).  Then, the connect cookie parser
	// can be used directly with Sails' simulated req and res objects.
	//
	//////////////////////////////////////////////////////////////////////////////

	// Prototype for pseudo connect session store wrapper
	// include method to trigger a save() of the session data
	function SocketIOSession (options) {
		var sid = options.sid,
			data = options.data;

		this.save = function (cb) {

			if (!sid) {
				sails.log.error('Could not save session, since socket is not associated with a session id.');
				sails.log.error('(this probably means the socket did not send a cookie-- is this a cross-origin socket?)');
				if (cb) cb('Could not save session.');
				return;
			}

			// Merge data directly into instance to allow easy access on `req.session` later
			util.defaults(this, data);

			// Persist session
			Session.set(sid, data, function (err) {
				if (err) {
					sails.log.error('Could not save session:');
					sails.log.error(err);
				}
				if (cb) cb(err);
			});
		};

		// Set the data on this object, since it will be used as req.session
		util.extend(this, options.data);
	}

	// Session hook
	var Session = {

		defaults: {
			session: {
	            adapter: 'memory',
				key: "sails.sid"
			}
		},

		/**
		 * Normalize and validate configuration for this hook.
		 * Then fold any modifications back into `sails.config`
		 */
		configure: function () {

			// Validate config
			// Ensure that secret is specified if a custom session store is used
			if(sails.config.session) {
				if(!util.isObject(sails.config.session)) {
					throw new Error('Invalid custom session store configuration!\n' +
						'\n' +
						'Basic usage ::\n' +
						'{ session: { adapter: "memory", secret: "someVerySecureString", /* ...if applicable: host, port, etc... */ } }' +
						'\n\nCustom usage ::\n' +
						'{ session: { store: { /* some custom connect session store instance */ }, secret: "someVerySecureString", /* ...custom settings.... */ } }'
					);
				}

			}

			// If session config is set, but secret is undefined, set a secure, one-time use secret
			if(!sails.config.session || !sails.config.session.secret) {

				sails.log.verbose('Session secret not defined-- automatically generating one for now...');

				if (sails.config.environment === 'production') {
					sails.log.warn('Session secret must be identified!');
					sails.log.warn('Automatically generating one for now...');

					sails.log.error('But this generated session secret is not OK for production!');
					sails.log.error('It will change each time the server starts and break multi-instance deployments.');
					console.log();
					sails.log.error('To set up a session secret, add or update it in `config/session.js`:');
					sails.log.error('module.exports.session = { secret: "keyboardcat" }');
					console.log();
				}

				sails.config.session.secret = Session.generateSecret();
			}
		},

		/**
		 * Create a connection to the configured session store
		 * and keep it around
		 *
		 * @api private
		 */
		initialize: function (cb) {
			var sessionConfig = sails.config.session;

			// Intepret session adapter config and "new up" a session store
			if (util.isObject(sessionConfig) && !util.isObject(sessionConfig.store)) {
				switch (sessionConfig.adapter) {

					// Session explicitly disabled
					case null:
						// Do nothing...
						break;

					// Supported session adapters
					case 'memory':
						sessionConfig.store = new(require('express').session.MemoryStore)();
						break;
					case 'redis':
						sessionConfig.store = new(require('connect-redis')(require('express')))(sessionConfig);
						break;
					case 'mongo':
						sessionConfig.store = new(require('connect-mongo')(require('express')))(sessionConfig);
						break;

					// Unknown session adapter
					default:
						return cb( new Error('Invalid session adapter :: ' + sessionConfig.adapter) );
				}
			}

			// Save reference in `sails.session`
			sails.session = Session;

			return cb();
		},

		/**
		 * Create a new sid and build an empty session for it.
		 *
		 * @param {Object} handshake - a socket "handshake" -- basically, this is like `req`
		 * @param {Function} cb
		 * @returns live session, with `id` property === new sid
		 */
		generate: function (handshake, cb) {

			// Generate a session object w/ sid
			// This is important since we need this sort of object as the basis for the data
			// we'll save directly into the session store.
			// (handshake is a pretend `req` object, and 2nd argument is cookie config)
			var session = new ConnectSession(handshake, {
				cookie: {
					// Prevent access from client-side javascript
					httpOnly: true,

					// Restrict to path
					path: '/'
				}
			});

			// Next, persist the new session
			Session.set(session.id, session, function (err) {
				if (err) return cb(err);
				sails.log.verbose('Generated new session (',session.id,') for socket....');

				// Pass back final session object
				return cb(null, session);
			});

		},

		/**
		 * @param {String} sessionId
		 * @param {Function} cb
		 *
		 * @api private
		 */
		get: function (sessionId, cb) {
			if ( !util.isFunction(cb) ) {
				throw new Error('Invalid usage :: `Session.get(sessionId, cb)`');
			}
			return sails.config.session.store.get(sessionId, cb);
		},

		/**
		 * @param {String} sessionId
		 * @param {} data
		 * @param {Function} [cb] - optional
		 *
		 * @api private
		 */
		set: function (sessionId, data, cb) {
			cb = util.optional(cb);
			return sails.config.session.store.set(sessionId, data, cb);
		},

		// Generate session secret
		generateSecret: function () {

			// Combine random and case-specific factors into a base string
			var factors = {
				creationDate: (new Date()).getTime(),
				random: Math.random() * (Math.random() * 1000),
				nodeVersion: process.version
			};
			var basestring = '';
			util.each(factors, function (val) { basestring += val; });

			// Build hash
			var hash =	crypto.
						createHash("md5").
						update(basestring).
						digest("hex");

			return hash;
		},

		/**
		 * Create a session transaction
		 *
		 * Load the Connect session data using the sessionID in the socket.io handshake object
		 * Mix-in the session.save() method for persisting the data back to the session store.
		 *
		 * Functionally equivalent to connect's sessionStore middleware.
		 */

		fromSocket: function (socket, cb) {

			// If a socket makes it here, even though its associated session is not specified,
			// it's authorized as far as the app is concerned, so no need to do that again.
			// Instead, use the cookie to look up the sid, and then the sid to look up the session data

			// If sid doesn't exit in socket, we have to do a little work first to get it
			// (or generate a new one-- and therefore a new empty session as well)
			if ( !socket.handshake.sessionID && !socket.handshake.headers.cookie ) {

				// If no cookie exists, generate a random one (this will create a new session!)
				var generatedCookie = sails.config.session.key + '=' + uuid.v1();
				socket.handshake.headers.cookie = generatedCookie;
				sails.log.warn('Could not fetch session, since connecting socket (',socket.id,') has no cookie.');
				sails.log.warn('Is this a cross-origin socket..?)');
				sails.log.verbose('Generated a one-time-use cookie:',generatedCookie);
				sails.log.verbose('This will result in an empty session, i.e. (req.session === {})');

				// Convert cookie into `sid` using session secret
				// Maintain sid in socket so that the session can be queried before processing each incoming message
				socket.handshake.cookie = cookie.parse(generatedCookie);
				// Parse and decrypt cookie and save it in the socket.handshake
				socket.handshake.sessionID = parseSignedCookie(socket.handshake.cookie[sails.config.session.key], sails.config.session.secret);

				// Generate and persist a new session in the store
				Session.generate(socket.handshake, function (err, sessionData) {
					if (err) return cb(err);
					sails.log.silly('socket.handshake.sessionID is now :: ',socket.handshake.sessionID);

					// Provide access to adapter-agnostic `.save()`
					return cb(null, new SocketIOSession({
						sid: sessionData.id,
						data: sessionData
					}));
				});
				return;
			}

			// Convert cookie into `sid` using session secret
			// Maintain sid in socket so that the session can be queried before processing each incoming message
			socket.handshake.cookie = cookie.parse(socket.handshake.headers.cookie);
			// Parse and decrypt cookie and save it in the socket.handshake
			socket.handshake.sessionID = parseSignedCookie(socket.handshake.cookie[sails.config.session.key], sails.config.session.secret);

			// If sid DOES exist, it's easy to look up in the socket
			var sid = socket.handshake.sessionID;

			// Retrieve session data from store
			Session.get(sid, function (err, sessionData) {
				if (err) {
					sails.log.error('Error retrieving session from socket.');
					return cb(err);
				}

				// sid is not known-- the session secret probably changed
				// Or maybe server restarted and it was:
				// (a) using an auto-generated secret, or
				// (b) using the session memory store
				// and so it doesn't recognize the socket's session ID.
				else if (!sessionData) {
					sails.log.verbose('A socket ('+sid+') is trying to connect with an invalid or expired session ID (' + sid + ').');
					sails.log.verbose('Regnerating empty session...');

					Session.generate(socket.handshake, function (err, sessionData) {
						if (err) return cb(err);

						// Provide access to adapter-agnostic `.save()`
						return cb(null, new SocketIOSession({
							sid: sessionData.id,
							data: sessionData
						}));
					});
				}

				// Otherwise session exists and everything is ok.

				// Instantiate SocketIOSession (provides .save() method)
				// And extend it with session data
				return cb(null, new SocketIOSession({
					data: sessionData,
					sid: sid
				}));
			});
		}
	};

	return Session;
};
<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
import {
  Button,
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
  TextInput,
  ListView,
  Alert
} from 'react-native';

import Icon from 'react-native-vector-icons/Entypo';
import { getNames, spliceMessage } from '../../services/mcServices';
import lodash from 'lodash';
import ModalComponent from './../../components/Modal';

/**
 * Sample view to demonstrate StackNavigator
 * @TODO remove this module in a live application.
 */
class CreateMessageView extends Component {
  constructor(props) {
    super(props);
    let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      background: 'red',
      currentMessage: this.props.navigation.state.params,
      Bcc: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Bcc,
      Cc: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Cc,
      From: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From,
      Subject: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Subject,
      MessageBody: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type === 'Draft' ? this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.MessageBody : '',
      LastMessageBody: lodash.isEmpty(this.props.navigation.state.params.Message) || (this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type === 'Draft') ? '' : spliceMessage(this.props.navigation.state.params.Message),
      To: [this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From],
      ToNames: this.props.navigation.state.params.Message && this.props.navigation.state.params.UserMessage.Type == 'Draft'?
        this.props.navigation.state.params.Message.To[0].PersonName : this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From.PersonName,
      BccNames: getNames(this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Bcc),
      CcNames: getNames(this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Cc),
      type: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type,
      id: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.MessageId,
      isModalVisible: false
    };
    this.data = [];
    this.ds = ds;
    this.hideModal = this.hideModal.bind(this);
    this.deleteModal = this.deleteModal.bind(this);
    this.save = this.save.bind(this);
  }
  static displayName = 'MessageDetailView';

  static navigationOptions = {
    header: {
      style: {
        height: 0
      }
    }
  }

  static propTypes = {
    navigate: PropTypes.func.isRequired
  };

  componentWillReceiveProps(nextProps) {
    try {
      if (nextProps.contactData !== this.props.contactData) {
        switch (nextProps.boxType) {
          case 'ToNames':
            this.setState({
              To: nextProps.contactData,
              ToNames: getNames(nextProps.contactData)
            })
            break;
          case 'CcNames':
            this.setState({
              Cc: nextProps.contactData,
              CcNames: getNames(nextProps.contactData)
            })
            break;
          case 'BccNames':
            this.setState({
              Bcc: nextProps.contactData,
              BccNames: getNames(nextProps.contactData)
            })
            break;
          default:
            return
        }
      }
    } catch (err) {
      console.log(err)
    }
  }

  send() {
    let formData = new FormData();
    let message = {}
    message.Bcc = this.state.Bcc;
    message.Cc = this.state.Cc;
    message.To = this.state.To;
    message.Subject = this.state.Subject;
    message.MessageBody = this.state.MessageBody + '\n\n' + this.state.LastMessageBody;
    message.From = { PersonName: this.props.userId, Id: this.props.userId };
    if(this.state.type && this.state.type == 'Draft'){
      message.Id = this.state.id;
    }
    formData.append('message', JSON.stringify(message))
    this.props.CreateMessageStateActions.sendMessage(formData);
     if(this.state.type == 'Inbox' || this.state.type == 'Sent'){
      this.props.navigation.goBack(null);
    }else if(this.state.type == 'Draft'){
      this.props.InboxStateActions.getMessages(this.props.userId, 'Draft');
      this.props.navigate({routeName: 'DraftStack'});
    }else{
      this.props.InboxStateActions.getMessages(this.props.userId, 'Inbox');
      this.props.navigate({routeName: 'InboxStack'});
    }
  }

  selectName(nameType) {
    this.props.CreateMessageStateActions.selectNames(nameType);
    this.props.navigate({ routeName: 'ContactStack' });
  }

  back() {
    return this.setState({ isModalVisible: true })
  }

  hideModal() {
    return this.setState({ isModalVisible: false })
  }

  deleteModal() {
    this.props.navigation.goBack(null);
  }

  save() {
    let formData = new FormData();
    let message = {}
    message.Bcc = this.state.Bcc;
    message.Cc = this.state.Cc;
    message.To = this.state.To;
    message.Subject = this.state.Subject;
    message.MessageBody = this.state.MessageBody + this.state.LastMessageBody;
    message.From = { PersonName: this.props.userId, Id: this.props.userId  };
    if(this.state.type && this.state.type == 'Draft'){
      message.Id = this.state.id;
    }
    formData.append('message', JSON.stringify(message));
    this.props.CreateMessageStateActions.saveAsDraft(formData);
    this.props.navigation.goBack(null);
  }

  render() {
    return (
      <View>
        <View style={{ flexDirection: 'row', height: 50, borderBottomWidth: 1, borderBottomColor: '#ccc', alignItems: 'center', backgroundColor: '#39babd' }}>
          <TouchableOpacity onPress={() => this.back()} style={{ flex: 1 }}>
            <Icon name='arrow-left' size={30} color={'orange'} />
          </TouchableOpacity>
          <Text style={{ flex: 5, textAlign: 'left' }}>CreateMessage</Text>
          <TouchableOpacity style={{ flex: 1 }} onPress={() => this.send()}>
            <Icon name='direction' size={30} color={'orange'} />
          </TouchableOpacity>
        </View>
        <View style={{ marginLeft: 10, marginTop: 10, marginRight: 10, flexDirection: 'column' }}>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>To:</Text>
            <TextInput value={this.state.ToNames} onChangeText={(PersonName) => {
              this.setState({
                'To': {
                  'PersonName': PersonName,
                  'Id': PersonName
                }
              })
            }}
              style={{ flex: 1 }}>
            </TextInput>
            <TouchableOpacity onPress={() => this.selectName('ToNames')}>
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Cc:</Text>
            <TextInput value={this.state.CcNames} onChangeText={(text) => {
              this.setState({
                'Cc': {
                  'PersonName': text,
                  'Id': text
                }
              })
            }}
              style={{ flex: 1 }}>
            </TextInput>
            <TouchableOpacity onPress={() => this.selectName('CcNames')} >
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Bcc:</Text>
            <TextInput value={this.state.BccNames} style={{ flex: 1 }}></TextInput>
            <TouchableOpacity onPress={() => this.selectName('BccNames')}>
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Subject:</Text>
            <TextInput value={this.state.Subject} onChangeText={(Subject) => { this.setState({ Subject }) }} style={{ flex: 1 }}></TextInput>
          </View>
          <View style={{ flexDirection: 'column', height: 300 }}>
            <TextInput style={{ flex: 1, borderColor: 'gray', borderLeftWidth: 0, borderRightWidth: 0, borderBottomWidth: 0, borderTopWidth: 0.1, textAlignVertical: 'top' }} autoFocus={true} onChangeText={(text) => this.setState({ 'MessageBody': text })} value={this.state.MessageBody} multiline={true} />
            {lodash.isEmpty(this.state.LastMessageBody) ? null : <TextInput style={{ flex: 1, borderColor: 'gray', borderLeftWidth: 0, borderRightWidth: 0, borderTopWidth: 1, textAlignVertical: 'top' }} onChangeText={(text) => this.setState({ 'LastMessageBody': text })} value={this.state.LastMessageBody} multiline={true} />}
          </View>
        </View>
        <ModalComponent isModalVisible={this.state.isModalVisible} hideModal={this.hideModal} deleteModal={this.deleteModal} save={this.save} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

export default CreateMessageView;
<commit_msg>fix bug - show all the field item in the  createView page<commit_after>import React, { PropTypes, Component } from 'react';
import {
  Button,
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
  TextInput,
  ListView,
  Alert
} from 'react-native';

import Icon from 'react-native-vector-icons/Entypo';
import { getNames, spliceMessage } from '../../services/mcServices';
import lodash from 'lodash';
import ModalComponent from './../../components/Modal';

/**
 * Sample view to demonstrate StackNavigator
 * @TODO remove this module in a live application.
 */
class CreateMessageView extends Component {
  constructor(props) {
    super(props);
    let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
    this.state = {
      background: 'red',
      currentMessage: this.props.navigation.state.params,
      Bcc: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Bcc,
      Cc: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Cc,
      From: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From,
      Subject: this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Subject,
      MessageBody: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type === 'Draft' ? this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.MessageBody : '',
      LastMessageBody: lodash.isEmpty(this.props.navigation.state.params.Message) || (this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type === 'Draft') ? '' : spliceMessage(this.props.navigation.state.params.Message),
      To: [this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From],
      ToNames: this.props.navigation.state.params.Message && this.props.navigation.state.params.UserMessage.Type == 'Draft'?
        getNames(this.props.navigation.state.params.Message.To) : this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.From.PersonName,
      BccNames: getNames(this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Bcc),
      CcNames: getNames(this.props.navigation.state.params.Message && this.props.navigation.state.params.Message.Cc),
      type: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.Type,
      id: this.props.navigation.state.params.UserMessage && this.props.navigation.state.params.UserMessage.MessageId,
      isModalVisible: false
    };
    this.data = [];
    this.ds = ds;
    this.hideModal = this.hideModal.bind(this);
    this.deleteModal = this.deleteModal.bind(this);
    this.save = this.save.bind(this);
  }
  static displayName = 'MessageDetailView';

  static navigationOptions = {
    header: {
      style: {
        height: 0
      }
    }
  }

  static propTypes = {
    navigate: PropTypes.func.isRequired
  };

  componentWillReceiveProps(nextProps) {
    try {
      if (nextProps.contactData !== this.props.contactData) {
        switch (nextProps.boxType) {
          case 'ToNames':
            this.setState({
              To: nextProps.contactData,
              ToNames: getNames(nextProps.contactData)
            })
            break;
          case 'CcNames':
            this.setState({
              Cc: nextProps.contactData,
              CcNames: getNames(nextProps.contactData)
            })
            break;
          case 'BccNames':
            this.setState({
              Bcc: nextProps.contactData,
              BccNames: getNames(nextProps.contactData)
            })
            break;
          default:
            return
        }
      }
    } catch (err) {
      console.log(err)
    }
  }

  send() {
    let formData = new FormData();
    let message = {}
    message.Bcc = this.state.Bcc;
    message.Cc = this.state.Cc;
    message.To = this.state.To;
    message.Subject = this.state.Subject;
    message.MessageBody = this.state.MessageBody + '\n\n' + this.state.LastMessageBody;
    message.From = { PersonName: this.props.userId, Id: this.props.userId };
    if(this.state.type && this.state.type == 'Draft'){
      message.Id = this.state.id;
    }
    formData.append('message', JSON.stringify(message))
    this.props.CreateMessageStateActions.sendMessage(formData);
     if(this.state.type == 'Inbox' || this.state.type == 'Sent'){
      this.props.navigation.goBack(null);
    }else if(this.state.type == 'Draft'){
      this.props.InboxStateActions.getMessages(this.props.userId, 'Draft');
      this.props.navigate({routeName: 'DraftStack'});
    }else{
      this.props.InboxStateActions.getMessages(this.props.userId, 'Inbox');
      this.props.navigate({routeName: 'InboxStack'});
    }
  }

  selectName(nameType) {
    this.props.CreateMessageStateActions.selectNames(nameType);
    this.props.navigate({ routeName: 'ContactStack' });
  }

  back() {
    return this.setState({ isModalVisible: true })
  }

  hideModal() {
    return this.setState({ isModalVisible: false })
  }

  deleteModal() {
    this.props.navigation.goBack(null);
  }

  save() {
    let formData = new FormData();
    let message = {}
    message.Bcc = this.state.Bcc;
    message.Cc = this.state.Cc;
    message.To = this.state.To;
    message.Subject = this.state.Subject;
    message.MessageBody = this.state.MessageBody + this.state.LastMessageBody;
    message.From = { PersonName: this.props.userId, Id: this.props.userId  };
    if(this.state.type && this.state.type == 'Draft'){
      message.Id = this.state.id;
    }
    formData.append('message', JSON.stringify(message));
    this.props.CreateMessageStateActions.saveAsDraft(formData);
    this.props.navigation.goBack(null);
  }

  render() {
    return (
      <View>
        <View style={{ flexDirection: 'row', height: 50, borderBottomWidth: 1, borderBottomColor: '#ccc', alignItems: 'center', backgroundColor: '#39babd' }}>
          <TouchableOpacity onPress={() => this.back()} style={{ flex: 1 }}>
            <Icon name='arrow-left' size={30} color={'orange'} />
          </TouchableOpacity>
          <Text style={{ flex: 5, textAlign: 'left' }}>CreateMessage</Text>
          <TouchableOpacity style={{ flex: 1 }} onPress={() => this.send()}>
            <Icon name='direction' size={30} color={'orange'} />
          </TouchableOpacity>
        </View>
        <View style={{ marginLeft: 10, marginTop: 10, marginRight: 10, flexDirection: 'column' }}>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>To:</Text>
            <TextInput value={this.state.ToNames} onChangeText={(PersonName) => {
              this.setState({
                'To': {
                  'PersonName': PersonName,
                  'Id': PersonName
                }
              })
            }}
              style={{ flex: 1 }}>
            </TextInput>
            <TouchableOpacity onPress={() => this.selectName('ToNames')}>
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Cc:</Text>
            <TextInput value={this.state.CcNames} onChangeText={(text) => {
              this.setState({
                'Cc': {
                  'PersonName': text,
                  'Id': text
                }
              })
            }}
              style={{ flex: 1 }}>
            </TextInput>
            <TouchableOpacity onPress={() => this.selectName('CcNames')} >
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Bcc:</Text>
            <TextInput value={this.state.BccNames} style={{ flex: 1 }}></TextInput>
            <TouchableOpacity onPress={() => this.selectName('BccNames')}>
              <Icon name='circle-with-plus' size={30} color={'#007FFB'} />
            </TouchableOpacity>
          </View>
          <View style={{ flexDirection: 'row', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: '#ddd' }}>
            <Text style={{ fontSize: 16, textAlign: 'center' }}>Subject:</Text>
            <TextInput value={this.state.Subject} onChangeText={(Subject) => { this.setState({ Subject }) }} style={{ flex: 1 }}></TextInput>
          </View>
          <View style={{ flexDirection: 'column', height: 300 }}>
            <TextInput style={{ flex: 1, borderColor: 'gray', borderLeftWidth: 0, borderRightWidth: 0, borderBottomWidth: 0, borderTopWidth: 0.1, textAlignVertical: 'top' }} autoFocus={true} onChangeText={(text) => this.setState({ 'MessageBody': text })} value={this.state.MessageBody} multiline={true} />
            {lodash.isEmpty(this.state.LastMessageBody) ? null : <TextInput style={{ flex: 1, borderColor: 'gray', borderLeftWidth: 0, borderRightWidth: 0, borderTopWidth: 1, textAlignVertical: 'top' }} onChangeText={(text) => this.setState({ 'LastMessageBody': text })} value={this.state.LastMessageBody} multiline={true} />}
          </View>
        </View>
        <ModalComponent isModalVisible={this.state.isModalVisible} hideModal={this.hideModal} deleteModal={this.deleteModal} save={this.save} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
});

export default CreateMessageView;
<|endoftext|>


<commit_before>#!/usr/bin/env node

var routes = require('../lib/routes.js');
var videos = require('../lib/videos.js');
var async = require('async');

var sourceIndividual;
var seenIndividuals = [];
var seenTracks = [];
var seenArtists = [];

var error = function (err) {
	if (err) {
		console.log('Error: ', err.message);
		process.exit(1);
	}
};

var random = function (array) {
	return array[Math.floor(Math.random()*array.length)];
};

var valuesNotIn = function (values, notIn) {
	// returns values from values that are not in notIn
	return values.filter( function (value) {
		return notIn.indexOf( value ) === -1;
	});
};

var generatePlaylist = function (individual, done) {
	var fulfill = 	function (tracks) {
		var track;

		var notSeenTracks = valuesNotIn(tracks, seenTracks);
		if (notSeenTracks.length > 0) {
			track = random(notSeenTracks);
			seenTracks.push(track);
		} else {
			track = random(tracks);
		}
		if (! track) {
			nextIndex = nextIndex +1;
			next[nextIndex]();
			return;
		}
		routes.getTrackDetails(track, function (err, details) {
			error(err);

			if (!details) {
				error(new Error('No details for ' + track));
			}

			var theseArtistMids = details.artists.map(function (value) { return value.mid; });
			seenArtists = seenArtists.concat(valuesNotIn(theseArtistMids, seenArtists));
			var name = details.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS TRACK';
			var artist = details.artists.map(function (value) {
				return value.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS ARTIST';
			}).join(' & ');
			var release = random(details.releases).name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS RELEASE';

			var output = '"' + name + '"';
			output += '\n' + artist;
			output += '\n_' + release + '_';

			var q = '"' + name + '" "' + artist + '" "' + release + '"';
			console.log(output);

			var writeVideoUrl = function (data) {
				if (data.items[0] && data.items[0].videoId) {
					console.log('http://youtu.be/' + data.items[0].videoId);
				}
			};

			var nextinator = function () {
				routes.getArtistsAndContributorsFromTracks([track], function (err, contributors) {
					error(err);
					var contributor;
					var notSeen = valuesNotIn(contributors, seenIndividuals);
					if (notSeen.length > 0) {
						contributor = random(notSeen);
						seenIndividuals.push(contributor);
					} else {
						contributor = random(contributors);
					}
					routes.getArtistDetails(contributor, function (err, details) {
						error(err);
						var name = details.name || 'WHOOPS, FREEBASE DOES NOT HAVE AN ENGLISH NAME FOR THIS PERSON';
						console.log('\n ... with ' + name + ' ... \n');
						sourceIndividual = contributor;
						done();
					});
				});
			};

			videos.search(q)
			.then(writeVideoUrl)
			.then(nextinator);
		});
	};

	var options = {subquery: {
		artist: [{
					'mid|=': seenArtists,
					optional: 'forbidden'
		}]
	}};

	// next[nextIndex] = what function to invoke if the current one doesn't find a track
	var nextIndex = 0;
	var next = [
		// Find a track by an artist we haven't seen yet.
		function () {
			if (seenArtists.length === 0) {
				// If this is the first track, get one by this artist if we can.
				routes.getTracksByArtists([individual]).then(fulfill, error);
			} else {
				// Otherwise, get one by an artist we haven't seen yet
				routes.getTracksWithContributors([individual], options).then(fulfill, error);
			}
		},
		function () {
			routes.getTracksWithContributors([individual], options).then(fulfill, error);
		},
		// Look for any track with this contributor credited as a contributor regardless if we've seen the artist already.
		function () {
			routes.getTracksWithContributors([individual], {}).then(fulfill, error);
		},
		// Look for any tracks actually credited to this contributor as the main artist. We are desperate!
		function () {
			routes.getTracksByArtists([individual]).then(fulfill, error);
		},
		// Give up
		error.bind(undefined, new Error('Could not find any tracks for contributor ' + individual))
	];

	// Kick it off
	next[nextIndex]();
};

var startingPoint = process.argv[2] || 'Todd Rundgren';

var kickOff = function(mids) {
	sourceIndividual = mids[0];
	if (! sourceIndividual) {
		console.log('Could not find an artist named ' + process.argv[2]);
		process.exit(0);
	}
	seenIndividuals.push(sourceIndividual);
	async.forever(
		function (next) {
			generatePlaylist(sourceIndividual, next);
		},
		error
	);
};

routes.getMids(startingPoint, '/music/artist')
.then(kickOff, error);<commit_msg>update playlist.js for promisified method<commit_after>#!/usr/bin/env node
/* global -Promise */

var routes = require('../lib/routes.js');
var videos = require('../lib/videos.js');
var async = require('async');
var Promise = require('promise');

var sourceIndividual;
var seenIndividuals = [];
var seenTracks = [];
var seenArtists = [];

var error = function (err) {
	if (err) {
		console.log('Error: ', err.message);
		process.exit(1);
	}
};

var random = function (array) {
	return array[Math.floor(Math.random()*array.length)];
};

var valuesNotIn = function (values, notIn) {
	// returns values from values that are not in notIn
	return values.filter( function (value) {
		return notIn.indexOf( value ) === -1;
	});
};

var generatePlaylist = function (individual, done) {
	var fulfill = 	function (tracks) {
		var track;

		var notSeenTracks = valuesNotIn(tracks, seenTracks);
		if (notSeenTracks.length > 0) {
			track = random(notSeenTracks);
			seenTracks.push(track);
		} else {
			track = random(tracks);
		}
		if (! track) {
			nextIndex = nextIndex +1;
			next[nextIndex]();
			return;
		}
		routes.getTrackDetails(track, function (err, details) {
			error(err);

			if (!details) {
				error(new Error('No details for ' + track));
			}

			var theseArtistMids = details.artists.map(function (value) { return value.mid; });
			seenArtists = seenArtists.concat(valuesNotIn(theseArtistMids, seenArtists));
			var name = details.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS TRACK';
			var artist = details.artists.map(function (value) {
				return value.name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS ARTIST';
			}).join(' & ');
			var release = random(details.releases).name || 'WHOOPS, FREEBASE DOES NOT APPEAR TO HAVE AN ENGLISH NAME FOR THIS RELEASE';

			var output = '"' + name + '"';
			output += '\n' + artist;
			output += '\n_' + release + '_';

			var q = '"' + name + '" "' + artist + '" "' + release + '"';
			console.log(output);

			var writeVideoUrl = function (data) {
				if (data.items[0] && data.items[0].videoId) {
					console.log('http://youtu.be/' + data.items[0].videoId);
				}
			};

			var pickContributor = function (contributors) {
				return new Promise(function (fulfill, reject) {
					var contributor;
					var notSeen = valuesNotIn(contributors, seenIndividuals);
					if (notSeen.length > 0) {
						contributor = random(notSeen);
						seenIndividuals.push(contributor);
					} else {
						contributor = random(contributors);
					}

					if (contributor) {
						fulfill(contributor);
					} else {
						reject(Error('No contributor found for track'));
					}
				});
			};

			var removeMeAfterPromisifyingGetArtistDetails = function (contributor) {
				return new Promise(function (fulfill, reject) {
					routes.getArtistDetails(contributor, function (err, details) {
						if (err) {
							return reject(err);
						}
						var name = details.name || 'WHOOPS, FREEBASE DOES NOT HAVE AN ENGLISH NAME FOR THIS PERSON';
						console.log('\n ... with ' + name + ' ... \n');
						sourceIndividual = contributor;
						done();
					});
				});
			};

			var nextinator = function () {
				routes.getArtistsAndContributorsFromTracks([track])
					.then(pickContributor, error)
					.then(removeMeAfterPromisifyingGetArtistDetails, error);
			};

			videos.search(q)
			.then(writeVideoUrl)
			.then(nextinator);
		});
	};

	var options = {subquery: {
		artist: [{
					'mid|=': seenArtists,
					optional: 'forbidden'
		}]
	}};

	// next[nextIndex] = what function to invoke if the current one doesn't find a track
	var nextIndex = 0;
	var next = [
		// Find a track by an artist we haven't seen yet.
		function () {
			if (seenArtists.length === 0) {
				// If this is the first track, get one by this artist if we can.
				routes.getTracksByArtists([individual]).then(fulfill, error);
			} else {
				// Otherwise, get one by an artist we haven't seen yet
				routes.getTracksWithContributors([individual], options).then(fulfill, error);
			}
		},
		function () {
			routes.getTracksWithContributors([individual], options).then(fulfill, error);
		},
		// Look for any track with this contributor credited as a contributor regardless if we've seen the artist already.
		function () {
			routes.getTracksWithContributors([individual], {}).then(fulfill, error);
		},
		// Look for any tracks actually credited to this contributor as the main artist. We are desperate!
		function () {
			routes.getTracksByArtists([individual]).then(fulfill, error);
		},
		// Give up
		error.bind(undefined, new Error('Could not find any tracks for contributor ' + individual))
	];

	// Kick it off
	next[nextIndex]();
};

var startingPoint = process.argv[2] || 'Todd Rundgren';

var kickOff = function(mids) {
	sourceIndividual = mids[0];
	if (! sourceIndividual) {
		console.log('Could not find an artist named ' + process.argv[2]);
		process.exit(0);
	}
	seenIndividuals.push(sourceIndividual);
	async.forever(
		function (next) {
			generatePlaylist(sourceIndividual, next);
		},
		error
	);
};

routes.getMids(startingPoint, '/music/artist')
.then(kickOff, error);<|endoftext|>


<commit_before>var gulp         = require('gulp');
var plumber      = require('gulp-plumber');
var transform    = require('vinyl-transform');
var map          = require('map-stream');
var add          = require('gulp-add');
var filter       = require('gulp-filter');
var insert       = require('gulp-insert');
var notify       = require('gulp-notify');
var displayError = require('../../utils/displayError');
var pumped       = require('../../utils/pumped');

// config
var project      = require('../../../package.json');
var config       = require('../../config/theme');
var includeDev   = require('../../config/templates/devmode.php.include');
var style        = require('../../config/templates/wordpress.style.css');
var bSSnippet    = require('../../config/templates/browser-sync.snippet');

/**
 * Move the Theme to
 * the build directory
 * add required files
 * and add browser-sync
 * snippet
 *
 * @returns {*}
 */
module.exports = function () {
	var filterPHP  = filter('**/*.php');
	var filterFunc = filter('functions.php');

	return gulp.src(config.paths.src)
		.pipe(plumber({ errorHandler: displayError }))

		.pipe(filterPHP) // Filter php files and transform
		                 // them to simply include the file
		                 // from the dev theme. This is to
		                 // make it possible to debug php from
		                 // within the dev theme
		.pipe(transform(function (filename) {
			return map(function (chunk, next) {
				return next(null, includeDev(filename));
			});
		}))
		.pipe(filterPHP.restore())

		.pipe(add({
			'.gitignore': '*',
			'style.css': style
		}))

		.pipe(filterFunc) // We only want to append the
		                  // Browser-sync snippet to the
		                  // functions.php so we need to
		                  // filter the gulp stream
		.pipe(insert.append(bSSnippet))
		.pipe(filterFunc.restore())

		.pipe(gulp.dest(config.paths.dest))
		.pipe(notify({
			message: pumped('Theme Moved!'),
			onLast: true
		}));
};<commit_msg>Add support for page templales<commit_after>var gulp         = require('gulp');
var plumber      = require('gulp-plumber');
var transform    = require('vinyl-transform');
var map          = require('map-stream');
var add          = require('gulp-add');
var filter       = require('gulp-filter');
var insert       = require('gulp-insert');
var notify       = require('gulp-notify');
var displayError = require('../../utils/displayError');
var pumped       = require('../../utils/pumped');

// config
var project      = require('../../../package.json');
var config       = require('../../config/theme');
var includeDev   = require('../../config/templates/devmode.php.include');
var style        = require('../../config/templates/wordpress.style.css');
var bSSnippet    = require('../../config/templates/browser-sync.snippet');

/**
 * Move the Theme to
 * the build directory
 * add required files
 * and add browser-sync
 * snippet
 *
 * @returns {*}
 */
module.exports = function () {
	var filterPHP  = filter('**/*.php');
	var filterFunc = filter('functions.php');

	return gulp.src(config.paths.src)
		.pipe(plumber({ errorHandler: displayError }))

		.pipe(filterPHP) // Filter php files and transform
		                 // them to simply include the file
		                 // from the dev theme. This is to
		                 // make it possible to debug php from
		                 // within the dev theme
		.pipe(transform(function (filename) {
			return map(function (chunk, next) {
				var templateDef = chunk.toString().match(/Template Name:.+/);
				if (templateDef) {
					templateDef = templateDef[0];
				}
				return next(null, includeDev(filename, templateDef));
			});
		}))
		.pipe(filterPHP.restore())

		.pipe(add({
			'.gitignore': '*',
			'style.css': style
		}))

		.pipe(filterFunc) // We only want to append the
		                  // Browser-sync snippet to the
		                  // functions.php so we need to
		                  // filter the gulp stream
		.pipe(insert.append(bSSnippet))
		.pipe(filterFunc.restore())

		.pipe(gulp.dest(config.paths.dest))
		.pipe(notify({
			message: pumped('Theme Moved!'),
			onLast: true
		}));
};
<|endoftext|>


<commit_before>var jwt = require('jsonwebtoken');
var UnauthorizedError = require('./errors/UnauthorizedError');
var unless = require('express-unless');
var async = require('async');

var DEFAULT_REVOKED_FUNCTION = function(_, __, cb) { return cb(null, false); }

var getClass = {}.toString;
function isFunction(object) {
  return object && getClass.call(object) == '[object Function]';
}

function wrapStaticSecretInCallback(secret){
  return function(_, __, cb){
    return cb(null, secret);
  };
}

module.exports = function(options) {
  if (!options || !options.secret) throw new Error('secret should be set');

  var secretCallback = options.secret;

  if (!isFunction(secretCallback)){
    secretCallback = wrapStaticSecretInCallback(secretCallback);
  }

  var isRevokedCallback = options.isRevoked || DEFAULT_REVOKED_FUNCTION;

  var _requestProperty = options.userProperty || options.requestProperty || 'user';
  var credentialsRequired = typeof options.credentialsRequired === 'undefined' ? true : options.credentialsRequired;

  var middleware = function(req, res, next) {
    var token;

    if (req.method === 'OPTIONS' && req.headers.hasOwnProperty('access-control-request-headers')) {
      var hasAuthInAccessControl = !!~req.headers['access-control-request-headers']
                                    .split(',').map(function (header) {
                                      return header.trim();
                                    }).indexOf('authorization');

      if (hasAuthInAccessControl) {
        return next();
      }
    }

    if (typeof options.skip !== 'undefined') {
      console.warn('WARN: express-jwt: options.skip is deprecated');
      console.warn('WARN: use app.use(jwt(options).unless({path: \'/x\'}))');
      if (options.skip.indexOf(req.url) > -1) {
        return next();
      }
    }

    if (options.getToken && typeof options.getToken === 'function') {
      try {
        token = options.getToken(req);
      } catch (e) {
        return next(e);
      }
    } else if (req.headers && req.headers.authorization) {
      var parts = req.headers.authorization.split(' ');
      if (parts.length == 2) {
        var scheme = parts[0];
        var credentials = parts[1];

        if (/^Bearer$/i.test(scheme)) {
          token = credentials;
        } else {
          return next(new UnauthorizedError('credentials_bad_scheme', { message: 'Format is Authorization: Bearer [token]' }));
        }
      } else {
        return next(new UnauthorizedError('credentials_bad_format', { message: 'Format is Authorization: Bearer [token]' }));
      }
    }

    if (!token) {
      if (credentialsRequired) {
        return next(new UnauthorizedError('credentials_required', { message: 'No authorization token was found' }));
      } else {
        return next();
      }
    }

    var dtoken = jwt.decode(token, { complete: true }) || {};

    async.parallel([
      function(callback){
        var arity = secretCallback.length;
        if (arity == 4) {
          secretCallback(req, dtoken.header, dtoken.payload, callback);
        } else { // arity == 3
          secretCallback(req, dtoken.payload, callback);
        }
      },
      function(callback){
        isRevokedCallback(req, dtoken.payload, callback);
      }
    ], function(err, results){
      if (err) { return next(err); }
      var revoked = results[1];
      if (revoked){
        return next(new UnauthorizedError('revoked_token', { message: 'The token has been revoked.'}));
      }

      var secret = results[0];

      jwt.verify(token, secret, options, function(err, decoded) {
        if (err && credentialsRequired) return next(new UnauthorizedError('invalid_token', err));

        req[_requestProperty] = decoded;
        next();
      });
    });
  };

  middleware.unless = unless;

  return middleware;
};
<commit_msg>Update index.js<commit_after>var jwt = require('jsonwebtoken');
var UnauthorizedError = require('./errors/UnauthorizedError');
var unless = require('express-unless');
var async = require('async');

var DEFAULT_REVOKED_FUNCTION = function(_, __, cb) { return cb(null, false); }

var getClass = {}.toString;
function isFunction(object) {
  return object && getClass.call(object) == '[object Function]';
}

function wrapStaticSecretInCallback(secret){
  return function(_, __, cb){
    return cb(null, secret);
  };
}

module.exports = function(options) {
  if (!options || !options.secret) throw new Error('secret should be set');

  var secretCallback = options.secret;

  if (!isFunction(secretCallback)){
    secretCallback = wrapStaticSecretInCallback(secretCallback);
  }

  var isRevokedCallback = options.isRevoked || DEFAULT_REVOKED_FUNCTION;

  var _requestProperty = options.userProperty || options.requestProperty || 'user';
  var credentialsRequired = typeof options.credentialsRequired === 'undefined' ? true : options.credentialsRequired;

  var middleware = function(req, res, next) {
    var token;

    if (req.method === 'OPTIONS' && req.headers.hasOwnProperty('access-control-request-headers')) {
      var hasAuthInAccessControl = !!~req.headers['access-control-request-headers']
                                    .split(',').map(function (header) {
                                      return header.trim();
                                    }).indexOf('authorization');

      if (hasAuthInAccessControl) {
        return next();
      }
    }

    if (typeof options.skip !== 'undefined') {
      console.warn('WARN: express-jwt: options.skip is deprecated');
      console.warn('WARN: use app.use(jwt(options).unless({path: \'/x\'}))');
      if (options.skip.indexOf(req.url) > -1) {
        return next();
      }
    }

    if (options.getToken && typeof options.getToken === 'function') {
      try {
        token = options.getToken(req);
      } catch (e) {
        return next(e);
      }
    } else if (req.headers && req.headers.authorization) {
      var parts = req.headers.authorization.split(' ');
      if (parts.length == 2) {
        var scheme = parts[0];
        var credentials = parts[1];

        if (/^Bearer$/i.test(scheme)) {
          token = credentials;
        } else {
          return next(new UnauthorizedError('credentials_bad_scheme', { message: 'Format is Authorization: Bearer [token]' }));
        }
      } else {
        return next(new UnauthorizedError('credentials_bad_format', { message: 'Format is Authorization: Bearer [token]' }));
      }
    }

    if (!token) {
      if (credentialsRequired) {
        return next(new UnauthorizedError('credentials_required', { message: 'No authorization token was found' }));
      } else {
        return next();
      }
    }

    var dtoken = jwt.decode(token, { complete: true }) || {};

    async.parallel([
      function(callback){
        var arity = secretCallback.length;
        if (arity == 4) {
          secretCallback(req, dtoken.header, dtoken.payload, callback);
        } else { // arity == 3
          secretCallback(req, dtoken.payload, callback);
        }
      },
      function(callback){
        isRevokedCallback(req, dtoken.payload, callback);
      }
    ], function(err, results){
      if (err) { return next(new UnauthorizedError(err.message, {message: err.message})); }
      var revoked = results[1];
      if (revoked){
        return next(new UnauthorizedError('revoked_token', { message: 'The token has been revoked.'}));
      }

      var secret = results[0];

      jwt.verify(token, secret, options, function(err, decoded) {
        if (err && credentialsRequired) return next(new UnauthorizedError('invalid_token', err));

        req[_requestProperty] = decoded;
        next();
      });
    });
  };

  middleware.unless = unless;

  return middleware;
};
<|endoftext|>