<commit_before>/* global THREE, drawGear */
(function() {
  'use strict';

  var container;

  var scene, camera, controls, renderer;

  var clock = new THREE.Clock();
  var running = true;

  var dt = 1 / 60;
  var accumulatedTime = 0;

  var lights = {
    basic: function( scene ) {
      var light = new THREE.DirectionalLight();
      light.position.set( 0, 8, 16 );
      scene.add( light );

      scene.add( new THREE.AmbientLight( '#222' ) );
    }
  };

  var spinners = {
    circles: (function() {
      var geometry = new THREE.BoxGeometry( 1, 1, 1 );
      var material = new THREE.MeshPhongMaterial();

      var mesh = new THREE.Mesh( geometry, material );
      mesh.position.x = 2;

      var group = new THREE.Group();
      group.add( mesh );

      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          mesh.rotation.x += 5 * dt;
          mesh.rotation.y += 5 * dt;
          group.rotation.y += 5 * dt;
        }
      };
    })(),

    loops: (function() {
      var radius = 0.1;
      var diameter = 2 * radius;

      var group = new THREE.Group();
      var meshes = new THREE.Group();

      var parent = meshes;
      var count = 8;
      var i = count;
      while ( i-- ) {
        var scale = i * diameter + 2;

        var geometry = new THREE.TorusGeometry( scale, radius, 16, 64 );
        var material = new THREE.MeshPhongMaterial({
          color: 'hsl(' + ( i * 360 / count ) + ', 100%, 50%)'
        });

        var mesh = new THREE.Mesh( geometry, material );
        parent.add( mesh );
        parent = mesh;
      }

      group.add( meshes );

      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          meshes.traverse(function( mesh ) {
            if (!mesh.geometry) {
              return;
            }

            mesh.rotation.x += dt;
            mesh.rotation.y += dt;
          });
        }
      };
    })(),

    particles: (function() {
      var PI2 = 2 * Math.PI;

      function randomPointOnSphere( vector, radius ) {
        radius = radius || 1;

        var theta = PI2 * Math.random();
        var u = 2 * Math.random() - 1;
        var v = Math.sqrt( 1 - u * u );

        return vector.set(
          radius * v * Math.cos( theta ),
          radius * v * Math.sin( theta ),
          radius * u
        );
      }

      var size = 0.1;

      var geometry = new THREE.BufferGeometry()
        .fromGeometry( new THREE.BoxGeometry( size, size, size ) );

      var material = new THREE.MeshPhongMaterial();

      var scene = new THREE.Group();
      var group = new THREE.Group();
      scene.add( group );

      var particles = [];

      var count = 512;
      var i = count;
      while ( i-- ) {
        var particle = new THREE.Object3D();
        group.add( particle );

        var mesh = new THREE.Mesh( geometry, material );
        particle.add( mesh );

        randomPointOnSphere( mesh.position, 4 * Math.random() );
        mesh.rotation.set(
          PI2 * Math.random(),
          PI2 * Math.random(),
          PI2 * Math.random()
        );
        mesh.scale.setLength( THREE.Math.randFloat( 0.5, 1.5 ) );

        particles.push({
          object: particle,
          angularVelocity: new THREE.Vector3(
            THREE.Math.randFloatSpread( 1 ),
            THREE.Math.randFloatSpread( 1 ),
            THREE.Math.randFloatSpread( 1 )
          )
        });
      }

      lights.basic( scene );

      var vector = new THREE.Vector3();

      return {
        group: scene,
        update: function( dt ) {
          group.rotation.x += 0.5 * dt;
          group.rotation.y += dt;

          particles.forEach(function( particle ) {
            vector.copy( particle.object.rotation )
              .addScaledVector( particle.angularVelocity, dt );

            particle.object.rotation.setFromVector3( vector );
          });
        }
      }
    })(),

    gears: (function() {
      var sunRadius = 2;
      var planetRadius = 1.5;
      var toothHeight = 0.2 * planetRadius;

      var sunTeethCount = 12;
      var planetTeethCount = 8;
      var annulusTeethCount = sunTeethCount + 2 * planetTeethCount;

      var bevelSize = 0.1;
      var planetPosition = planetRadius + sunRadius + toothHeight + 2 * bevelSize;
      var annulusRadius = planetPosition + planetRadius + toothHeight + 2 * bevelSize;

      var annulusGearShape = new THREE.Shape();
      annulusGearShape.absarc( 0, 0, annulusRadius + toothHeight, 0, 2 * Math.PI );

      var annulusHole = drawGear( new THREE.Shape(), annulusRadius, annulusTeethCount, [
        [ 0.2, annulusRadius ],
        [ 0.4, annulusRadius - toothHeight ],
        [ 0.6, annulusRadius - toothHeight ],
        [ 0.8, annulusRadius ]
      ]);

      annulusGearShape.holes.push( annulusHole );

      var hole = new THREE.Shape();
      hole.absarc( 0, 0, 0.4 * planetRadius, 0, 2 * Math.PI );

      var sunGearShape = drawGear( new THREE.Shape(), sunRadius, sunTeethCount, [
        [ 0.2, sunRadius ],
        [ 0.4, sunRadius + toothHeight ],
        [ 0.6, sunRadius + toothHeight ],
        [ 0.8, sunRadius ]
      ]);

      sunGearShape.holes.push( hole );

      var planetGearShape = drawGear( new THREE.Shape(), planetRadius, planetTeethCount, [
        [ 0.2, planetRadius ],
        [ 0.4, planetRadius + toothHeight ],
        [ 0.6, planetRadius + toothHeight ],
        [ 0.8, planetRadius ]
      ]);

      planetGearShape.holes.push( hole );

      var extrudeOptions = {
        amount: 0.5,
        bevelEnabled: true,
        steps: 1,
        bevelSize: bevelSize,
        bevelThickness: 0.1,
        bevelSegments: 1
      };

      var annulusGearGeometry = new THREE.ExtrudeGeometry( annulusGearShape, Object.assign( {}, extrudeOptions, { curveSegments: 56 } ) );
      var sunGearGeometry = new THREE.ExtrudeGeometry( sunGearShape, extrudeOptions );
      var planetGearGeometry = new THREE.ExtrudeGeometry( planetGearShape, extrudeOptions );

      var material = new THREE.MeshStandardMaterial();

      var annulusGear = new THREE.Mesh( annulusGearGeometry, material );
      var sunGear = new THREE.Mesh( sunGearGeometry, material );
      var topPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var leftPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var rightPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var bottomPlanetGear = new THREE.Mesh( planetGearGeometry, material );

      topPlanetGear.position.y = planetPosition;
      leftPlanetGear.position.x = planetPosition;
      rightPlanetGear.position.x = -planetPosition;
      bottomPlanetGear.position.y = -planetPosition;

      // Shift by half a tooth width.
      annulusGear.rotation.z += Math.PI / annulusTeethCount;
      sunGear.rotation.z += Math.PI / sunTeethCount;

      var group = new THREE.Group();
      group.add( annulusGear );
      group.add( sunGear );
      group.add( topPlanetGear );
      group.add( leftPlanetGear );
      group.add( rightPlanetGear );
      group.add( bottomPlanetGear );
      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          annulusGear.rotation.z -= planetTeethCount / annulusTeethCount * dt;
          sunGear.rotation.z += planetTeethCount / sunTeethCount * dt;
          topPlanetGear.rotation.z -= dt;
          leftPlanetGear.rotation.z -= dt;
          rightPlanetGear.rotation.z -= dt;
          bottomPlanetGear.rotation.z -= dt;
        }
      }
    })()
  };

  var spinner = spinners.gears;

  function init() {
    container = document.createElement( 'div' );
    document.body.appendChild( container );

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight );
    camera.position.set( 0, 0, 8 );

    controls = new THREE.OrbitControls( camera, renderer.domElement );

    controls.addEventListener( 'change', function() {
      if ( !running ) {
        render();
      }
    });

    scene.add( spinner.group );
  }

  function render() {
    renderer.render( scene, camera );
  }

  function animate() {
    if ( !running ) {
      return;
    }

    var delta = Math.min( clock.getDelta(), 0.1 );
    accumulatedTime += delta;

    while ( accumulatedTime >= dt ) {
      spinner.update( dt );
      accumulatedTime -= dt;
    }

    render();
    requestAnimationFrame( animate );
  }

  init();
  animate();

  window.addEventListener( 'resize', function() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );
  });

  // Double click to restart animation.
  document.addEventListener( 'dblclick', function() {
    running = !running;

    if ( running ) {
      clock.start();
      animate();
    }
  });

  // Scroll to control animation.
  renderer.domElement.addEventListener( 'wheel', function( event ) {
    if ( !event.deltaY ) {
      return;
    }

    event.preventDefault();
    running = false;

    spinner.update( event.deltaY * dt );
    render();
  });
})();
<commit_msg>spinners[gears]: Enable zooming with shift-key.<commit_after>/* global THREE, drawGear */
(function() {
  'use strict';

  var container;

  var scene, camera, controls, renderer;

  var clock = new THREE.Clock();
  var running = true;

  var dt = 1 / 60;
  var accumulatedTime = 0;

  var lights = {
    basic: function( scene ) {
      var light = new THREE.DirectionalLight();
      light.position.set( 0, 8, 16 );
      scene.add( light );

      scene.add( new THREE.AmbientLight( '#222' ) );
    }
  };

  var spinners = {
    circles: (function() {
      var geometry = new THREE.BoxGeometry( 1, 1, 1 );
      var material = new THREE.MeshPhongMaterial();

      var mesh = new THREE.Mesh( geometry, material );
      mesh.position.x = 2;

      var group = new THREE.Group();
      group.add( mesh );

      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          mesh.rotation.x += 5 * dt;
          mesh.rotation.y += 5 * dt;
          group.rotation.y += 5 * dt;
        }
      };
    })(),

    loops: (function() {
      var radius = 0.1;
      var diameter = 2 * radius;

      var group = new THREE.Group();
      var meshes = new THREE.Group();

      var parent = meshes;
      var count = 8;
      var i = count;
      while ( i-- ) {
        var scale = i * diameter + 2;

        var geometry = new THREE.TorusGeometry( scale, radius, 16, 64 );
        var material = new THREE.MeshPhongMaterial({
          color: 'hsl(' + ( i * 360 / count ) + ', 100%, 50%)'
        });

        var mesh = new THREE.Mesh( geometry, material );
        parent.add( mesh );
        parent = mesh;
      }

      group.add( meshes );

      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          meshes.traverse(function( mesh ) {
            if (!mesh.geometry) {
              return;
            }

            mesh.rotation.x += dt;
            mesh.rotation.y += dt;
          });
        }
      };
    })(),

    particles: (function() {
      var PI2 = 2 * Math.PI;

      function randomPointOnSphere( vector, radius ) {
        radius = radius || 1;

        var theta = PI2 * Math.random();
        var u = 2 * Math.random() - 1;
        var v = Math.sqrt( 1 - u * u );

        return vector.set(
          radius * v * Math.cos( theta ),
          radius * v * Math.sin( theta ),
          radius * u
        );
      }

      var size = 0.1;

      var geometry = new THREE.BufferGeometry()
        .fromGeometry( new THREE.BoxGeometry( size, size, size ) );

      var material = new THREE.MeshPhongMaterial();

      var scene = new THREE.Group();
      var group = new THREE.Group();
      scene.add( group );

      var particles = [];

      var count = 512;
      var i = count;
      while ( i-- ) {
        var particle = new THREE.Object3D();
        group.add( particle );

        var mesh = new THREE.Mesh( geometry, material );
        particle.add( mesh );

        randomPointOnSphere( mesh.position, 4 * Math.random() );
        mesh.rotation.set(
          PI2 * Math.random(),
          PI2 * Math.random(),
          PI2 * Math.random()
        );
        mesh.scale.setLength( THREE.Math.randFloat( 0.5, 1.5 ) );

        particles.push({
          object: particle,
          angularVelocity: new THREE.Vector3(
            THREE.Math.randFloatSpread( 1 ),
            THREE.Math.randFloatSpread( 1 ),
            THREE.Math.randFloatSpread( 1 )
          )
        });
      }

      lights.basic( scene );

      var vector = new THREE.Vector3();

      return {
        group: scene,
        update: function( dt ) {
          group.rotation.x += 0.5 * dt;
          group.rotation.y += dt;

          particles.forEach(function( particle ) {
            vector.copy( particle.object.rotation )
              .addScaledVector( particle.angularVelocity, dt );

            particle.object.rotation.setFromVector3( vector );
          });
        }
      }
    })(),

    gears: (function() {
      var sunRadius = 2;
      var planetRadius = 1.5;
      var toothHeight = 0.2 * planetRadius;

      var sunTeethCount = 12;
      var planetTeethCount = 8;
      var annulusTeethCount = sunTeethCount + 2 * planetTeethCount;

      var bevelSize = 0.1;
      var planetPosition = planetRadius + sunRadius + toothHeight + 2 * bevelSize;
      var annulusRadius = planetPosition + planetRadius + toothHeight + 2 * bevelSize;

      var annulusGearShape = new THREE.Shape();
      annulusGearShape.absarc( 0, 0, annulusRadius + toothHeight, 0, 2 * Math.PI );

      var annulusHole = drawGear( new THREE.Shape(), annulusRadius, annulusTeethCount, [
        [ 0.2, annulusRadius ],
        [ 0.4, annulusRadius - toothHeight ],
        [ 0.6, annulusRadius - toothHeight ],
        [ 0.8, annulusRadius ]
      ]);

      annulusGearShape.holes.push( annulusHole );

      var hole = new THREE.Shape();
      hole.absarc( 0, 0, 0.4 * planetRadius, 0, 2 * Math.PI );

      var sunGearShape = drawGear( new THREE.Shape(), sunRadius, sunTeethCount, [
        [ 0.2, sunRadius ],
        [ 0.4, sunRadius + toothHeight ],
        [ 0.6, sunRadius + toothHeight ],
        [ 0.8, sunRadius ]
      ]);

      sunGearShape.holes.push( hole );

      var planetGearShape = drawGear( new THREE.Shape(), planetRadius, planetTeethCount, [
        [ 0.2, planetRadius ],
        [ 0.4, planetRadius + toothHeight ],
        [ 0.6, planetRadius + toothHeight ],
        [ 0.8, planetRadius ]
      ]);

      planetGearShape.holes.push( hole );

      var extrudeOptions = {
        amount: 0.5,
        curveSegments: 2 * annulusTeethCount,
        bevelEnabled: true,
        steps: 1,
        bevelSize: bevelSize,
        bevelThickness: 0.1,
        bevelSegments: 1
      };

      var annulusGearGeometry = new THREE.ExtrudeGeometry( annulusGearShape, extrudeOptions );
      var sunGearGeometry = new THREE.ExtrudeGeometry( sunGearShape, extrudeOptions );
      var planetGearGeometry = new THREE.ExtrudeGeometry( planetGearShape, extrudeOptions );

      var material = new THREE.MeshStandardMaterial();

      var annulusGear = new THREE.Mesh( annulusGearGeometry, material );
      var sunGear = new THREE.Mesh( sunGearGeometry, material );
      var topPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var leftPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var rightPlanetGear = new THREE.Mesh( planetGearGeometry, material );
      var bottomPlanetGear = new THREE.Mesh( planetGearGeometry, material );

      topPlanetGear.position.y = planetPosition;
      leftPlanetGear.position.x = planetPosition;
      rightPlanetGear.position.x = -planetPosition;
      bottomPlanetGear.position.y = -planetPosition;

      // Shift by half a tooth width.
      annulusGear.rotation.z += Math.PI / annulusTeethCount;
      sunGear.rotation.z += Math.PI / sunTeethCount;

      var group = new THREE.Group();
      group.add( annulusGear );
      group.add( sunGear );
      group.add( topPlanetGear );
      group.add( leftPlanetGear );
      group.add( rightPlanetGear );
      group.add( bottomPlanetGear );
      lights.basic( group );

      return {
        group: group,
        update: function( dt ) {
          annulusGear.rotation.z -= planetTeethCount / annulusTeethCount * dt;
          sunGear.rotation.z += planetTeethCount / sunTeethCount * dt;
          topPlanetGear.rotation.z -= dt;
          leftPlanetGear.rotation.z -= dt;
          rightPlanetGear.rotation.z -= dt;
          bottomPlanetGear.rotation.z -= dt;
        }
      }
    })()
  };

  var spinner = spinners.gears;

  function init() {
    container = document.createElement( 'div' );
    document.body.appendChild( container );

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight );
    camera.position.set( 0, 0, 8 );

    controls = new THREE.OrbitControls( camera, renderer.domElement );

    controls.addEventListener( 'change', function() {
      if ( !running ) {
        render();
      }
    });

    scene.add( spinner.group );
  }

  function render() {
    renderer.render( scene, camera );
  }

  function animate() {
    if ( !running ) {
      return;
    }

    var delta = Math.min( clock.getDelta(), 0.1 );
    accumulatedTime += delta;

    while ( accumulatedTime >= dt ) {
      spinner.update( dt );
      accumulatedTime -= dt;
    }

    render();
    requestAnimationFrame( animate );
  }

  init();
  animate();

  window.addEventListener( 'resize', function() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );
  });

  function toggle() {
    running = !running;

    if ( running ) {
      clock.start();
      animate();
    }
  }

  // Scroll to control animation.
  function onWheel( event ) {
    if ( !event.deltaY ) {
      return;
    }

    event.preventDefault();
    running = false;

    spinner.update( event.deltaY * dt );
    render();
  }

  function toggleZoom() {
    controls.enableZoom = !controls.enableZoom;

    // Need to remove/add wheel event-listener for events to propagate to
    // OrbitControls.
    if ( controls.enableZoom ) {
      renderer.domElement.removeEventListener( 'wheel', onWheel );
    } else {
      renderer.domElement.addEventListener( 'wheel', onWheel );
    }
  }

  document.addEventListener( 'keydown', function( event ) {
    // Space.
    if ( event.keyCode === 32 ) {
      toggle();
    }

    if ( event.keyCode === 16 ) {
      toggleZoom();
    }
  });

  document.addEventListener( 'keyup', function( event ) {
    if ( event.keyCode === 16 ) {
      toggleZoom();
    }
  })

  // Double click to restart animation.
  document.addEventListener( 'dblclick', toggle );

  controls.enableZoom = false;
  renderer.domElement.addEventListener( 'wheel', onWheel );
})();
<|endoftext|>


<commit_before><commit_msg>Create scripts.js<commit_after><|endoftext|>


<commit_before>module.exports = function (fs, cli, childProcess, asyncblock, sys) {
	passToConsole = function (error, stdout, stderr) {
		sys.puts(stdout);
	};

	return {
		getConfigOptions: function (configPath) {
			configPath = configPath ? configPath : 'initr.json';

			if (fs.existsSync(configPath)) {
				configFile = fs.readFileSync(configPath);

				this.options = JSON.parse(configFile);

				return this.options;
			} else {
				cli.error('Config file could not be found');
				process.exit(0);
			}
		},
		runCommand: function (command) {
			asyncblock(function(flow){
				childProcess.exec(command, function(error, stdout, stderr) {
					flow.add();
					passToConsole(error, stdout, stderr);
				});
				flow.wait();

				return true;
			});
		},
		runScript: function (scriptPath) {
			asyncblock(function(flow){
				if (scriptPath.indexOf('http') == 0) {
					command = "curl " + scriptPath + " | sh";
					childProcess.exec(command, function(error, stdout, stderr) {
						flow.add();
						passToConsole(error, stdout, stderr);
					});
				} else {
					if (fs.existsSync(scriptPath)) {
						command = "sh " + scriptPath;
						childProcess.exec(command, function(error, stdout, stderr) {
							flow.add();
							passToConsole(error, stdout, stderr);
						});
					}
				}

				flow.wait();
			});
		},
		runFromOptions: function (options) {
			options = options ? options : this.options;

			if (typeof options.scripts !== 'undefined') {
				for (var i = 0; i < options.scripts.length; i++) {
					this.runScript(options.scripts[i]);
				};
			}

			if (typeof options.commands !== 'undefined') {
				for (var i = 0; i < options.commands.length; i++) {
					this.runCommand(options.commands[i]);
				};
			}
		}
	}
}
<commit_msg>Refactor and make sync<commit_after>module.exports = function (fs, cli, childProcess, asyncblock, sys) {
	Initr = {};

	Initr.getConfigOptions = function (configPath) {
		configPath = configPath ? configPath : 'initr.json';

		if (fs.existsSync(configPath)) {
			configFile = fs.readFileSync(configPath);

			this.options = JSON.parse(configFile);

			return this.options;
		} else {
			cli.error('Config file could not be found');
			process.exit(0);
		}
	};

	Initr.runCommand = function (command, callback) {
		asyncblock(function(flow){
			childProcess.exec(command, function(error, stdout, stderr) {
				flow.add();
				passToConsole(error, stdout, stderr);
			});
			flow.wait();

			if (callback) {
				callback();
			}

			return true;
		});
	};

	Initr.runScript = function (scriptPath, callback) {
		asyncblock(function(flow){
			var command;

			if (scriptPath.indexOf('http') == 0) {
				command = "curl " + scriptPath + " | sh";
			} else {
				if (fs.existsSync(scriptPath)) {
					command = "sh " + scriptPath;
				}
			}

			childProcess.exec(command, function(error, stdout, stderr) {
				flow.add();
				passToConsole(error, stdout, stderr);
			});

			flow.wait();

			if (callback) {
				callback();
			}

			return true;
		});
	};

	Initr.runFromOptions = function (options) {
		options = options ? options : this.options;

		if (typeof options.scripts !== 'undefined') {
			for (var i = 0; i < options.scripts.length; i++) {
				asyncblock(function(flow) {
					Initr.runScript(options.scripts[i], function() {
						flow.add();
					});
					flow.wait();
				})
			};
		}

		if (typeof options.commands !== 'undefined') {
			for (var i = 0; i < options.commands.length; i++) {
				asyncblock(function(flow) {
					Initr.runCommand(options.commands[i], function() {
						flow.add();
					});
					flow.wait();
				})
			};
		}
	};

	passToConsole = function (error, stdout, stderr) {
		sys.puts(stdout);
	};

	return Initr;
}
<|endoftext|>


<commit_before><commit_msg>Testing pathname adjust<commit_after><|endoftext|>


<commit_before>import Service from '@ember/service';

export default Service.extend({
  text: null,
});
<commit_msg>services/search-text: Convert to ES6 class<commit_after>import Service from '@ember/service';

export default class SearchTextService extends Service {
  text = null;
}
<|endoftext|>


<commit_before>var validator = require('validator');
var config = require('./config');

/**
 * Shared validation functions for validating various fields.
 * These functions, being in a common library, may not be used
 * for project specific validations and techniques, such as using
 * the project database module to perform various lookups. Those
 * validation tasks are best left to a project specific validation module
 */
var spaceAndPeriodRegex = /^[A-Za-z0-9\.\s]*$/;
var spacePeriodAndUnderscoreRegex = /^[A-Za-z0-9_\.\s]*$/;
var usernameRegex = /^[A-Za-z0-9_@\.]*$/;    // ascii printable plus enough to enter email, and underscores
var passwordRegex = /^[A-Za-z0-9!@#%^&*_\s]*$/;    // A few more punctuation chars.

var firstLastNameRegex = /^[$!{}]/;
var spaceAndLimitedPunctuationRegex = /^[A-Za-z0-9\.\s,!#@$%^&*]*$/;
var serviceNameRegex = /^[A-Za-z0-9\.]*$/;
var spaceOnlyRegex = /^[A-Za-z0-9\s]*$/;

var PermissionStringLength = 100;
var DescriptionStringLength = 256;
var RealmMaxLength = 75;
var RealmMinLength = 2;
var RolesMaxLength = 75;
var OriginsMaxLength = 100;
var RolesMinLength = 75;
var PasswordMinLength = 8;
var PasswordMaxLength = 48;
var EmailMaxLength = 50;
var ServiceMaxLength = 50;

var NameMaxLength = 30;
var NameMinLength = 1;

/**
 * For example, min length 8, max length: 30, no punctuation other than the subrealm
 * separator '.' and '_' and ' '.
 * @param val The realm name to test
 * @return true if ok, false if failed
 */
var realmValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < RealmMinLength || val.length > RealmMaxLength) {
        return false;
    }
    return spacePeriodAndUnderscoreRegex.test(val);
};
exports.realmValidator = realmValidator;

// Username validator. Valid chars are ascii character ranges plus a few punctuation
// characters for email addresses as username.
var usernameValidator = function (val) {

    //In order to have modules respect the logging configuration supplied by the service, we
    //need to get the logger in a 'lazy' fashion.  If we get it during initialization, then
    //the logger instance only has the default configuration.
    var logger = require('./loggers').getLogger();

    if (typeof(val) !=='string') {
        logger.debug('Username invalid type');
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        logger.debug('Username invalid length');
        return false;
    }
    var result = usernameRegex.test(val);
    return result;
};
exports.usernameValidator = usernameValidator;

// First, last name validator
var nameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        return false;
    }
    // Allow all unicode chars for name fields.
    return !firstLastNameRegex.test(val);
};
exports.nameValidator = nameValidator;

// accountname validator.
var accountNameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        return false;
    }
    return spaceAndPeriodRegex.test(val);
};
exports.accountNameValidator = accountNameValidator;

// Account description validator
var descriptionValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > DescriptionStringLength) {
        return false;
    }
    return spaceAndLimitedPunctuationRegex.test(val);
};
exports.descriptionValidator = descriptionValidator;

var serviceNameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > ServiceMaxLength) {
        return false;
    }
    return serviceNameRegex.test(val);
};
exports.serviceNameValidator = serviceNameValidator;

var serviceArrayValidator = function(val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    var service;
    for (var i = 0; i < val.length; i ++) {
        service = val[i];
        if (!serviceNameValidator(service)) {
            return false;
        }
    }
    return true;
}
exports.serviceArrayValidator = serviceArrayValidator;

var booleanValidator = function (val) {
    if (typeof(val) !=='boolean') {
        return false;
    }
    if (true !== val && false !== val) {
        return false;
    }
    return true;
};
exports.booleanValidator = booleanValidator;

var passwordValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < PasswordMinLength || val.length > PasswordMaxLength) {
        return false;
    }
    return passwordRegex.test(val);
};
exports.passwordValidator = passwordValidator;

var emailValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > EmailMaxLength) {
        return false;
    }
    return validator.isEmail(val);
};
exports.emailValidator = emailValidator;

var queryValidator = function (query) {
    // Todo
    return true;
};
exports.queryValidator = queryValidator;

/**
 * Check that the format of the permissions array is correct. This should be
 * done prior to doing the account type validation
 */
var permissionFormatValidator = function (val) {

    //In order to have modules respect the logging configuration supplied by the service, we
    //need to get the logger in a 'lazy' fashion.  If we get it during initialization, then
    //the logger instance only has the default configuration.
    var logger = require('./loggers').getLogger();

    if (Array.isArray(val) === false) {
        logger.debug('Permission set not an array: ' + typeof(val));
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (typeof(val[i]) !=='string') {
            logger.debug('Permission not a string: ' + typeof(val[i]));
            return false;
        }
        if (val[i].length > PermissionStringLength) {
            logger.debug('Invalid permission length: ' + val[i].length);
            return false;
        }
        if (!serviceNameRegex.test(val[i])) {
            logger.debug('Permission name invalid: ' + val[i]);
            return false;
        }
    }
    return true;
};
exports.permissionFormatValidator = permissionFormatValidator;

/**
 * Check that the format of the realm reference array is correct.
 * @param val An array of permission strings
 */
var realmReferenceFormatValidator = function (val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (typeof(val[i]) !=='string') {
            return false;
        }
        if (!val[i] || val[i].length > RealmMaxLength) {
            return false;
        }
        if (!spaceAndPeriodRegex.test(val[i])) {
            return false;
        }
    }
    return true;
};
exports.realmReferenceFormatValidator = realmReferenceFormatValidator;

/**
 * Check that the format of the permissions array is correct. This should be
 * done prior to doing the account type validation
 */
var rolesFormatValidator = function (val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (!val[i] || val[i].length > RolesMaxLength) {
            return false;
        }
        if (!serviceNameRegex.test(val[i])) {
            return false;
        }
    }
    return true;
};
exports.rolesFormatValidator = rolesFormatValidator;

/**
 * Check that the format of the origins array is correct. This should be done as
 * part of the realm validation
 *
 * The origin array can contain a series of domains which need to be validated.
 *
 */
var originsArrayFormatValidator = function(val) {
    if (Array.isArray(val) == false) {
        var logger = require('./loggers').getLogger();
        logger.debug('Origins value is not array');
        return false;
    }
    var pass = true;
    var originField;
    for (var i = 0; i < val.length; i++) {
        if (typeof (val[i]) !== 'string' ) {
            return false;
        }
        if (val[i].length <= 0 || val[i].length > OriginsMaxLength) {
            return false;
        }
        // wildcard doesn't fit URL scheme
        if (val[i].indexOf('*') > -1) {
            continue;
        }
        pass = validator.isURL( val[i] );
        if (!pass) {
            return false;
        }
    }
    return true;

};
exports.originsArrayFormatValidator = originsArrayFormatValidator;
<commit_msg>NTFY-133 Fixed boolean validation for various browser inputs<commit_after>var validator = require('validator');
var config = require('./config');

/**
 * Shared validation functions for validating various fields.
 * These functions, being in a common library, may not be used
 * for project specific validations and techniques, such as using
 * the project database module to perform various lookups. Those
 * validation tasks are best left to a project specific validation module
 */
var spaceAndPeriodRegex = /^[A-Za-z0-9\.\s]*$/;
var spacePeriodAndUnderscoreRegex = /^[A-Za-z0-9_\.\s]*$/;
var usernameRegex = /^[A-Za-z0-9_@\.]*$/;    // ascii printable plus enough to enter email, and underscores
var passwordRegex = /^[A-Za-z0-9!@#%^&*_\s]*$/;    // A few more punctuation chars.

var firstLastNameRegex = /^[$!{}]/;
var spaceAndLimitedPunctuationRegex = /^[A-Za-z0-9\.\s,!#@$%^&*]*$/;
var serviceNameRegex = /^[A-Za-z0-9\.]*$/;
var spaceOnlyRegex = /^[A-Za-z0-9\s]*$/;

var PermissionStringLength = 100;
var DescriptionStringLength = 256;
var RealmMaxLength = 75;
var RealmMinLength = 2;
var RolesMaxLength = 75;
var OriginsMaxLength = 100;
var RolesMinLength = 75;
var PasswordMinLength = 8;
var PasswordMaxLength = 48;
var EmailMaxLength = 50;
var ServiceMaxLength = 50;

var NameMaxLength = 30;
var NameMinLength = 1;

/**
 * For example, min length 8, max length: 30, no punctuation other than the subrealm
 * separator '.' and '_' and ' '.
 * @param val The realm name to test
 * @return true if ok, false if failed
 */
var realmValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < RealmMinLength || val.length > RealmMaxLength) {
        return false;
    }
    return spacePeriodAndUnderscoreRegex.test(val);
};
exports.realmValidator = realmValidator;

// Username validator. Valid chars are ascii character ranges plus a few punctuation
// characters for email addresses as username.
var usernameValidator = function (val) {

    //In order to have modules respect the logging configuration supplied by the service, we
    //need to get the logger in a 'lazy' fashion.  If we get it during initialization, then
    //the logger instance only has the default configuration.
    var logger = require('./loggers').getLogger();

    if (typeof(val) !=='string') {
        logger.debug('Username invalid type');
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        logger.debug('Username invalid length');
        return false;
    }
    var result = usernameRegex.test(val);
    return result;
};
exports.usernameValidator = usernameValidator;

// First, last name validator
var nameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        return false;
    }
    // Allow all unicode chars for name fields.
    return !firstLastNameRegex.test(val);
};
exports.nameValidator = nameValidator;

// accountname validator.
var accountNameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < NameMinLength || val.length > NameMaxLength) {
        return false;
    }
    return spaceAndPeriodRegex.test(val);
};
exports.accountNameValidator = accountNameValidator;

// Account description validator
var descriptionValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > DescriptionStringLength) {
        return false;
    }
    return spaceAndLimitedPunctuationRegex.test(val);
};
exports.descriptionValidator = descriptionValidator;

var serviceNameValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > ServiceMaxLength) {
        return false;
    }
    return serviceNameRegex.test(val);
};
exports.serviceNameValidator = serviceNameValidator;

var serviceArrayValidator = function(val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    var service;
    for (var i = 0; i < val.length; i ++) {
        service = val[i];
        if (!serviceNameValidator(service)) {
            return false;
        }
    }
    return true;
}
exports.serviceArrayValidator = serviceArrayValidator;

var booleanValidator = function (val) {
    if (typeof(val)==='boolean') {
        if (true !== val && false !== val) {
            return false;
        }
        return true;
    } else if (typeof(val)==='string') {
        if ('true'!= val && 'false' != val){
            return false;
        }
        return true;
    }
    return false;
};
exports.booleanValidator = booleanValidator;

var passwordValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length < PasswordMinLength || val.length > PasswordMaxLength) {
        return false;
    }
    return passwordRegex.test(val);
};
exports.passwordValidator = passwordValidator;

var emailValidator = function (val) {
    if (typeof(val) !=='string') {
        return false;
    }
    if (val.length > EmailMaxLength) {
        return false;
    }
    return validator.isEmail(val);
};
exports.emailValidator = emailValidator;

var queryValidator = function (query) {
    // Todo
    return true;
};
exports.queryValidator = queryValidator;

/**
 * Check that the format of the permissions array is correct. This should be
 * done prior to doing the account type validation
 */
var permissionFormatValidator = function (val) {

    //In order to have modules respect the logging configuration supplied by the service, we
    //need to get the logger in a 'lazy' fashion.  If we get it during initialization, then
    //the logger instance only has the default configuration.
    var logger = require('./loggers').getLogger();

    if (Array.isArray(val) === false) {
        logger.debug('Permission set not an array: ' + typeof(val));
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (typeof(val[i]) !=='string') {
            logger.debug('Permission not a string: ' + typeof(val[i]));
            return false;
        }
        if (val[i].length > PermissionStringLength) {
            logger.debug('Invalid permission length: ' + val[i].length);
            return false;
        }
        if (!serviceNameRegex.test(val[i])) {
            logger.debug('Permission name invalid: ' + val[i]);
            return false;
        }
    }
    return true;
};
exports.permissionFormatValidator = permissionFormatValidator;

/**
 * Check that the format of the realm reference array is correct.
 * @param val An array of permission strings
 */
var realmReferenceFormatValidator = function (val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (typeof(val[i]) !=='string') {
            return false;
        }
        if (!val[i] || val[i].length > RealmMaxLength) {
            return false;
        }
        if (!spaceAndPeriodRegex.test(val[i])) {
            return false;
        }
    }
    return true;
};
exports.realmReferenceFormatValidator = realmReferenceFormatValidator;

/**
 * Check that the format of the permissions array is correct. This should be
 * done prior to doing the account type validation
 */
var rolesFormatValidator = function (val) {
    if (Array.isArray(val) === false) {
        return false;
    }
    for (var i = 0; i < val.length; i++) {
        if (!val[i] || val[i].length > RolesMaxLength) {
            return false;
        }
        if (!serviceNameRegex.test(val[i])) {
            return false;
        }
    }
    return true;
};
exports.rolesFormatValidator = rolesFormatValidator;

/**
 * Check that the format of the origins array is correct. This should be done as
 * part of the realm validation
 *
 * The origin array can contain a series of domains which need to be validated.
 *
 */
var originsArrayFormatValidator = function(val) {
    if (Array.isArray(val) == false) {
        var logger = require('./loggers').getLogger();
        logger.debug('Origins value is not array');
        return false;
    }
    var pass = true;
    var originField;
    for (var i = 0; i < val.length; i++) {
        if (typeof (val[i]) !== 'string' ) {
            return false;
        }
        if (val[i].length <= 0 || val[i].length > OriginsMaxLength) {
            return false;
        }
        // wildcard doesn't fit URL scheme
        if (val[i].indexOf('*') > -1) {
            continue;
        }
        pass = validator.isURL( val[i] );
        if (!pass) {
            return false;
        }
    }
    return true;

};
exports.originsArrayFormatValidator = originsArrayFormatValidator;
<|endoftext|>


<commit_before>/*
 * The MIT License
 *
 * Copyright 2014 Timo Behrmann, Guillaume Chauvet.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
var _ = require('lodash');
var assert = require('assert');
var utils = require('./utils');

var validators = module.exports._validators = require('./validators');
var validatorCodes = module.exports._validatorCodes = require('./validatorCodes');

var ignoredValidationKeys = module.exports._ignoredValidationKeys = ['msg', 'description', 'swaggerType'];
var validatorChainStore = module.exports._validationChainStore = {};

module.exports._generateValidationChain = function (validationRules) {
    // Reduces the array of validators into a new array with objects
    // with a validation method to call, the value to validate against
    // and the specified error message, if any
    var validationChain = _.reduce(validationRules, function (memo, validationRule) {
        _.each(_.difference(_.keys(validationRule), ignoredValidationKeys), function (validator) {
            if (_.has(validators, validator)) {
                var error = {
                    name: validator,
                    fn: validators[validator],
                    value: validationRule[validator],
                    msg: validationRule.msg
                };

                memo.push(error);
            }
        });
        return memo;
    }, []);

    return validationChain;
};

module.exports.getValidatorChain = function (key, validationRules, validationModel, scope, req, options, recentErrors) {
    var value = '['+scope+':'+key+']';
    if (req && req.route && req.route.name && _.has(validatorChainStore, req.route.name+value)) {
        return validatorChainStore[req.route.name+value];
    }

    // No array? Wrap it!
    if (!_.isArray(validationRules)) {
        validationRules = [validationRules];
    }

    var validationChain = this._generateValidationChain(validationRules);

    if (req && req.route && req.route.name) {
        validatorChainStore[req.route.name+value] = validationChain;
    }

    return validationChain;
};

module.exports.validateAttribute = function (key, validationRules, validationModel, scope, req, options, recentErrors) {
    var validatorChain = this.getValidatorChain(key, validationRules, validationModel, scope, req, options, recentErrors);
    var self = this;

    var submittedValue = req[scope] !== undefined ? req[scope][key] : undefined;
    var supportsMultipleValues = validationRules.multiple === true;
    var isArray = _.isArray(submittedValue);
    var doSingleCheck = !(isArray && supportsMultipleValues);
    var context = {
        req: req,
        scope: scope,
        validationModel: validationModel,
        validationRules: validationRules,
        options: options,
        recentErrors: recentErrors
    };
    // process the validatorChain and reduce it to the first error
    return _.reduce(validatorChain, function (memo, validator) {
        var result;

        if (doSingleCheck) {
            try {
                result = validator.fn.call(context, key, submittedValue, validator);
            }
            catch (err) {
                result = true;
            }
        } else if (!doSingleCheck) {
            var invalidValue = _.find(submittedValue, function(currentValue) {
                var returnVal;
                try {
                    returnVal = validator.fn.call(context, key, currentValue, validator);
                }
                catch (err) {
                    returnVal = true;
                }
                return returnVal;
            });

            if (!_.isUndefined(invalidValue)) {
                return true;
            }
        }

        if (result === false || memo === false) {
            return false;
        }

        if (result && !memo) {
            return self.createError(scope, key, validator);
        }

        return memo;
    }, '');
};

function _createError(scope, key, validator) {
    var error = {
        scope: utils.getInternalScope(scope),
        field: key,
        code: validatorCodes.codes[validator.name] || validatorCodes.codes._default
    };

    var message = validator.msg || validatorCodes.messages[validator.name] || validatorCodes.messages._default;

    if (message) {
        error.message = message;
    }

    return error;
};

module.exports.createError = _createError;

module.exports.process = function (validationModel, req, options) {
    assert.ok(validationModel, 'No validationModel present');

    var errors = options.errorsAsArray === false ? {} : [];
    var self = this;

    function addError(error, key) {
        if (error) {
            if (options.errorsAsArray === false) {
                errors[key] = error;
            } else {
                errors.push(error);
            }
        }
    };

    // fill missing fields with null
    _.each(validationModel, function (validationRulesScope, scope) {
        var realScope = utils.getExternalScope(scope);
        if(!realScope) {
            addError(_createError(scope, realScope, {msg: "Unvalid scope. Must be in [" + utils.getScopeKeys + "]."}), realScope);
        } else {
            var keys = req[realScope] ? ( typeof req[realScope] === 'object' ? Object.keys(req[realScope]) : [] ) : [];
            _.each(validationRulesScope, function (validationRules, key) {
                addError(self.validateAttribute(key, validationRules, validationModel, realScope, req, options, errors), key);
                var index = keys.indexOf(key);
                if (index > -1) {
                    keys.splice(index, 1);
                }
            });
	    if (options.forbidUndefinedVariables === true) {
	       keys.forEach(function(key) {
		    addError(_createError(realScope, key, { name: "undefinedVariable" }));
	      });
	    }
        }
    });
    return errors;
};
<commit_msg>Fix: Typo error<commit_after>/*
 * The MIT License
 *
 * Copyright 2014 Timo Behrmann, Guillaume Chauvet.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
var _ = require('lodash');
var assert = require('assert');
var utils = require('./utils');

var validators = module.exports._validators = require('./validators');
var validatorCodes = module.exports._validatorCodes = require('./validatorCodes');

var ignoredValidationKeys = module.exports._ignoredValidationKeys = ['msg', 'description', 'swaggerType'];
var validatorChainStore = module.exports._validationChainStore = {};

module.exports._generateValidationChain = function (validationRules) {
    // Reduces the array of validators into a new array with objects
    // with a validation method to call, the value to validate against
    // and the specified error message, if any
    var validationChain = _.reduce(validationRules, function (memo, validationRule) {
        _.each(_.difference(_.keys(validationRule), ignoredValidationKeys), function (validator) {
            if (_.has(validators, validator)) {
                var error = {
                    name: validator,
                    fn: validators[validator],
                    value: validationRule[validator],
                    msg: validationRule.msg
                };

                memo.push(error);
            }
        });
        return memo;
    }, []);

    return validationChain;
};

module.exports.getValidatorChain = function (key, validationRules, validationModel, scope, req, options, recentErrors) {
    var value = '['+scope+':'+key+']';
    if (req && req.route && req.route.name && _.has(validatorChainStore, req.route.name+value)) {
        return validatorChainStore[req.route.name+value];
    }

    // No array? Wrap it!
    if (!_.isArray(validationRules)) {
        validationRules = [validationRules];
    }

    var validationChain = this._generateValidationChain(validationRules);

    if (req && req.route && req.route.name) {
        validatorChainStore[req.route.name+value] = validationChain;
    }

    return validationChain;
};

module.exports.validateAttribute = function (key, validationRules, validationModel, scope, req, options, recentErrors) {
    var validatorChain = this.getValidatorChain(key, validationRules, validationModel, scope, req, options, recentErrors);
    var self = this;

    var submittedValue = req[scope] !== undefined ? req[scope][key] : undefined;
    var supportsMultipleValues = validationRules.multiple === true;
    var isArray = _.isArray(submittedValue);
    var doSingleCheck = !(isArray && supportsMultipleValues);
    var context = {
        req: req,
        scope: scope,
        validationModel: validationModel,
        validationRules: validationRules,
        options: options,
        recentErrors: recentErrors
    };
    // process the validatorChain and reduce it to the first error
    return _.reduce(validatorChain, function (memo, validator) {
        var result;

        if (doSingleCheck) {
            try {
                result = validator.fn.call(context, key, submittedValue, validator);
            }
            catch (err) {
                result = true;
            }
        } else if (!doSingleCheck) {
            var invalidValue = _.find(submittedValue, function(currentValue) {
                var returnVal;
                try {
                    returnVal = validator.fn.call(context, key, currentValue, validator);
                }
                catch (err) {
                    returnVal = true;
                }
                return returnVal;
            });

            if (!_.isUndefined(invalidValue)) {
                return true;
            }
        }

        if (result === false || memo === false) {
            return false;
        }

        if (result && !memo) {
            return self.createError(scope, key, validator);
        }

        return memo;
    }, '');
};

function _createError(scope, key, validator) {
    var error = {
        scope: utils.getInternalScope(scope),
        field: key,
        code: validatorCodes.codes[validator.name] || validatorCodes.codes._default
    };

    var message = validator.msg || validatorCodes.messages[validator.name] || validatorCodes.messages._default;

    if (message) {
        error.message = message;
    }

    return error;
};

module.exports.createError = _createError;

module.exports.process = function (validationModel, req, options) {
    assert.ok(validationModel, 'No validationModel present');

    var errors = options.errorsAsArray === false ? {} : [];
    var self = this;

    function addError(error, key) {
        if (error) {
            if (options.errorsAsArray === false) {
                errors[key] = error;
            } else {
                errors.push(error);
            }
        }
    };

    // fill missing fields with null
    _.each(validationModel, function (validationRulesScope, scope) {
        var realScope = utils.getExternalScope(scope);
        if(!realScope) {
            addError(_createError(scope, realScope, {msg: "Invalid scope. Must be in [" + utils.getScopeKeys + "]."}), realScope);
        } else {
            var keys = req[realScope] ? ( typeof req[realScope] === 'object' ? Object.keys(req[realScope]) : [] ) : [];
            _.each(validationRulesScope, function (validationRules, key) {
                addError(self.validateAttribute(key, validationRules, validationModel, realScope, req, options, errors), key);
                var index = keys.indexOf(key);
                if (index > -1) {
                    keys.splice(index, 1);
                }
            });
	    if (options.forbidUndefinedVariables === true) {
	       keys.forEach(function(key) {
		    addError(_createError(realScope, key, { name: "undefinedVariable" }));
	      });
	    }
        }
    });
    return errors;
};
<|endoftext|>


<commit_before>/**
 * Copyright 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */

$.register_module({
    name: 'og.common.util.ui.Form',
    dependencies: ['og.api.text'],
    obj: function () {
        var module = this, STALL = 500 /* 500ms */, api_text = og.api.text, numbers = {},
            has = 'hasOwnProperty', form_template = Handlebars.compile('<form action="." id="{{id}}">' +
                '
{{{html}}}<input type="submit" style="display: none;">
</form>');
        /** @private */
        var delegator = function (event) {
            var form = this, $target = $(event.target), results = [];
            form.dom_events[event.type].forEach(function (val) {
                if (!$target.is(val.selector) && !$target.parent(val.selector).length) return;
                var result = val.handler(event);
                results.push(typeof result === 'undefined' ? true : !!result);
            });
            if (results.length && !results.some(Boolean)) return false;
        };
        /** @private */
        var meta_build = function (input, type_map, find) {
            var result = {}, key, empty = '<EMPTY>', index = '<INDEX>',
                data = input.data, path = input.path, warns = input.warns, null_path = path === null, new_path;
            if ($.isArray(data)) return data.map(function (val, idx) {
                var value = meta_build({
                    data: val, path: null_path ? idx : [path, index].join('.'), warns: warns
                }, type_map, find);
                if ((value === Form.type.IND) && (val !== null)) value = Form.type.STR;
                return numbers[has](value) ? ((data[idx] = +data[idx]), value) : value;
            });
            if (data === null || typeof data !== 'object') // no empty string keys at root level
                return !(result = type_map[path] || find(path)) ? (warns.push(path), 'BADTYPE'): result;
            for (key in data) {
                new_path = null_path ? key.replace(/\./g, '') // if a key has dots in it, drop them, it is
                    : [path, key.replace(/\./g, '') || empty].join('.'); // a wildcard anyway
                result[key] = meta_build({data: data[key], path: new_path, warns: warns}, type_map, find);
                if (numbers[has](result[key])) {
                    if (typeof data[key] === 'number') continue;
                    if (data[key].length) data[key] = +data[key]; else delete data[key];
                }
                // INDs that are not null need to be re-typed as STRs
                if ((result[key] === Form.type.IND) && (data[key] !== null)) result[key] = Form.type.STR;
            }
            return result;
        };
        /** @private */
        var meta_find = function (memo, type_map) {
            var key, len;
            for (key in type_map) if (~key.indexOf('*')) memo.push({
                expr: new RegExp('^' + key.replace(/\./g, '\\.').replace(/\*/g, '[^\.]+') + '$'), value: type_map[key]
            });
            len = memo.length;
            return function (path) {
                for (var lcv = 0; lcv < len; lcv += 1) if (memo[lcv].expr.test(path)) return memo[lcv].value;
                return null
            };
        };
        /** @private */
        var submit_handler = function (form, extras) {
            var result = form.compile();
            result.extras = extras || {};
            try {
                og.common.events.fire.call(form, 'form:submit', result);
            } catch (error) {
                og.dev.warn(module.name + '#submit_handler a form:submit handler failed with:', error);
            }
        };
        /**
         * creates a Form instance
         * @name Form
         * @constructor
         * @param {Object} data optional map which is used to build the final compiled for results upon submit
         * @augments Block
         * @property {String} id autogenerated ID of form, useful for making child selectors
         */
        var Form = function (config) {
            var form = this;
            og.common.util.ui.Block.call(form, null, config); // assign a Block instance to this (form)
            /**
             * creates Block instance whose parent is current Form instance
             * @function
             * @name Form.prototype.Block
             */
            form.Block = og.common.util.ui.Block.partial(form);
            form.data = config.data || {};
            form.dom_events = {};
            form.id = og.common.id('form');
            form.parent = $(config.selector).unbind(); // no listeners on the selector
            form.root = null;
            /**
             * submits the form
             * @function
             * @name Form.prototype.submit
             * @param {Object} extras optional extraneous values that may be necessary upon submit (like as_new)
             * @type undefined
             */
            /** @ignore */
            form.submit = function (extras) {submit_handler(form, extras);}; // defined here so $ can't hijack this
        };
        Form.prototype = new og.common.util.ui.Block; // inherit Block prototype
        /**
         * turns contents of form into a data structure using field names and block processors
         * @function
         * @type Object
         * @returns {Object} a data structures with raw, data, errors, and meta
         * @throws {Error} if form field names do not correspond with data keys to drill down into
         */
        Form.prototype.compile = function () {
            var form = this, raw = form.root.serializeArray(), built_meta = null, meta_warns = [],
                data = $.extend(true, {}, form.data), errors = [], type_map = form.config.type_map;
            if (!form.meta_find && type_map) form.meta_find = meta_find([], type_map); // cache this function
            if (data) raw.forEach(function (value) {
                var hier = value.name.split('.'), last = hier.pop();
                try {
                    hier.reduce(function (acc, level) {
                        return acc[level] && typeof acc[level] === 'object' ? acc[level] : (acc[level] = {});
                    }, data)[last] = value.value;
                } catch (error) {
                    data = null;
                    error = new Error(module.name + '#compile: could not drill down to data.' + value.name);
                    og.common.events.fire.call(form, 'form:error', error);
                }
            });
            form.process(data, errors);
            if (type_map)
                built_meta = meta_build({data: data, path: null, warns: meta_warns}, type_map, form.meta_find);
            meta_warns = meta_warns.sort().reduce(function (acc, val) {
                return acc[acc.length - 1] !== val ? (acc.push(val), acc) : acc;
            }, []).join(', ');
            if (meta_warns.length) throw new Error(module.name + '#meta_build needs: ' + meta_warns);
            return {raw: raw, data: data, errors: errors, meta: built_meta};
        };
        /**
         * writes form and all of its children to the DOM
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.dom = function () {
            var form = this;
            return form.html(function (html) {
                form.parent.empty().append(form_template({id: form.id, html: html}));
                og.common.events.fire.call(form, 'form:load');
                (form.root = $('#' + form.id)).unbind().submit(function (event) {return submit_handler(form), false;});
            });
        };
        /**
         * removes an event listener
         * @param {String} type event type
         * @param {String} selector DOM selector for event
         * (optional, and only applicable for DOM events, not Form events)
         * @param {Function} handler event handler to remove (optional)
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.off = function (type) {
            var form = this.form || this, origin = this,
                selector = typeof arguments[1] === 'string' ? arguments[1] : null,
                handler = typeof arguments[1] === 'function' ? arguments[1] : arguments[2];
            if (0 === type.indexOf('form:')) return og.common.events.off.call(form, type, handler), origin;
            if (!form.dom_events[type]) return origin;
            form.dom_events[type] = form.dom_events[type].filter(function (val) {
                if (val.type !== type) return true;
                if (handler && selector) return val.handler !== handler && val.selector !== selector;
                if (handler) return val.handler !== handler;
                if (selector) return val.selector !== selector;
                return false;
            });
            if (form.dom_events[type].length) return origin;
            delete form.dom_events[type];
            form.root.off(type);
            return origin;
        };
        /**
         * adds an event listener, returns reference to current Form instance, in addition to supporting DOM events,
         * Form also has three custom events: "form:load", "form:submit", and "form:error"
         * @param {String} type event type
         * @param {String} selector DOM selector for event
         * (optional, and only applicable for DOM events, not Form events)
         * @param {Function} handler event handler to add (optional)
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.on = function (type) {
            var form = this.form || this, origin = this,
                selector = typeof arguments[1] === 'string' ? arguments[1] : null,
                handler = typeof arguments[1] === 'function' ? arguments[1] : arguments[2],
                context = typeof arguments[2] !== 'function' ? arguments[2] : arguments[3];
            if (0 === type.indexOf('form:')) {
                og.common.events.on.call(form, type, handler, context);
                return form.events[type][form.events[type].length - 1].origin = origin;
            }
            if (!selector) throw new TypeError(module.name + '#on: selector is not defined');
            if (form.dom_events[type])
                return form.dom_events[type].push({type: type, selector: selector, handler: handler}), origin;
            form.dom_events[type] = [{type: type, selector: selector, handler: handler}];
            form.parent.on(type, delegator.bind(form));
            return origin;
        };
        /**
         * collection of meta type information for creating metadata to describe config objects for REST API
         * @name Form.type
         */
        Form.type =  {BOO: 'boolean', BYT: 'byte', DBL: 'double', IND: 'indicator', SHR: 'short', STR: 'string'};
        ['BYT', 'DBL', 'SHR'].forEach(function (val, idx) {numbers[Form.type[val]] = null;});
        return Form;
    }
});<commit_msg>bugfix from changing og.common.events<commit_after>/**
 * Copyright 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */

$.register_module({
    name: 'og.common.util.ui.Form',
    dependencies: ['og.api.text'],
    obj: function () {
        var module = this, STALL = 500 /* 500ms */, api_text = og.api.text, numbers = {},
            has = 'hasOwnProperty', form_template = Handlebars.compile('<form action="." id="{{id}}">' +
                '
{{{html}}}<input type="submit" style="display: none;">
</form>');
        /** @private */
        var delegator = function (event) {
            var form = this, $target = $(event.target), results = [];
            form.dom_events[event.type].forEach(function (val) {
                if (!$target.is(val.selector) && !$target.parent(val.selector).length) return;
                var result = val.handler(event);
                results.push(typeof result === 'undefined' ? true : !!result);
            });
            if (results.length && !results.some(Boolean)) return false;
        };
        /** @private */
        var meta_build = function (input, type_map, find) {
            var result = {}, key, empty = '<EMPTY>', index = '<INDEX>',
                data = input.data, path = input.path, warns = input.warns, null_path = path === null, new_path;
            if ($.isArray(data)) return data.map(function (val, idx) {
                var value = meta_build({
                    data: val, path: null_path ? idx : [path, index].join('.'), warns: warns
                }, type_map, find);
                if ((value === Form.type.IND) && (val !== null)) value = Form.type.STR;
                return numbers[has](value) ? ((data[idx] = +data[idx]), value) : value;
            });
            if (data === null || typeof data !== 'object') // no empty string keys at root level
                return !(result = type_map[path] || find(path)) ? (warns.push(path), 'BADTYPE'): result;
            for (key in data) {
                new_path = null_path ? key.replace(/\./g, '') // if a key has dots in it, drop them, it is
                    : [path, key.replace(/\./g, '') || empty].join('.'); // a wildcard anyway
                result[key] = meta_build({data: data[key], path: new_path, warns: warns}, type_map, find);
                if (numbers[has](result[key])) {
                    if (typeof data[key] === 'number') continue;
                    if (data[key].length) data[key] = +data[key]; else delete data[key];
                }
                // INDs that are not null need to be re-typed as STRs
                if ((result[key] === Form.type.IND) && (data[key] !== null)) result[key] = Form.type.STR;
            }
            return result;
        };
        /** @private */
        var meta_find = function (memo, type_map) {
            var key, len;
            for (key in type_map) if (~key.indexOf('*')) memo.push({
                expr: new RegExp('^' + key.replace(/\./g, '\\.').replace(/\*/g, '[^\.]+') + '$'), value: type_map[key]
            });
            len = memo.length;
            return function (path) {
                for (var lcv = 0; lcv < len; lcv += 1) if (memo[lcv].expr.test(path)) return memo[lcv].value;
                return null
            };
        };
        /** @private */
        var submit_handler = function (form, extras) {
            var result = form.compile();
            result.extras = extras || {};
            try {
                og.common.events.fire.call(form, 'form:submit', result);
            } catch (error) {
                og.dev.warn(module.name + '#submit_handler a form:submit handler failed with:', error);
            }
        };
        /**
         * creates a Form instance
         * @name Form
         * @constructor
         * @param {Object} data optional map which is used to build the final compiled for results upon submit
         * @augments Block
         * @property {String} id autogenerated ID of form, useful for making child selectors
         */
        var Form = function (config) {
            var form = this;
            og.common.util.ui.Block.call(form, null, config); // assign a Block instance to this (form)
            /**
             * creates Block instance whose parent is current Form instance
             * @function
             * @name Form.prototype.Block
             */
            form.Block = og.common.util.ui.Block.partial(form);
            form.data = config.data || {};
            form.dom_events = {};
            form.id = og.common.id('form');
            form.parent = $(config.selector).unbind(); // no listeners on the selector
            form.root = null;
            /**
             * submits the form
             * @function
             * @name Form.prototype.submit
             * @param {Object} extras optional extraneous values that may be necessary upon submit (like as_new)
             * @type undefined
             */
            /** @ignore */
            form.submit = function (extras) {submit_handler(form, extras);}; // defined here so $ can't hijack this
        };
        Form.prototype = new og.common.util.ui.Block; // inherit Block prototype
        /**
         * turns contents of form into a data structure using field names and block processors
         * @function
         * @type Object
         * @returns {Object} a data structures with raw, data, errors, and meta
         * @throws {Error} if form field names do not correspond with data keys to drill down into
         */
        Form.prototype.compile = function () {
            var form = this, raw = form.root.serializeArray(), built_meta = null, meta_warns = [],
                data = $.extend(true, {}, form.data), errors = [], type_map = form.config.type_map;
            if (!form.meta_find && type_map) form.meta_find = meta_find([], type_map); // cache this function
            if (data) raw.forEach(function (value) {
                var hier = value.name.split('.'), last = hier.pop();
                try {
                    hier.reduce(function (acc, level) {
                        return acc[level] && typeof acc[level] === 'object' ? acc[level] : (acc[level] = {});
                    }, data)[last] = value.value;
                } catch (error) {
                    data = null;
                    error = new Error(module.name + '#compile: could not drill down to data.' + value.name);
                    og.common.events.fire.call(form, 'form:error', error);
                }
            });
            form.process(data, errors);
            if (type_map)
                built_meta = meta_build({data: data, path: null, warns: meta_warns}, type_map, form.meta_find);
            meta_warns = meta_warns.sort().reduce(function (acc, val) {
                return acc[acc.length - 1] !== val ? (acc.push(val), acc) : acc;
            }, []).join(', ');
            if (meta_warns.length) throw new Error(module.name + '#meta_build needs: ' + meta_warns);
            return {raw: raw, data: data, errors: errors, meta: built_meta};
        };
        /**
         * writes form and all of its children to the DOM
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.dom = function () {
            var form = this;
            return form.html(function (html) {
                form.parent.empty().append(form_template({id: form.id, html: html}));
                og.common.events.fire.call(form, 'form:load');
                (form.root = $('#' + form.id)).unbind().submit(function (event) {return submit_handler(form), false;});
            });
        };
        /**
         * removes an event listener
         * @param {String} type event type
         * @param {String} selector DOM selector for event
         * (optional, and only applicable for DOM events, not Form events)
         * @param {Function} handler event handler to remove (optional)
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.off = function (type) {
            var form = this.form || this, origin = this,
                selector = typeof arguments[1] === 'string' ? arguments[1] : null,
                handler = typeof arguments[1] === 'function' ? arguments[1] : arguments[2];
            if (0 === type.indexOf('form:')) return og.common.events.off.call(form, type, handler), origin;
            if (!form.dom_events[type]) return origin;
            form.dom_events[type] = form.dom_events[type].filter(function (val) {
                if (val.type !== type) return true;
                if (handler && selector) return val.handler !== handler && val.selector !== selector;
                if (handler) return val.handler !== handler;
                if (selector) return val.selector !== selector;
                return false;
            });
            if (form.dom_events[type].length) return origin;
            delete form.dom_events[type];
            form.root.off(type);
            return origin;
        };
        /**
         * adds an event listener, returns reference to current Form instance, in addition to supporting DOM events,
         * Form also has three custom events: "form:load", "form:submit", and "form:error"
         * @param {String} type event type
         * @param {String} selector DOM selector for event
         * (optional, and only applicable for DOM events, not Form events)
         * @param {Function} handler event handler to add (optional)
         * @type Form
         * @returns {Form} reference to current Form instance
         */
        Form.prototype.on = function (type) {
            var form = this.form || this, origin = this,
                selector = typeof arguments[1] === 'string' ? arguments[1] : null,
                handler = typeof arguments[1] === 'function' ? arguments[1] : arguments[2],
                context = typeof arguments[2] !== 'function' ? arguments[2] : arguments[3];
            if (0 === type.indexOf('form:')) {
                og.common.events.on.call(form, type, handler, context);
                return form['og.common.events'][type][form['og.common.events'][type].length - 1].origin = origin;
            }
            if (!selector) throw new TypeError(module.name + '#on: selector is not defined');
            if (form.dom_events[type])
                return form.dom_events[type].push({type: type, selector: selector, handler: handler}), origin;
            form.dom_events[type] = [{type: type, selector: selector, handler: handler}];
            form.parent.on(type, delegator.bind(form));
            return origin;
        };
        /**
         * collection of meta type information for creating metadata to describe config objects for REST API
         * @name Form.type
         */
        Form.type =  {BOO: 'boolean', BYT: 'byte', DBL: 'double', IND: 'indicator', SHR: 'short', STR: 'string'};
        ['BYT', 'DBL', 'SHR'].forEach(function (val, idx) {numbers[Form.type[val]] = null;});
        return Form;
    }
});<|endoftext|>


<commit_before>const request = require('request')

const TOKEN_ENDPOINT = 'https://tokens.indieauth.com/token'
const ME = 'https://bret.io/'

function micropub (event, context, cb) {
  const bearer = event.headers.authorization
  console.log('event.path: ' + event.path)
  console.log('event.httpMethod: ' + event.httpMethod)
  console.log('event.header: ' + event.header)
  console.log('event.queryStringParameters: ' + event.queryStringParameters)
  console.log('event.body: ' + event.body)
  console.log('event.isBase64Encoded: ' + event.isBase64Encoded)

  if (!bearer) return cb(null, { statusCode: 401, body: 'Missing bearer token' })

  request({
    url: TOKEN_ENDPOINT,
    headers: {
      'Authorization': bearer,
      Accept: 'application/json'
    }
  }, handleVerify)

  function handleVerify (err, resp, body) {
    if (err) {
      console.error(err)
      return cb(null, { statusCode: 500, body: 'Unknown error' })
    }

    console.log('Token endpoint: ' + resp.statusCode)

    let info
    try {
      info = JSON.parse(body)
    } catch (e) {
      console.error(e)
      return cb(null, { statusCode: 500, body: 'Token endpoint error' })
    }
    console.log(info)

    if (resp.statusCode !== 200) return cb(null, { statusCode: 401, body: 'Not authorized' })

    if (info.me !== ME) return cb(null, {statusCode: 401, 'body': 'Not authorized'})

    return processRequest(info)
  }

  function processRequest (info) {
    return cb(null, { statusCode: 200, 'body': 'Authorized!' })
  }
}

exports.handler = micropub
<commit_msg>Just log it all<commit_after>const request = require('request')

const TOKEN_ENDPOINT = 'https://tokens.indieauth.com/token'
const ME = 'https://bret.io/'

function micropub (event, context, cb) {
  const bearer = event.headers.authorization
  console.log('**********************NEW REQUEST*************************')
  console.log(event)

  if (!bearer) return cb(null, { statusCode: 401, body: 'Missing bearer token' })

  request({
    url: TOKEN_ENDPOINT,
    headers: {
      'Authorization': bearer,
      Accept: 'application/json'
    }
  }, handleVerify)

  function handleVerify (err, resp, body) {
    if (err) {
      console.error(err)
      return cb(null, { statusCode: 500, body: 'Unknown error' })
    }

    console.log('Token endpoint: ' + resp.statusCode)

    let info
    try {
      info = JSON.parse(body)
    } catch (e) {
      console.error(e)
      return cb(null, { statusCode: 500, body: 'Token endpoint error' })
    }
    console.log(info)

    if (resp.statusCode !== 200) return cb(null, { statusCode: 401, body: 'Not authorized' })

    if (info.me !== ME) return cb(null, {statusCode: 401, 'body': 'Not authorized'})

    return processRequest(info)
  }

  function processRequest (info) {
    return cb(null, { statusCode: 200, 'body': 'Authorized!' })
  }
}

exports.handler = micropub
<|endoftext|>