<commit_before>/* === Расширения для NODE === */

Node.prototype.addClass = function (cls) {
	var c = this.className ? this.className.split(' ') : [];
	for (var i=0; i<c.length; i++) {
		if (c[i] == cls) return;
	}
	c.push(cls);
	this.className = c.join(' ');
};

Node.prototype.removeClass = function (cls) {
	var c = this.className.split(' ');
	for (var i=0; i<c.length; i++) {
		if (c[i] == cls) c.splice(i--, 1);
	}
	this.className = c.join(' ');
};

Node.prototype.hasClass = function(cls) {
	for (var c = this.className.split(' '),i=c.length-1; i>=0; i--) {
		if (c[i] == cls) return true;
	}
	return false;
}

Node.prototype.addChild = function (attr) {
		if(attr instanceof Array){//В качестве аттр может быть массив, что позволяет не дублировать вызов из кода
			for(var a in attr){
				var e = this.addChild(attr[a]);
				e.setAttribute('data-child-index' , a);
			}
			return this;
		}
		var exclude = {'content':-1}//список аттрибутов-исключений
		var a = document.createElement(attr.TagName ? attr.TagName : 'div');
		for(var key in attr){if(attr.hasOwnProperty(key)&&!exclude[key])a[key]=attr[key];}  //a.setAttribute(key , attr [key]);
		if(attr['content'])a.innerHTML = attr['content'];
		return this.appendChild(a);
	}

	Node.prototype.appEnd = function (string, returnChild) {
		var a = document.createElement('div');
		a.innerHTML = string;
		if(a.childNodes.length[1]){ return this.appendChild(a.childNodes[0]); }
		for(var i=0; i<a.childNodes.length; i++ ){  this.appendChild(a.childNodes[i]);}
		return returnChild ? a.childNodes : this;
	}

	Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}

NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

if(!document.getElementsByClass){
Node.prototype.getElementsByClass = function(classList) {
		var node = this,
		list = node.getElementsByTagName('*'),
		length = list.length,
		classArray = classList.split(/\s+/),
		classes = classArray.length,
		result = [], i,j
		for(i = 0; i < length; i++) {
			for(j = 0; j < classes; j++)  {
				if(list[i].className.search('\\b' + classArray[j] + '\\b') != -1) {
					result.push(list[i])
					break
				}
			}
		}
		return result;
}
}

Node.prototype.searchUp = function(attrName,_t,attr, max_level){
	if(!attr){attr = 'id';} //if(!max_level){max_level=false}
	var result = false;
	if(_t&&this[attr]==attrName){result = this;}else if(this.offsetParent){result = this.offsetParent.searchUp(attrName,true,attr);}
	return result;
}

Node.prototype.width = function(s){if(typeof s == "undefined"){return this.offsetWidth;} this.style.width=s+"px"; return this;}
Node.prototype.height = function(s){if(typeof s == "undefined"){return this.offsetHeight;} this.style.height=s+"px"; return this;}
Node.prototype.FullWH = function(a,s,margin){//Полный размер, включая padding, border [margin]. Можно как получить, так и задать
var style = window.getComputedStyle(this, null),
p = 0, l = (a == 'height') ? ['top, bottom'] : ['left, right'];
for(var i; i<2; i++){
	p += parseInt('border-' + l[i] + '-width');
	p += parseInt('padding-' +  l[i]);
	if(margin)p += parseInt('margin-' + l[i] );
}
if(typeof s == "number" ){ this.style[a]=(s-p)+"px"; return this;}return this['offset'+$_SYS.fn.toTitleCase(a)]+p;
}
//сокращенные записи. Возможна передача в виде el.FullWidth() - вернет FullWH('width');  el.FullWidth(1) - выполнит FullWH('width', 1), вернет this;  el.FullWidth(1,true) - выполнит FullWH('width', 1, true), вернет this; el.FullWidth(true) - вернет FullWH('width',false,true);
Node.prototype.FullWidth = Node.prototype.outerWidth = function(s,margin){ if(arguments.length==1 && typeof arguments[0] == 'boolean'){var s = false, margin = arguments[0]}return this.FullWH('width',s,margin);}
Node.prototype.FullHeight = Node.prototype.outerHeight = function(s,margin){ if(arguments.length==1 && typeof arguments[0] == 'boolean'){var s = false, margin = arguments[0]} return this.FullWH('height',s,margin);}
Node.prototype._X = function(s){ if(typeof s == "undefined"){if(!this._x){this._x=this.offsetLeft;} return this._x;} this.style.left=s+"px"; this._x=s; return this; }
Node.prototype._Y = function(s){ if(typeof s == "undefined"){if(!this._y){this._y=this.offsetTop;} return this._y;} this.style.top=s+"px"; this._y=s; return this; }
//x,y,width, height отн-но центра объета
Node.prototype.WidthC = function(s){if(typeof s == "undefined"){return parseInt(this.offsetWidth/2);} var  delta =  (this.WidthC() - s); this.style.width=2*s+"px"; this._X(this._X()+delta); return this;}
Node.prototype.HeightC = function(s){if(typeof s == "undefined"){return parseInt(this.offsetHeight/2);} var delta = (this.HeightC() - s) ; this.style.height=2*s+"px"; this._Y(this._Y()+delta); return this;}
Node.prototype.XC = function(s){ if(typeof s == "undefined"){return this._X()+this.WidthC();} this._X(s-this.WidthC()); return this; }
Node.prototype.YC = function(s){ if(typeof s == "undefined"){return this._Y()+this.HeightC();} this._Y(s-this.HeightC());  return this; }
Node.prototype.ZC = function(s) {if(typeof s == "undefined"){return this.style.zIndex;} this.style.zIndex = s;  return this;}

Node.prototype.getElementBy=function(id, attr){//Ищит дочерние элементы с id.
		var attr = attr ? attr : 'id'
		var node = this,
		list = node.getElementsByTagName('*'),
		length = list.length,
		classArray = classList.split(/\s+/),
		classes = classArray.length,
		result = [], i,j
		for(i = 0; i < length; i++) {
				if(list[i][attr] == id || list[i].getAttribute(attr) == id) {
					result.push(list[i]);
				}
		}
		return  result;
 }

Node.prototype.background = function(o){
	//{color,img,position,repeat, attachment, size}
	//style.background = "#f3f3f3 url('img_tree.png') no-repeat right top";
	if(o.color){this.style.backgroundColor = o.color}
	if(o.url){this.style.backgroundImage = "url('"+o.url+"')";}
	if(o.position){var suf =o.position.suf ?  o.position.suf : "px"; this.style.backgroundPosition = o.position.x+suf+" "+o.position.y+suf; }
	if(o.repeat){this.style.backgroundRepeat = o.repeat;}
	if(o.attachment){this.style.backgroundAttachment = o.attachment;}
	if(o.size){var suf = o.suf ? o.suf : "px"; this.style.backgroundSize = (typeof o.size=='object' ? (o.size.x+suf+" "+o.size.y+suf): o.size);}
}

Node.prototype.rotate=function(r){this.style.transform = "rotate(7deg)"; }
Node.prototype.scale=function(s){this.style.transform = "scale("+s+","+s+")"; }
Node.prototype.mirror=function(s,n){this.style.transform = "scale"+s.toLocaleUpperCase()+"("+n+")"; }
Node.prototype.show=function(){this.style.display = "block"; }
Node.prototype.hidden=function(){this.style.display = "none"; }

Node.prototype.position = function(a){
	var a = a ? a : {};
	if(!a.position) a.position = "absolute";
	var n =  ['left', 'right','top','bottom'];
	for(var i in n){
		if(a[n[i]]===false)continue;
		a[n[i]] = a[n[i]] ? (typeof a[n[i]]== "number" ? a[n[i]]+'px' : a[n[i]]):0;
	}
	for(var d in a){this.style[d] =  a[d];}
	return this;
}

Node.prototype.topBlock = function(a){
	var a = a ? a : {};
	if(!a.zIndex) a.zIndex = 9999;
	return this.position(a)
}
<commit_msg>добавленны функции проверки элемента на соответствие заданному параметру, поиск родительских элементов, обновлен поиск дочерних элементов (последний - еще не испытывал)<commit_after>/* === Расширения для NODE === */

Node.prototype.addClass = function (cls) {
	var c = this.className ? this.className.split(' ') : [];
	for (var i=0; i<c.length; i++) {
		if (c[i] == cls) return;
	}
	c.push(cls);
	this.className = c.join(' ');
};

Node.prototype.removeClass = function (cls) {
	var c = this.className.split(' ');
	for (var i=0; i<c.length; i++) {
		if (c[i] == cls) c.splice(i--, 1);
	}
	this.className = c.join(' ');
};

Node.prototype.hasClass = function(cls) {
	if(!this.className || this.className=='')return false;
	for (var c = this.className.split(' '),i=c.length-1; i>=0; i--) {
		if (c[i] == cls) return true;
	}
	return false;
}

Node.prototype.addChild = function (attr) {
		if(attr instanceof Array){//В качестве аттр может быть массив, что позволяет не дублировать вызов из кода
			for(var a in attr){
				var e = this.addChild(attr[a]);
				e.setAttribute('data-child-index' , a);
			}
			return this;
		}
		var exclude = {'content':-1}//список аттрибутов-исключений
		var a = document.createElement(attr.TagName ? attr.TagName : 'div');
		for(var key in attr){if(attr.hasOwnProperty(key)&&!exclude[key])a[key]=attr[key];}  //a.setAttribute(key , attr [key]);
		if(attr['content'])a.innerHTML = attr['content'];
		return this.appendChild(a);
	}

	Node.prototype.appEnd = function (string, returnChild) {
		var a = document.createElement('div');
		a.innerHTML = string;
		if(a.childNodes.length[1]){ return this.appendChild(a.childNodes[0]); }
		for(var i=0; i<a.childNodes.length; i++ ){  this.appendChild(a.childNodes[i]);}
		return returnChild ? a.childNodes : this;
	}

	Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}

NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

if(!document.getElementsByClass){
Node.prototype.getElementsByClass = function(classList) {
		var node = this,
		list = node.getElementsByTagName('*'),
		length = list.length,
		classArray = classList.split(/\s+/),
		classes = classArray.length,
		result = [], i,j
		for(i = 0; i < length; i++) {
			for(j = 0; j < classes; j++)  {
				if(list[i].className.search('\\b' + classArray[j] + '\\b') != -1) {
					result.push(list[i])
					break
				}
			}
		}
		return result;
}
}

 /*Проверяет принадлежность элемента к какому-либо параметру Node.getParents([by(string), [value(string), [light(boolean)]]])
 by - индификатор (id, klassName ... ). М.б. использована функция. Если передан без value будет искать по наличию индификатора
value - значение. для 'hasClass' значение подставляетсяя, для ос. сравнивается
light - "встречается" ( ищит по indexOf а не по == ; не распространяется на typeof by == function )
*/
 Node.prototype.isIt = function(by, value, light){var isset = $_SYS.fn.isset; return ( !isset(by)  || (!isset(value)&&this[by]) || ((typeof this[by] == 'function') ? (by == 'hasClass' ? this[by](value) : this[by]()) : (light ? this[by].indexOf(value)>-1 : this[by]== value))  ); }

/*
Node.getParents([by(string), value(string), [light(boolean)]],[include_this(boolean) = true]) - поиск родительских элементов (начиная с текущего).
by, value,light аналогичен isIt()
include_this - включать или нет в поиск текущий элемент (по умолчанию - включен, т.к. наиболее частое применение - поиск, был ли клик по элементу). При передаче в функцию одного параметра 'boolean' считается за include_this (если тип string - будет искать по наличию свойства)
*/
Node.prototype.getParents = function(by,value, light, include_this){
	if(arguments.length<3)var include_this = true;
	if(arguments.length==1&&typeof arguments[0] != 'string')var include_this = arguments[0];
	var result =  [];
	var e = this;

	if(include_this && e.isIt(by,value, light) )result.push(e);
	while(e.parentNode){
		e = e.parentNode;
		if(e.isIt(by,value, light))result.push(e);
	}
	return result;
}

//Поиск элемента по параметру . Аналогично getParents, но include_this по умолчанию false
Node.prototype.getElementBy=function(by,value, light, include_this){//Ищит дочерние элементы с id.
		//var //value = value ? value : 'id';
		if(arguments.length==1&&typeof arguments[0] != 'string')var include_this = arguments[0];
		var list = this.getElementsByTagName('*'),
		result = [], i;
		if(include_this && this.isIt(by,value, light))result.push(this);
		for(i = 0; i < list.length; i++) {
				if(list[i].isIt(by,value, light))result.push(list[i]);
		}
		return  result;
 }

Node.prototype.width = function(s){if(typeof s == "undefined"){return this.offsetWidth;} this.style.width=s+"px"; return this;}
Node.prototype.height = function(s){if(typeof s == "undefined"){return this.offsetHeight;} this.style.height=s+"px"; return this;}
Node.prototype.FullWH = function(a,s,margin){//Полный размер, включая padding, border [margin]. Можно как получить, так и задать
var style = window.getComputedStyle(this, null),
p = 0, l = (a == 'height') ? ['top, bottom'] : ['left, right'];
for(var i; i<2; i++){
	p += parseInt('border-' + l[i] + '-width');
	p += parseInt('padding-' +  l[i]);
	if(margin)p += parseInt('margin-' + l[i] );
}
if(typeof s == "number" ){ this.style[a]=(s-p)+"px"; return this;}return this['offset'+$_SYS.fn.toTitleCase(a)]+p;
}
//сокращенные записи. Возможна передача в виде el.FullWidth() - вернет FullWH('width');  el.FullWidth(1) - выполнит FullWH('width', 1), вернет this;  el.FullWidth(1,true) - выполнит FullWH('width', 1, true), вернет this; el.FullWidth(true) - вернет FullWH('width',false,true);
Node.prototype.FullWidth = Node.prototype.outerWidth = function(s,margin){ if(arguments.length==1 && typeof arguments[0] == 'boolean'){var s = false, margin = arguments[0]}return this.FullWH('width',s,margin);}
Node.prototype.FullHeight = Node.prototype.outerHeight = function(s,margin){ if(arguments.length==1 && typeof arguments[0] == 'boolean'){var s = false, margin = arguments[0]} return this.FullWH('height',s,margin);}
Node.prototype._X = function(s){ if(typeof s == "undefined"){if(!this._x){this._x=this.offsetLeft;} return this._x;} this.style.left=s+"px"; this._x=s; return this; }
Node.prototype._Y = function(s){ if(typeof s == "undefined"){if(!this._y){this._y=this.offsetTop;} return this._y;} this.style.top=s+"px"; this._y=s; return this; }
//x,y,width, height отн-но центра объета
Node.prototype.WidthC = function(s){if(typeof s == "undefined"){return parseInt(this.offsetWidth/2);} var  delta =  (this.WidthC() - s); this.style.width=2*s+"px"; this._X(this._X()+delta); return this;}
Node.prototype.HeightC = function(s){if(typeof s == "undefined"){return parseInt(this.offsetHeight/2);} var delta = (this.HeightC() - s) ; this.style.height=2*s+"px"; this._Y(this._Y()+delta); return this;}
Node.prototype.XC = function(s){ if(typeof s == "undefined"){return this._X()+this.WidthC();} this._X(s-this.WidthC()); return this; }
Node.prototype.YC = function(s){ if(typeof s == "undefined"){return this._Y()+this.HeightC();} this._Y(s-this.HeightC());  return this; }
Node.prototype.ZC = function(s) {if(typeof s == "undefined"){return this.style.zIndex;} this.style.zIndex = s;  return this;}

Node.prototype.background = function(o){
	//{color,img,position,repeat, attachment, size}
	//style.background = "#f3f3f3 url('img_tree.png') no-repeat right top";
	if(o.color){this.style.backgroundColor = o.color}
	if(o.url){this.style.backgroundImage = "url('"+o.url+"')";}
	if(o.position){var suf =o.position.suf ?  o.position.suf : "px"; this.style.backgroundPosition = o.position.x+suf+" "+o.position.y+suf; }
	if(o.repeat){this.style.backgroundRepeat = o.repeat;}
	if(o.attachment){this.style.backgroundAttachment = o.attachment;}
	if(o.size){var suf = o.suf ? o.suf : "px"; this.style.backgroundSize = (typeof o.size=='object' ? (o.size.x+suf+" "+o.size.y+suf): o.size);}
}

Node.prototype.rotate=function(r){this.style.transform = "rotate(7deg)"; }
Node.prototype.scale=function(s){this.style.transform = "scale("+s+","+s+")"; }
Node.prototype.mirror=function(s,n){this.style.transform = "scale"+s.toLocaleUpperCase()+"("+n+")"; }
Node.prototype.show=function(){this.style.display = "block"; }
Node.prototype.hidden=function(){this.style.display = "none"; }

Node.prototype.position = function(a){
	var a = a ? a : {};
	if(!a.position) a.position = "absolute";
	var n =  ['left', 'right','top','bottom'];
	for(var i in n){
		if(a[n[i]]===false)continue;
		a[n[i]] = a[n[i]] ? (typeof a[n[i]]== "number" ? a[n[i]]+'px' : a[n[i]]):0;
	}
	for(var d in a){this.style[d] =  a[d];}
	return this;
}

Node.prototype.topBlock = function(a){
	var a = a ? a : {};
	if(!a.zIndex) a.zIndex = 9999;
	return this.position(a)
}
<|endoftext|>


<commit_before>#! /usr/bin/env node
/*eslint no-console: "off"*/
var program = require('starting');
var path = require('path');
var config = require('../lib/config');
var useRules = require('./use');
var showStatus = require('./status');
var util = require('./util');
var plugin = require('./plugin');

var showUsage = util.showUsage;
var error = util.error;
var warn = util.warn;
var info = util.info;

function showStartupInfo(err, options, debugMode, restart) {
  if (!err || err === true) {
    return showUsage(err, options, restart);
  }
  if (/listen EADDRINUSE/.test(err)) {
    error('[!] Failed to bind proxy port ' + (options.port || config.port) + ': The port is already in use');
    info('[i] Please check if ' + config.name + ' is already running, you can ' + (debugMode ? 'stop whistle with `w2 stop` first' : 'restart whistle with `w2 restart`'));
    info('    or if another application is using the port, you can change the port with ' + (debugMode ? '`w2 run -p newPort`\n' : '`w2 start -p newPort`\n'));
  } else if (err.code == 'EACCES' || err.code == 'EPERM') {
    error('[!] Cannot start ' + config.name + ' owned by root');
    info('[i] Try to run command with `sudo`\n');
  }

  error(err.stack ? 'Date: ' + new Date().toLocaleString() + '\n' + err.stack : err);
}

program.setConfig({
  main: function(options) {
    var hash = options && options.storage && encodeURIComponent(options.storage);
    return path.join(__dirname, '../index.js') + (hash ? '#' + hash + '#' : '');
  },
  name: config.name,
  version: config.version,
  runCallback: function(err, options) {
    if (err) {
      showStartupInfo(err, options, true);
      return;
    }
    showUsage(false, options);
    console.log('Press [Ctrl+C] to stop ' + config.name + '...');
  },
  startCallback: showStartupInfo,
  restartCallback: function(err, options) {
    showStartupInfo(err, options, false, true);
  },
  stopCallback: function(err) {
    if (err === true) {
      info('[i] ' + config.name + ' killed.');
    } else if (err) {
      if (err.code === 'EPERM') {
        util.showKillError();
      } else {
        error('[!] ' + err.message);
      }
    } else {
      warn('[!] No running ' + config.name);
    }
  }
});

program
  .command('status')
  .description('Show the running status of whistle');
program.command('install')
  .description('Install a whistle plugin');
program.command('uninstall')
  .description('Uninstall a whistle plugin');
program
  .command('add [filepath]')
  .description('Add rules from local js file (.whistle.js by default)');

program
  .option('-D, --baseDir [baseDir]', 'set the configured storage root path', String, undefined)
  .option('-z, --certDir [directory]', 'set custom certificate store directory', String, undefined)
  .option('-l, --localUIHost [hostname]', 'set the domain for the web ui of whistle (' + config.localUIHost + ' by default)', String, undefined)
  .option('-L, --pluginHost [hostname]', 'set the domain for the web ui of plugin  (as: "script=a.b.com&vase=x.y.com")', String, undefined)
  .option('-n, --username [username]', 'set the username to access the web ui of whistle', String, undefined)
  .option('-w, --password [password]', 'set the password to access the web ui of whistle', String, undefined)
  .option('-N, --guestName [username]', 'set the the guest name to access the web ui of whistle (can only view the data)', String, undefined)
  .option('-W, --guestPassword [password]', 'set the guest password to access the web ui of whistle (can only view the data)', String, undefined)
  .option('-s, --sockets [number]', 'set the max number of cached long connection on each domain (' + config.sockets + ' by default)', parseInt, undefined)
  .option('-S, --storage [newStorageDir]', 'set the configured storage directory', String, undefined)
  .option('-C, --copy [storageDir]', 'copy the configuration of the specified directory to a new directory', String, undefined)
  .option('-c, --dnsCache [time]', 'set the cache time of DNS (30000ms by default)', String, undefined)
  .option('-H, --host [boundHost]', 'set the bound host of whistle (INADDR_ANY by default)', String, undefined)
  .option('-p, --port [proxyPort]', 'set the proxy port of whistle (' + config.port + ' by default)', parseInt, undefined)
  .option('-P, --uiport [uiport]', 'set the listening port of whistle webui', parseInt, undefined)
  .option('-m, --middlewares [script path or module name]', 'set the express middlewares loaded at startup (as: xx,yy/zz.js)', String, undefined)
  .option('-M, --mode [mode]', 'set the way of starting the whistle mode (as: pureProxy|debug|multiEnv)', String, undefined)
  .option('-t, --timeout [ms]', 'set the request timeout (' + config.timeout + 'ms by default)', parseInt, undefined)
  .option('-e, --extra [extraData]', 'set the extra parameters for plugin', String, undefined)
  .option('-f, --secureFilter [secureFilter]', 'set the path of secure filter', String, undefined)
  .option('-R, --reqCacheSize [reqCacheSize]', 'set the cache size of request data (600 by default)', String, undefined)
  .option('-F, --frameCacheSize [frameCacheSize]', 'set the cache size of webSocket and socket\'s frames (512 by default)', String, undefined)
  .option('-A, --addon [pluginPaths]', 'add custom plugin paths', String, undefined)
  .option('--socksPort [socksPort]', 'set the socksv5 server port of whistle', parseInt, undefined)
  .option('--httpPort [httpPort]', 'set the http server port of whistle', parseInt, undefined)
  .option('--httpsPort [httpsPort]', 'set the https server port of whistle', parseInt, undefined)
  .option('--no-global-plugins', 'do not load any globally installed plugins')
  .option('--no-prev-options', 'do not reuse the previous options when restarting');

var argv = process.argv;
var cmd = argv[2];
var storage;
var removeItem = function(list, name) {
  var i = list.indexOf(name);
  i !== -1 && list.splice(i, 1);
};
if (cmd === 'status') {
  var all = argv[3] === '--all';
  if (argv[3] === '-S') {
    storage = argv[4];
  }
  showStatus(all, storage);
} else if (cmd === 'uninstall' || cmd === 'uni') {
  cmd = (RegExp.$1 || '') + 'npm';
  plugin.uninstall(Array.prototype.slice.call(argv, 3));
} else if (/^([a-z]{1,2})?i(nstall)?$/.test(cmd)) {
  cmd = (RegExp.$1 || '') + 'npm';
  argv = Array.prototype.slice.call(argv, 3);
  argv.unshift('install');
  removeItem(argv, '-g');
  removeItem(argv, '--global');
  plugin.install(cmd, argv);
} else if (cmd === 'use' || cmd === 'enable' || cmd === 'add') {
  var index = argv.indexOf('--force');
  var force = index !== -1;
  if (force) {
    argv.splice(index, 1);
  }
  var filepath = argv[3];
  if (filepath === '-S') {
    filepath = null;
    storage = argv[4];
  } else if (argv[4] === '-S') {
    storage = argv[5];
  }
  if (filepath && /^-/.test(filepath)) {
    filepath = null;
  }
  useRules(filepath, storage, force);
} else if (cmd === 'run' && argv[3] && /^[^-]/.test(argv[3])) {
  cmd = argv[3];
  argv = Array.prototype.slice.call(argv, 4);
  plugin.run(cmd, argv);
} else {
  program.parse(argv);
}
<commit_msg>feat: w2 run <=> w2 exec<commit_after>#! /usr/bin/env node
/*eslint no-console: "off"*/
var program = require('starting');
var path = require('path');
var config = require('../lib/config');
var useRules = require('./use');
var showStatus = require('./status');
var util = require('./util');
var plugin = require('./plugin');

var showUsage = util.showUsage;
var error = util.error;
var warn = util.warn;
var info = util.info;

function showStartupInfo(err, options, debugMode, restart) {
  if (!err || err === true) {
    return showUsage(err, options, restart);
  }
  if (/listen EADDRINUSE/.test(err)) {
    error('[!] Failed to bind proxy port ' + (options.port || config.port) + ': The port is already in use');
    info('[i] Please check if ' + config.name + ' is already running, you can ' + (debugMode ? 'stop whistle with `w2 stop` first' : 'restart whistle with `w2 restart`'));
    info('    or if another application is using the port, you can change the port with ' + (debugMode ? '`w2 run -p newPort`\n' : '`w2 start -p newPort`\n'));
  } else if (err.code == 'EACCES' || err.code == 'EPERM') {
    error('[!] Cannot start ' + config.name + ' owned by root');
    info('[i] Try to run command with `sudo`\n');
  }

  error(err.stack ? 'Date: ' + new Date().toLocaleString() + '\n' + err.stack : err);
}

program.setConfig({
  main: function(options) {
    var hash = options && options.storage && encodeURIComponent(options.storage);
    return path.join(__dirname, '../index.js') + (hash ? '#' + hash + '#' : '');
  },
  name: config.name,
  version: config.version,
  runCallback: function(err, options) {
    if (err) {
      showStartupInfo(err, options, true);
      return;
    }
    showUsage(false, options);
    console.log('Press [Ctrl+C] to stop ' + config.name + '...');
  },
  startCallback: showStartupInfo,
  restartCallback: function(err, options) {
    showStartupInfo(err, options, false, true);
  },
  stopCallback: function(err) {
    if (err === true) {
      info('[i] ' + config.name + ' killed.');
    } else if (err) {
      if (err.code === 'EPERM') {
        util.showKillError();
      } else {
        error('[!] ' + err.message);
      }
    } else {
      warn('[!] No running ' + config.name);
    }
  }
});

program
  .command('status')
  .description('Show the running status of whistle');
program
  .command('add [filepath]')
  .description('Add rules from local js file (.whistle.js by default)');
program.command('install')
  .description('Install a whistle plugin');
program.command('uninstall')
  .description('Uninstall a whistle plugin');
program.command('exec')
  .description('Exec whistle plugin command');

program
  .option('-D, --baseDir [baseDir]', 'set the configured storage root path', String, undefined)
  .option('-z, --certDir [directory]', 'set custom certificate store directory', String, undefined)
  .option('-l, --localUIHost [hostname]', 'set the domain for the web ui of whistle (' + config.localUIHost + ' by default)', String, undefined)
  .option('-L, --pluginHost [hostname]', 'set the domain for the web ui of plugin  (as: "script=a.b.com&vase=x.y.com")', String, undefined)
  .option('-n, --username [username]', 'set the username to access the web ui of whistle', String, undefined)
  .option('-w, --password [password]', 'set the password to access the web ui of whistle', String, undefined)
  .option('-N, --guestName [username]', 'set the the guest name to access the web ui of whistle (can only view the data)', String, undefined)
  .option('-W, --guestPassword [password]', 'set the guest password to access the web ui of whistle (can only view the data)', String, undefined)
  .option('-s, --sockets [number]', 'set the max number of cached long connection on each domain (' + config.sockets + ' by default)', parseInt, undefined)
  .option('-S, --storage [newStorageDir]', 'set the configured storage directory', String, undefined)
  .option('-C, --copy [storageDir]', 'copy the configuration of the specified directory to a new directory', String, undefined)
  .option('-c, --dnsCache [time]', 'set the cache time of DNS (30000ms by default)', String, undefined)
  .option('-H, --host [boundHost]', 'set the bound host of whistle (INADDR_ANY by default)', String, undefined)
  .option('-p, --port [proxyPort]', 'set the proxy port of whistle (' + config.port + ' by default)', parseInt, undefined)
  .option('-P, --uiport [uiport]', 'set the listening port of whistle webui', parseInt, undefined)
  .option('-m, --middlewares [script path or module name]', 'set the express middlewares loaded at startup (as: xx,yy/zz.js)', String, undefined)
  .option('-M, --mode [mode]', 'set the way of starting the whistle mode (as: pureProxy|debug|multiEnv)', String, undefined)
  .option('-t, --timeout [ms]', 'set the request timeout (' + config.timeout + 'ms by default)', parseInt, undefined)
  .option('-e, --extra [extraData]', 'set the extra parameters for plugin', String, undefined)
  .option('-f, --secureFilter [secureFilter]', 'set the path of secure filter', String, undefined)
  .option('-R, --reqCacheSize [reqCacheSize]', 'set the cache size of request data (600 by default)', String, undefined)
  .option('-F, --frameCacheSize [frameCacheSize]', 'set the cache size of webSocket and socket\'s frames (512 by default)', String, undefined)
  .option('-A, --addon [pluginPaths]', 'add custom plugin paths', String, undefined)
  .option('--socksPort [socksPort]', 'set the socksv5 server port of whistle', parseInt, undefined)
  .option('--httpPort [httpPort]', 'set the http server port of whistle', parseInt, undefined)
  .option('--httpsPort [httpsPort]', 'set the https server port of whistle', parseInt, undefined)
  .option('--no-global-plugins', 'do not load any globally installed plugins')
  .option('--no-prev-options', 'do not reuse the previous options when restarting');

var argv = process.argv;
var cmd = argv[2];
var storage;
var removeItem = function(list, name) {
  var i = list.indexOf(name);
  i !== -1 && list.splice(i, 1);
};
if (cmd === 'status') {
  var all = argv[3] === '--all';
  if (argv[3] === '-S') {
    storage = argv[4];
  }
  showStatus(all, storage);
} else if (cmd === 'uninstall' || cmd === 'uni') {
  cmd = (RegExp.$1 || '') + 'npm';
  plugin.uninstall(Array.prototype.slice.call(argv, 3));
} else if (/^([a-z]{1,2})?i(nstall)?$/.test(cmd)) {
  cmd = (RegExp.$1 || '') + 'npm';
  argv = Array.prototype.slice.call(argv, 3);
  argv.unshift('install');
  removeItem(argv, '-g');
  removeItem(argv, '--global');
  plugin.install(cmd, argv);
} else if (cmd === 'use' || cmd === 'enable' || cmd === 'add') {
  var index = argv.indexOf('--force');
  var force = index !== -1;
  if (force) {
    argv.splice(index, 1);
  }
  var filepath = argv[3];
  if (filepath === '-S') {
    filepath = null;
    storage = argv[4];
  } else if (argv[4] === '-S') {
    storage = argv[5];
  }
  if (filepath && /^-/.test(filepath)) {
    filepath = null;
  }
  useRules(filepath, storage, force);
} else if ((cmd === 'run' || cmd === 'exec') && argv[3] && /^[^-]/.test(argv[3])) {
  cmd = argv[3];
  argv = Array.prototype.slice.call(argv, 4);
  plugin.run(cmd, argv);
} else {
  program.parse(argv);
}
<|endoftext|>


<commit_before>function route(pathname) {
  console.log("About to route a request for " + pathname);
}
exports.route = route;

<commit_msg>commit without password<commit_after>function route(pathname) {
  console.log("About to route a request for " + pathname);
}
exports.route = route;
//Test comment

<|endoftext|>


<commit_before>module.exports = {
    handlers: {},

    register: function (op, handler) {
        this.handlers[op] = handler;
    },

    route: function (server, connection, data) {
        try {
            data = JSON.parse(data);
        } catch (e) {
            ui.writeLog('Connection ' + connection.id + ' sent bad data! Closing connection.');
            connection.disconnect();
            return;
        }

        if (typeof data.op == 'undefined') {
            return;
        }

        if (typeof this.handlers[data.op] != 'undefined') {
            var handlerFn = this.handlers[data.op];
            handlerFn(connection, data);
        }
    }
};

var normalizedPath = require("path").join(__dirname, "handlers");

require("fs").readdirSync(normalizedPath).forEach(function(file) {
    require("./handlers/" + file);
});<commit_msg>Router: only allow LOGIN opcode on an unauthenticated client.<commit_after>module.exports = {
    handlers: {},

    register: function (op, handler) {
        this.handlers[op] = handler;
    },

    route: function (server, connection, data) {
        try {
            data = JSON.parse(data);
        } catch (e) {
            ui.writeLog('Connection ' + connection.id + ' sent bad data! Closing connection.');
            connection.disconnect();
            return;
        }

        if (typeof data.op == 'undefined') {
            return;
        }

        if (data.op != opcodes.LOGIN && !connection.authenticated) {
            ui.writeLog('Refusing to process opcode ' + data.op + ' without an authenticated connection.');
            return;
        }

        if (typeof this.handlers[data.op] != 'undefined') {
            var handlerFn = this.handlers[data.op];
            handlerFn(connection, data);
        }
    }
};

var normalizedPath = require("path").join(__dirname, "handlers");

require("fs").readdirSync(normalizedPath).forEach(function(file) {
    require("./handlers/" + file);
});<|endoftext|>


<commit_before>var config = require('./config'),
    ops = require('./facets/ops'),
    fmt = require('util').format,
    validatePackageName = require('validate-npm-package-name'),
    Hoek = require("hoek")

var enterpriseConfig = {
  plugins: {
    blankie: {
      scriptSrc: config.enterpriseCspScriptSrc
    }
  }
}

var unathenticatedRouteConfig = {
  config: {
    auth: {
      mode: 'try'
    },
    plugins: {
      'hapi-auth-cookie': {
        redirectTo: false
      }
    }
  }
};

var stripeSafeConfig = {
  plugins: {
    blankie: {
      scriptSrc: ['self', 'unsafe-eval', 'https://www.google-analytics.com', 'https://checkout.stripe.com', 'https://js.hs-analytics.net/analytics/'],
      frameSrc: 'https://checkout.stripe.com'
    }
  }
}

// CAUTION: THESE ROUTES DO NOT REQUIRE AUTHENTICATION.
// DO NOT PUT SENSITIVE ROUTES IN THIS ARRAY.
var unauthenticatedRoutes = [
  {
    path: '/favicon.ico',
    method: 'GET',
    handler: {
      file: './static/misc/favicon.ico'
    }
  },{
    path: '/robots.txt',
    method: 'GET',
    handler: {
      file: './static/misc/robots.txt'
    }
  },{
    path: '/google17836d108133913c.html',
    method: 'GET',
    handler: function (request, reply) {
      reply("google-site-verification: google17836d108133913c.html");
    }
  },{
    path: '/install.sh',
    method: 'GET',
    handler: {
      file: './static/misc/install.sh'
    }
  },{
    path: '/opensearch.xml',
    method: 'GET',
    handler: {
      file: './static/misc/opensearch.xml'
    }
  },{
    path: '/static/{path*}',
    method: 'GET',
    handler: {
      directory: {
        path: './static',
        listing: true,
        index: true
      }
    }
  },{
    path: "/",
    method: "GET",
    handler: require('./facets/company/show-homepage')
  },{
    path: "/private-npm",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/private-modules").code(301);
    }
  },{
    path: "/contact",
    method: "GET",
    handler: require('./facets/company/show-contact')
  },{
    path: "/send-contact",
    method: "POST",
    handler: require('./facets/company/show-send-contact')(config.user.mail)
  },{
    path: "/support",
    method: "GET",
    handler: require('./facets/company/show-contact')
  },{
    path: "/policies/{policy?}",
    method: "GET",
    handler: require('./facets/company/show-policy')
  },{
    path: "/whoshiring",
    method: "GET",
    handler: require('./facets/company/show-whoshiring')
  },{
    path: "/joinwhoshiring",
    method: "GET",
    handler: require('./facets/company/show-whoshiring-payments')(config.stripe),
    config: stripeSafeConfig
  },{
    path: "/joinwhoshiring",
    method: "POST",
    handler: require('./facets/company/show-whoshiring-payments')(config.stripe),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/enterprise",
    method: "GET",
    handler: require('./facets/enterprise/show-index'),
    config: enterpriseConfig
  },{
    path: "/enterprise-start-signup",
    method: "POST",
    handler: require('./facets/enterprise/show-ula'),
    config: enterpriseConfig
  },{
    path: "/enterprise-contact-me",
    method: "POST",
    handler: require('./facets/enterprise/show-contact-me'),
    config: enterpriseConfig
  },{
    path: "/enterprise-trial-signup",
    method: "POST",
    handler: require('./facets/enterprise/show-trial-signup'),
    config: enterpriseConfig
  },{
    path: "/enterprise-verify",
    method: "GET",
    handler: require('./facets/enterprise/show-verification'),
    config: enterpriseConfig
  },{
    path: "/enterprise/license",
    method: ["GET","POST"],
    handler: require('./facets/enterprise/find-license'),
    config: stripeSafeConfig
  },{
    path: "/enterprise/license-options",
    method: "GET",
    handler: require('./facets/enterprise/license-options')(config.stripe),
    config: stripeSafeConfig
  },{
    path: "/enterprise/buy-license",
    method: "POST",
    handler: require('./facets/enterprise/buy-license')(config.stripe),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/enterprise/license-paid",
    method: "GET",
    handler: require('./facets/enterprise/license-paid'),
    config: enterpriseConfig
  },{
    path: "/enterprise/license-error",
    method: "GET",
    handler: require('./facets/enterprise/license-error'),
    config: enterpriseConfig
  },{
    path: "/package/{package}/{version?}",
    method: "GET",
    handler: require('./facets/registry/show-package')
  },{
    path: "/packages/{package}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/package/" + request.params.package).code(301);
    }
  },{
    // Redirect to home, because who cares
    path: "/browse/all",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/").code(301);
    }
  },{
    // Redirect to /~user#packages
    path: "/browse/author/{user}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect(fmt("/~%s#packages", request.params.user)).code(301);
    }
  },{
    // Users, ordered descending by how many packages they've starred
    path: "/browse/userstar",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/").code(301);
    }
  },{
    // Redirect to /~user#starred
    path: "/browse/userstar/{user}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect(fmt("/~%s#starred", request.params.user)).code(301);
    }
  },{
    // Catch-all for all other browse pages
    // - top keywords
    // - packages that have a certain keywords
    // - recently updated packages
    // - prolific authors
    // - most depended-upon packages
    // - all the packages that depend on the given package
    path: "/browse/{p*}",
    method: "GET",
    handler: require('./facets/registry/show-browse')
  },{
    path: "/keyword/{kw}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect('/browse/keyword/' + request.params.kw).code(301);
    }
  },{
    path: "/recent-authors/{since?}",
    method: "GET",
    handler: require('./facets/registry/show-recent-authors')
  },{
    path: "/star",
    method: "POST",
    handler: require('./facets/registry/show-star'),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/search/{q?}",
    method: "GET",
    handler: require('./facets/registry/show-search')(config.search)
  },{
    path: "/~{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile/{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/~/{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/signup",
    method: "GET",
    handler: require('./facets/user/show-signup')
  },{
    path: "/signup",
    method: "HEAD",
    handler: require('./facets/user/show-signup')
  },{
    path: "/signup",
    method: "POST",
    handler: require('./facets/user/show-signup')
  },{
    path: "/login",
    method: "GET",
    handler: require('./facets/user/show-login')
  },{
    path: "/login",
    method: "POST",
    handler: require('./facets/user/show-login')
  },{
    path: "/logout",
    method: "GET",
    handler: require('./facets/user/show-logout')
  },{
    path: "/forgot/{token?}",
    method: "GET",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/forgot/{token?}",
    method: "HEAD",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/forgot/{token?}",
    method: "POST",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/_monitor/ping",
    method: "GET",
    handler: function(request, reply) {
      return reply('ok').code(200);
    }
  },{
    path: "/_monitor/status",
    method: "GET",
    handler: ops.status(require('./package.json').version)
  },{
    path: "/-/csplog",
    method: "POST",
    handler: ops.csplog,
    config: {
      plugins: {
        crumb: false
      }
    }
  },{
    method: '*',
    path: '/doc/{p*}',
    handler: function(request, reply) {
      return reply.redirect(require("url").format({
        protocol: "https",
        hostname: "docs.npmjs.com",
        pathname: request.url.path
          .replace(/^\/doc/, "")
          .replace(/\.html$/, "")
          .replace(/\/npm-/, "/")
      })).code(301)
    }
  },{
    method: '*',
    path: '/{p*}',
    handler: fallback
  }

];

var authenticatedRoutes = [
  {
    // shortcut for viewing your own stars
    path: "/star",
    method: "GET",
    handler: require('./facets/registry/show-star'),
  },{
    path: "/~",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "GET",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "PUT",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "POST",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/email-edit",
    method: "GET",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "HEAD",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "PUT",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "POST",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    // confirm or revert
    // /email-edit/confirm/1234567
    // /email-edit/revert/1234567
    path: "/email-edit/{token*2}",
    method: "GET",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit/{token*2}",
    method: "HEAD",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/password",
    method: "GET",
    handler: require('./facets/user/show-password')
  },{
    path: "/password",
    method: "HEAD",
    handler: require('./facets/user/show-password')
  },{
    path: "/password",
    method: "POST",
    handler: require('./facets/user/show-password')
  }

]

// Apply unathenticated route config to all the public routes
unauthenticatedRoutes = unauthenticatedRoutes.map(function(route){
  return Hoek.applyToDefaults(unathenticatedRouteConfig, route)
})

module.exports = unauthenticatedRoutes.concat(authenticatedRoutes)

function fallback(request, reply) {

  // 1. Try to render a static page
  // 2. Look for a package with the given name
  // 3. 404

  var route = request.params.p,
    opts = {
      user: request.auth.credentials,
    };

  request.server.methods.corp.getPage(route, function(er, content) {

    if (content) {
      opts.md = content;
      return reply.view('company/corporate', opts);
    }

    request.server.methods.registry.getPackage(route, function(err, package) {

      if (package) {
        return reply.redirect('/package/' + package._id);
      }

      // Add package to view context if path is a valid package name
      if (validatePackageName(request.params.p).valid) {
        opts.package = {name: request.params.p};
      }

      return reply.view('errors/not-found', opts).code(404);
    });
  });
}
<commit_msg>buy-license and license-options now pull in their own config<commit_after>var config = require('./config'),
    ops = require('./facets/ops'),
    fmt = require('util').format,
    validatePackageName = require('validate-npm-package-name'),
    Hoek = require("hoek")

var enterpriseConfig = {
  plugins: {
    blankie: {
      scriptSrc: config.enterpriseCspScriptSrc
    }
  }
}

var unathenticatedRouteConfig = {
  config: {
    auth: {
      mode: 'try'
    },
    plugins: {
      'hapi-auth-cookie': {
        redirectTo: false
      }
    }
  }
};

var stripeSafeConfig = {
  plugins: {
    blankie: {
      scriptSrc: ['self', 'unsafe-eval', 'https://www.google-analytics.com', 'https://checkout.stripe.com', 'https://js.hs-analytics.net/analytics/'],
      frameSrc: 'https://checkout.stripe.com'
    }
  }
}

// CAUTION: THESE ROUTES DO NOT REQUIRE AUTHENTICATION.
// DO NOT PUT SENSITIVE ROUTES IN THIS ARRAY.
var unauthenticatedRoutes = [
  {
    path: '/favicon.ico',
    method: 'GET',
    handler: {
      file: './static/misc/favicon.ico'
    }
  },{
    path: '/robots.txt',
    method: 'GET',
    handler: {
      file: './static/misc/robots.txt'
    }
  },{
    path: '/google17836d108133913c.html',
    method: 'GET',
    handler: function (request, reply) {
      reply("google-site-verification: google17836d108133913c.html");
    }
  },{
    path: '/install.sh',
    method: 'GET',
    handler: {
      file: './static/misc/install.sh'
    }
  },{
    path: '/opensearch.xml',
    method: 'GET',
    handler: {
      file: './static/misc/opensearch.xml'
    }
  },{
    path: '/static/{path*}',
    method: 'GET',
    handler: {
      directory: {
        path: './static',
        listing: true,
        index: true
      }
    }
  },{
    path: "/",
    method: "GET",
    handler: require('./facets/company/show-homepage')
  },{
    path: "/private-npm",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/private-modules").code(301);
    }
  },{
    path: "/contact",
    method: "GET",
    handler: require('./facets/company/show-contact')
  },{
    path: "/send-contact",
    method: "POST",
    handler: require('./facets/company/show-send-contact')(config.user.mail)
  },{
    path: "/support",
    method: "GET",
    handler: require('./facets/company/show-contact')
  },{
    path: "/policies/{policy?}",
    method: "GET",
    handler: require('./facets/company/show-policy')
  },{
    path: "/whoshiring",
    method: "GET",
    handler: require('./facets/company/show-whoshiring')
  },{
    path: "/joinwhoshiring",
    method: "GET",
    handler: require('./facets/company/show-whoshiring-payments')(config.stripe),
    config: stripeSafeConfig
  },{
    path: "/joinwhoshiring",
    method: "POST",
    handler: require('./facets/company/show-whoshiring-payments')(config.stripe),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/enterprise",
    method: "GET",
    handler: require('./facets/enterprise/show-index'),
    config: enterpriseConfig
  },{
    path: "/enterprise-start-signup",
    method: "POST",
    handler: require('./facets/enterprise/show-ula'),
    config: enterpriseConfig
  },{
    path: "/enterprise-contact-me",
    method: "POST",
    handler: require('./facets/enterprise/show-contact-me'),
    config: enterpriseConfig
  },{
    path: "/enterprise-trial-signup",
    method: "POST",
    handler: require('./facets/enterprise/show-trial-signup'),
    config: enterpriseConfig
  },{
    path: "/enterprise-verify",
    method: "GET",
    handler: require('./facets/enterprise/show-verification'),
    config: enterpriseConfig
  },{
    path: "/enterprise/license",
    method: ["GET","POST"],
    handler: require('./facets/enterprise/find-license'),
    config: stripeSafeConfig
  },{
    path: "/enterprise/license-options",
    method: "GET",
    handler: require('./facets/enterprise/license-options'),
    config: stripeSafeConfig
  },{
    path: "/enterprise/buy-license",
    method: "POST",
    handler: require('./facets/enterprise/buy-license'),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/enterprise/license-paid",
    method: "GET",
    handler: require('./facets/enterprise/license-paid'),
    config: enterpriseConfig
  },{
    path: "/enterprise/license-error",
    method: "GET",
    handler: require('./facets/enterprise/license-error'),
    config: enterpriseConfig
  },{
    path: "/package/{package}/{version?}",
    method: "GET",
    handler: require('./facets/registry/show-package')
  },{
    path: "/packages/{package}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/package/" + request.params.package).code(301);
    }
  },{
    // Redirect to home, because who cares
    path: "/browse/all",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/").code(301);
    }
  },{
    // Redirect to /~user#packages
    path: "/browse/author/{user}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect(fmt("/~%s#packages", request.params.user)).code(301);
    }
  },{
    // Users, ordered descending by how many packages they've starred
    path: "/browse/userstar",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect("/").code(301);
    }
  },{
    // Redirect to /~user#starred
    path: "/browse/userstar/{user}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect(fmt("/~%s#starred", request.params.user)).code(301);
    }
  },{
    // Catch-all for all other browse pages
    // - top keywords
    // - packages that have a certain keywords
    // - recently updated packages
    // - prolific authors
    // - most depended-upon packages
    // - all the packages that depend on the given package
    path: "/browse/{p*}",
    method: "GET",
    handler: require('./facets/registry/show-browse')
  },{
    path: "/keyword/{kw}",
    method: "GET",
    handler: function(request, reply) {
      return reply.redirect('/browse/keyword/' + request.params.kw).code(301);
    }
  },{
    path: "/recent-authors/{since?}",
    method: "GET",
    handler: require('./facets/registry/show-recent-authors')
  },{
    path: "/star",
    method: "POST",
    handler: require('./facets/registry/show-star'),
    config: {
      plugins: {
        // tolerate Ajax
        crumb: {
          source: 'payload',
          restful: true
        }
      }
    }
  },{
    path: "/search/{q?}",
    method: "GET",
    handler: require('./facets/registry/show-search')(config.search)
  },{
    path: "/~{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile/{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/~/{name}",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/signup",
    method: "GET",
    handler: require('./facets/user/show-signup')
  },{
    path: "/signup",
    method: "HEAD",
    handler: require('./facets/user/show-signup')
  },{
    path: "/signup",
    method: "POST",
    handler: require('./facets/user/show-signup')
  },{
    path: "/login",
    method: "GET",
    handler: require('./facets/user/show-login')
  },{
    path: "/login",
    method: "POST",
    handler: require('./facets/user/show-login')
  },{
    path: "/logout",
    method: "GET",
    handler: require('./facets/user/show-logout')
  },{
    path: "/forgot/{token?}",
    method: "GET",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/forgot/{token?}",
    method: "HEAD",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/forgot/{token?}",
    method: "POST",
    handler: require('./facets/user/show-forgot')(config.user.mail)
  },{
    path: "/_monitor/ping",
    method: "GET",
    handler: function(request, reply) {
      return reply('ok').code(200);
    }
  },{
    path: "/_monitor/status",
    method: "GET",
    handler: ops.status(require('./package.json').version)
  },{
    path: "/-/csplog",
    method: "POST",
    handler: ops.csplog,
    config: {
      plugins: {
        crumb: false
      }
    }
  },{
    method: '*',
    path: '/doc/{p*}',
    handler: function(request, reply) {
      return reply.redirect(require("url").format({
        protocol: "https",
        hostname: "docs.npmjs.com",
        pathname: request.url.path
          .replace(/^\/doc/, "")
          .replace(/\.html$/, "")
          .replace(/\/npm-/, "/")
      })).code(301)
    }
  },{
    method: '*',
    path: '/{p*}',
    handler: fallback
  }

];

var authenticatedRoutes = [
  {
    // shortcut for viewing your own stars
    path: "/star",
    method: "GET",
    handler: require('./facets/registry/show-star'),
  },{
    path: "/~",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile",
    method: "GET",
    handler: require('./facets/user/show-profile')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "GET",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "PUT",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/profile-edit",
    method: "POST",
    handler: require('./facets/user/show-profile-edit')(config.user.profileFields)
  },{
    path: "/email-edit",
    method: "GET",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "HEAD",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "PUT",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit",
    method: "POST",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    // confirm or revert
    // /email-edit/confirm/1234567
    // /email-edit/revert/1234567
    path: "/email-edit/{token*2}",
    method: "GET",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/email-edit/{token*2}",
    method: "HEAD",
    handler: require('./facets/user/show-email-edit')(config.user.mail)
  },{
    path: "/password",
    method: "GET",
    handler: require('./facets/user/show-password')
  },{
    path: "/password",
    method: "HEAD",
    handler: require('./facets/user/show-password')
  },{
    path: "/password",
    method: "POST",
    handler: require('./facets/user/show-password')
  }

]

// Apply unathenticated route config to all the public routes
unauthenticatedRoutes = unauthenticatedRoutes.map(function(route){
  return Hoek.applyToDefaults(unathenticatedRouteConfig, route)
})

module.exports = unauthenticatedRoutes.concat(authenticatedRoutes)

function fallback(request, reply) {

  // 1. Try to render a static page
  // 2. Look for a package with the given name
  // 3. 404

  var route = request.params.p,
    opts = {
      user: request.auth.credentials,
    };

  request.server.methods.corp.getPage(route, function(er, content) {

    if (content) {
      opts.md = content;
      return reply.view('company/corporate', opts);
    }

    request.server.methods.registry.getPackage(route, function(err, package) {

      if (package) {
        return reply.redirect('/package/' + package._id);
      }

      // Add package to view context if path is a valid package name
      if (validatePackageName(request.params.p).valid) {
        opts.package = {name: request.params.p};
      }

      return reply.view('errors/not-found', opts).code(404);
    });
  });
}
<|endoftext|>


<commit_before>'use strict';

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.set('X-Auth-Required', 'true');
  req.session.returnUrl = req.originalUrl;
  res.redirect('/login/');
}

function ensureAdmin(req, res, next) {
  if (req.user.canPlayRoleOf('admin')) {
    return next();
  }
  res.redirect('/');
}

function ensureAccount(req, res, next) {
  if (req.user.canPlayRoleOf('account')) {
    if (req.app.config.requireAccountVerification) {
      if (req.user.roles.account.isVerified !== 'yes' && !/^\/account\/verification\//.test(req.url)) {
        return res.redirect('/account/verification/');
      }
    }
    return next();
  }
  res.redirect('/');
}

exports = module.exports = function(app, passport) {

  app.post('/api/v1/signup/', require('./api/signup/index').signup);

  //social sign up
  app.post('/signup/social/', require('./api/signup/index').signupSocial);
  app.get('/signup/twitter/', passport.authenticate('twitter', { callbackURL: '/signup/twitter/callback/' }));
  app.get('/signup/twitter/callback/', require('./api/signup/index').signupTwitter);
  app.get('/signup/github/', passport.authenticate('github', { callbackURL: '/signup/github/callback/', scope: ['user:email'] }));
  app.get('/signup/github/callback/', require('./api/signup/index').signupGitHub);
  app.get('/signup/facebook/', passport.authenticate('facebook', { callbackURL: '/signup/facebook/callback/', scope: ['email'] }));
  app.get('/signup/facebook/callback/', require('./api/signup/index').signupFacebook);
  app.get('/signup/google/', passport.authenticate('google', { callbackURL: '/signup/google/callback/', scope: ['profile email'] }));
  app.get('/signup/google/callback/', require('./api/signup/index').signupGoogle);
  app.get('/signup/tumblr/', passport.authenticate('tumblr', { callbackURL: '/signup/tumblr/callback/' }));
  app.get('/signup/tumblr/callback/', require('./api/signup/index').signupTumblr);

  //login/out
  //app.get('/login/', require('./api/login/index').init);
  app.post('/api/v1/login/', require('./api/login/index').login);
  //app.get('/login/forgot/', require('./api/login/forgot/index').init);
  app.post('/api/v1/login/forgot/', require('./api/login/forgot/index').send);
  //app.get('/login/reset/', require('./api/login/reset/index').init);
  app.get('/api/v1/login/reset/:email/:token/', require('./api/login/reset/index').init);
  app.put('/api/v1/login/reset/:email/:token/', require('./api/login/reset/index').set);
  app.get('/logout/', require('./api/logout/index').init);

  //Check if logged in and get user object
  app.post('/api/v1/user/', require('./api/login/index').check);

  //social login
  app.get('/login/twitter/', passport.authenticate('twitter', { callbackURL: '/login/twitter/callback/' }));
  app.get('/login/twitter/callback/', require('./api/login/index').loginTwitter);
  app.get('/login/github/', passport.authenticate('github', { callbackURL: '/login/github/callback/' }));
  app.get('/login/github/callback/', require('./api/login/index').loginGitHub);
  app.get('/login/facebook/', passport.authenticate('facebook', { callbackURL: '/login/facebook/callback/' }));
  app.get('/login/facebook/callback/', require('./api/login/index').loginFacebook);
  app.get('/login/google/', passport.authenticate('google', { callbackURL: '/login/google/callback/', scope: ['profile email'] }));
  app.get('/login/google/callback/', require('./api/login/index').loginGoogle);
  app.get('/login/tumblr/', passport.authenticate('tumblr', { callbackURL: '/login/tumblr/callback/', scope: ['profile email'] }));
  app.get('/login/tumblr/callback/', require('./api/login/index').loginTumblr);

  //admin
  app.all('/admin*', ensureAuthenticated);
  app.all('/admin*', ensureAdmin);
  app.get('/admin/', require('./api/admin/index').init);

  //admin > users
  app.get('/admin/users/', require('./api/admin/users/index').find);
  app.post('/admin/users/', require('./api/admin/users/index').create);
  app.get('/admin/users/:id/', require('./api/admin/users/index').read);
  app.put('/admin/users/:id/', require('./api/admin/users/index').update);
  app.put('/admin/users/:id/password/', require('./api/admin/users/index').password);
  app.put('/admin/users/:id/role-admin/', require('./api/admin/users/index').linkAdmin);
  app.delete('/admin/users/:id/role-admin/', require('./api/admin/users/index').unlinkAdmin);
  app.put('/admin/users/:id/role-account/', require('./api/admin/users/index').linkAccount);
  app.delete('/admin/users/:id/role-account/', require('./api/admin/users/index').unlinkAccount);
  app.delete('/admin/users/:id/', require('./api/admin/users/index').delete);

  //admin > administrators
  app.get('/admin/administrators/', require('./api/admin/administrators/index').find);
  app.post('/admin/administrators/', require('./api/admin/administrators/index').create);
  app.get('/admin/administrators/:id/', require('./api/admin/administrators/index').read);
  app.put('/admin/administrators/:id/', require('./api/admin/administrators/index').update);
  app.put('/admin/administrators/:id/permissions/', require('./api/admin/administrators/index').permissions);
  app.put('/admin/administrators/:id/groups/', require('./api/admin/administrators/index').groups);
  app.put('/admin/administrators/:id/user/', require('./api/admin/administrators/index').linkUser);
  app.delete('/admin/administrators/:id/user/', require('./api/admin/administrators/index').unlinkUser);
  app.delete('/admin/administrators/:id/', require('./api/admin/administrators/index').delete);

  //admin > admin groups
  app.get('/admin/admin-groups/', require('./api/admin/admin-groups/index').find);
  app.post('/admin/admin-groups/', require('./api/admin/admin-groups/index').create);
  app.get('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').read);
  app.put('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').update);
  app.put('/admin/admin-groups/:id/permissions/', require('./api/admin/admin-groups/index').permissions);
  app.delete('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').delete);

  //admin > accounts
  app.get('/admin/accounts/', require('./api/admin/accounts/index').find);
  app.post('/admin/accounts/', require('./api/admin/accounts/index').create);
  app.get('/admin/accounts/:id/', require('./api/admin/accounts/index').read);
  app.put('/admin/accounts/:id/', require('./api/admin/accounts/index').update);
  app.put('/admin/accounts/:id/user/', require('./api/admin/accounts/index').linkUser);
  app.delete('/admin/accounts/:id/user/', require('./api/admin/accounts/index').unlinkUser);
  app.post('/admin/accounts/:id/notes/', require('./api/admin/accounts/index').newNote);
  app.post('/admin/accounts/:id/status/', require('./api/admin/accounts/index').newStatus);
  app.delete('/admin/accounts/:id/', require('./api/admin/accounts/index').delete);

  //admin > statuses
  app.get('/admin/statuses/', require('./api/admin/statuses/index').find);
  app.post('/admin/statuses/', require('./api/admin/statuses/index').create);
  app.get('/admin/statuses/:id/', require('./api/admin/statuses/index').read);
  app.put('/admin/statuses/:id/', require('./api/admin/statuses/index').update);
  app.delete('/admin/statuses/:id/', require('./api/admin/statuses/index').delete);

  //admin > categories
  app.get('/admin/categories/', require('./api/admin/categories/index').find);
  app.post('/admin/categories/', require('./api/admin/categories/index').create);
  app.get('/admin/categories/:id/', require('./api/admin/categories/index').read);
  app.put('/admin/categories/:id/', require('./api/admin/categories/index').update);
  app.delete('/admin/categories/:id/', require('./api/admin/categories/index').delete);

  //admin > search
  app.get('/admin/search/', require('./api/admin/search/index').find);

  //account
  app.all('/account*', ensureAuthenticated);
  app.all('/account*', ensureAccount);
  app.get('/account/', require('./api/account/index').init);

  //account > verification
  app.get('/account/verification/', require('./api/account/verification/index').init);
  app.post('/account/verification/', require('./api/account/verification/index').resendVerification);
  app.get('/account/verification/:token/', require('./api/account/verification/index').verify);

  //account > settings
  app.get('/account/settings/', require('./api/account/settings/index').init);
  app.put('/account/settings/', require('./api/account/settings/index').update);
  app.put('/account/settings/identity/', require('./api/account/settings/index').identity);
  app.put('/account/settings/password/', require('./api/account/settings/index').password);

  //account > settings > social
  app.get('/account/settings/twitter/', passport.authenticate('twitter', { callbackURL: '/account/settings/twitter/callback/' }));
  app.get('/account/settings/twitter/callback/', require('./api/account/settings/index').connectTwitter);
  app.get('/account/settings/twitter/disconnect/', require('./api/account/settings/index').disconnectTwitter);
  app.get('/account/settings/github/', passport.authenticate('github', { callbackURL: '/account/settings/github/callback/' }));
  app.get('/account/settings/github/callback/', require('./api/account/settings/index').connectGitHub);
  app.get('/account/settings/github/disconnect/', require('./api/account/settings/index').disconnectGitHub);
  app.get('/account/settings/facebook/', passport.authenticate('facebook', { callbackURL: '/account/settings/facebook/callback/' }));
  app.get('/account/settings/facebook/callback/', require('./api/account/settings/index').connectFacebook);
  app.get('/account/settings/facebook/disconnect/', require('./api/account/settings/index').disconnectFacebook);
  app.get('/account/settings/google/', passport.authenticate('google', { callbackURL: '/account/settings/google/callback/', scope: ['profile email'] }));
  app.get('/account/settings/google/callback/', require('./api/account/settings/index').connectGoogle);
  app.get('/account/settings/google/disconnect/', require('./api/account/settings/index').disconnectGoogle);
  app.get('/account/settings/tumblr/', passport.authenticate('tumblr', { callbackURL: '/account/settings/tumblr/callback/' }));
  app.get('/account/settings/tumblr/callback/', require('./api/account/settings/index').connectTumblr);
  app.get('/account/settings/tumblr/disconnect/', require('./api/account/settings/index').disconnectTumblr);

  //app

  app.get('/cellar/', require('./api/cellar/index').find);
  app.post('/cellar/', require('./api/cellar/index').create);
  app.delete('/cellar/:id', require('./api/cellar/index').delete);

  //route not found
  app.all('*', require('./api/http/index').http404);
};
<commit_msg>changed post to get for user check<commit_after>'use strict';

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.set('X-Auth-Required', 'true');
  req.session.returnUrl = req.originalUrl;
  res.redirect('/login/');
}

function ensureAdmin(req, res, next) {
  if (req.user.canPlayRoleOf('admin')) {
    return next();
  }
  res.redirect('/');
}

function ensureAccount(req, res, next) {
  if (req.user.canPlayRoleOf('account')) {
    if (req.app.config.requireAccountVerification) {
      if (req.user.roles.account.isVerified !== 'yes' && !/^\/account\/verification\//.test(req.url)) {
        return res.redirect('/account/verification/');
      }
    }
    return next();
  }
  res.redirect('/');
}

exports = module.exports = function(app, passport) {

  app.post('/api/v1/signup/', require('./api/signup/index').signup);

  //social sign up
  app.post('/signup/social/', require('./api/signup/index').signupSocial);
  app.get('/signup/twitter/', passport.authenticate('twitter', { callbackURL: '/signup/twitter/callback/' }));
  app.get('/signup/twitter/callback/', require('./api/signup/index').signupTwitter);
  app.get('/signup/github/', passport.authenticate('github', { callbackURL: '/signup/github/callback/', scope: ['user:email'] }));
  app.get('/signup/github/callback/', require('./api/signup/index').signupGitHub);
  app.get('/signup/facebook/', passport.authenticate('facebook', { callbackURL: '/signup/facebook/callback/', scope: ['email'] }));
  app.get('/signup/facebook/callback/', require('./api/signup/index').signupFacebook);
  app.get('/signup/google/', passport.authenticate('google', { callbackURL: '/signup/google/callback/', scope: ['profile email'] }));
  app.get('/signup/google/callback/', require('./api/signup/index').signupGoogle);
  app.get('/signup/tumblr/', passport.authenticate('tumblr', { callbackURL: '/signup/tumblr/callback/' }));
  app.get('/signup/tumblr/callback/', require('./api/signup/index').signupTumblr);

  //login/out
  //app.get('/login/', require('./api/login/index').init);
  app.post('/api/v1/login/', require('./api/login/index').login);
  //app.get('/login/forgot/', require('./api/login/forgot/index').init);
  app.post('/api/v1/login/forgot/', require('./api/login/forgot/index').send);
  //app.get('/login/reset/', require('./api/login/reset/index').init);
  app.get('/api/v1/login/reset/:email/:token/', require('./api/login/reset/index').init);
  app.put('/api/v1/login/reset/:email/:token/', require('./api/login/reset/index').set);
  app.get('/logout/', require('./api/logout/index').init);

  //Check if logged in and get user object
  app.get('/api/v1/user/', require('./api/login/index').check);

  //social login
  app.get('/login/twitter/', passport.authenticate('twitter', { callbackURL: '/login/twitter/callback/' }));
  app.get('/login/twitter/callback/', require('./api/login/index').loginTwitter);
  app.get('/login/github/', passport.authenticate('github', { callbackURL: '/login/github/callback/' }));
  app.get('/login/github/callback/', require('./api/login/index').loginGitHub);
  app.get('/login/facebook/', passport.authenticate('facebook', { callbackURL: '/login/facebook/callback/' }));
  app.get('/login/facebook/callback/', require('./api/login/index').loginFacebook);
  app.get('/login/google/', passport.authenticate('google', { callbackURL: '/login/google/callback/', scope: ['profile email'] }));
  app.get('/login/google/callback/', require('./api/login/index').loginGoogle);
  app.get('/login/tumblr/', passport.authenticate('tumblr', { callbackURL: '/login/tumblr/callback/', scope: ['profile email'] }));
  app.get('/login/tumblr/callback/', require('./api/login/index').loginTumblr);

  //admin
  app.all('/admin*', ensureAuthenticated);
  app.all('/admin*', ensureAdmin);
  app.get('/admin/', require('./api/admin/index').init);

  //admin > users
  app.get('/admin/users/', require('./api/admin/users/index').find);
  app.post('/admin/users/', require('./api/admin/users/index').create);
  app.get('/admin/users/:id/', require('./api/admin/users/index').read);
  app.put('/admin/users/:id/', require('./api/admin/users/index').update);
  app.put('/admin/users/:id/password/', require('./api/admin/users/index').password);
  app.put('/admin/users/:id/role-admin/', require('./api/admin/users/index').linkAdmin);
  app.delete('/admin/users/:id/role-admin/', require('./api/admin/users/index').unlinkAdmin);
  app.put('/admin/users/:id/role-account/', require('./api/admin/users/index').linkAccount);
  app.delete('/admin/users/:id/role-account/', require('./api/admin/users/index').unlinkAccount);
  app.delete('/admin/users/:id/', require('./api/admin/users/index').delete);

  //admin > administrators
  app.get('/admin/administrators/', require('./api/admin/administrators/index').find);
  app.post('/admin/administrators/', require('./api/admin/administrators/index').create);
  app.get('/admin/administrators/:id/', require('./api/admin/administrators/index').read);
  app.put('/admin/administrators/:id/', require('./api/admin/administrators/index').update);
  app.put('/admin/administrators/:id/permissions/', require('./api/admin/administrators/index').permissions);
  app.put('/admin/administrators/:id/groups/', require('./api/admin/administrators/index').groups);
  app.put('/admin/administrators/:id/user/', require('./api/admin/administrators/index').linkUser);
  app.delete('/admin/administrators/:id/user/', require('./api/admin/administrators/index').unlinkUser);
  app.delete('/admin/administrators/:id/', require('./api/admin/administrators/index').delete);

  //admin > admin groups
  app.get('/admin/admin-groups/', require('./api/admin/admin-groups/index').find);
  app.post('/admin/admin-groups/', require('./api/admin/admin-groups/index').create);
  app.get('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').read);
  app.put('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').update);
  app.put('/admin/admin-groups/:id/permissions/', require('./api/admin/admin-groups/index').permissions);
  app.delete('/admin/admin-groups/:id/', require('./api/admin/admin-groups/index').delete);

  //admin > accounts
  app.get('/admin/accounts/', require('./api/admin/accounts/index').find);
  app.post('/admin/accounts/', require('./api/admin/accounts/index').create);
  app.get('/admin/accounts/:id/', require('./api/admin/accounts/index').read);
  app.put('/admin/accounts/:id/', require('./api/admin/accounts/index').update);
  app.put('/admin/accounts/:id/user/', require('./api/admin/accounts/index').linkUser);
  app.delete('/admin/accounts/:id/user/', require('./api/admin/accounts/index').unlinkUser);
  app.post('/admin/accounts/:id/notes/', require('./api/admin/accounts/index').newNote);
  app.post('/admin/accounts/:id/status/', require('./api/admin/accounts/index').newStatus);
  app.delete('/admin/accounts/:id/', require('./api/admin/accounts/index').delete);

  //admin > statuses
  app.get('/admin/statuses/', require('./api/admin/statuses/index').find);
  app.post('/admin/statuses/', require('./api/admin/statuses/index').create);
  app.get('/admin/statuses/:id/', require('./api/admin/statuses/index').read);
  app.put('/admin/statuses/:id/', require('./api/admin/statuses/index').update);
  app.delete('/admin/statuses/:id/', require('./api/admin/statuses/index').delete);

  //admin > categories
  app.get('/admin/categories/', require('./api/admin/categories/index').find);
  app.post('/admin/categories/', require('./api/admin/categories/index').create);
  app.get('/admin/categories/:id/', require('./api/admin/categories/index').read);
  app.put('/admin/categories/:id/', require('./api/admin/categories/index').update);
  app.delete('/admin/categories/:id/', require('./api/admin/categories/index').delete);

  //admin > search
  app.get('/admin/search/', require('./api/admin/search/index').find);

  //account
  app.all('/account*', ensureAuthenticated);
  app.all('/account*', ensureAccount);
  app.get('/account/', require('./api/account/index').init);

  //account > verification
  app.get('/account/verification/', require('./api/account/verification/index').init);
  app.post('/account/verification/', require('./api/account/verification/index').resendVerification);
  app.get('/account/verification/:token/', require('./api/account/verification/index').verify);

  //account > settings
  app.get('/account/settings/', require('./api/account/settings/index').init);
  app.put('/account/settings/', require('./api/account/settings/index').update);
  app.put('/account/settings/identity/', require('./api/account/settings/index').identity);
  app.put('/account/settings/password/', require('./api/account/settings/index').password);

  //account > settings > social
  app.get('/account/settings/twitter/', passport.authenticate('twitter', { callbackURL: '/account/settings/twitter/callback/' }));
  app.get('/account/settings/twitter/callback/', require('./api/account/settings/index').connectTwitter);
  app.get('/account/settings/twitter/disconnect/', require('./api/account/settings/index').disconnectTwitter);
  app.get('/account/settings/github/', passport.authenticate('github', { callbackURL: '/account/settings/github/callback/' }));
  app.get('/account/settings/github/callback/', require('./api/account/settings/index').connectGitHub);
  app.get('/account/settings/github/disconnect/', require('./api/account/settings/index').disconnectGitHub);
  app.get('/account/settings/facebook/', passport.authenticate('facebook', { callbackURL: '/account/settings/facebook/callback/' }));
  app.get('/account/settings/facebook/callback/', require('./api/account/settings/index').connectFacebook);
  app.get('/account/settings/facebook/disconnect/', require('./api/account/settings/index').disconnectFacebook);
  app.get('/account/settings/google/', passport.authenticate('google', { callbackURL: '/account/settings/google/callback/', scope: ['profile email'] }));
  app.get('/account/settings/google/callback/', require('./api/account/settings/index').connectGoogle);
  app.get('/account/settings/google/disconnect/', require('./api/account/settings/index').disconnectGoogle);
  app.get('/account/settings/tumblr/', passport.authenticate('tumblr', { callbackURL: '/account/settings/tumblr/callback/' }));
  app.get('/account/settings/tumblr/callback/', require('./api/account/settings/index').connectTumblr);
  app.get('/account/settings/tumblr/disconnect/', require('./api/account/settings/index').disconnectTumblr);

  //app

  app.get('/cellar/', require('./api/cellar/index').find);
  app.post('/cellar/', require('./api/cellar/index').create);
  app.delete('/cellar/:id', require('./api/cellar/index').delete);

  //route not found
  app.all('*', require('./api/http/index').http404);
};
<|endoftext|>