<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Touch events: touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight, scrollstart, scrollstop
//>>label: touch
//>>group: Events

define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");

(function( $, window, undefined ) {
	// add new event shortcuts
	$.each( ( "touchstart touchmove touchend " +
		"tap taphold " +
		"swipe swipeleft swiperight " +
		"scrollstart scrollstop" ).split( " " ), function( i, name ) {

		$.fn[ name ] = function( fn ) {
			return fn ? this.bind( name, fn ) : this.trigger( name );
		};

		// jQuery < 1.8
		if ( $.attrFn ) {
			$.attrFn[ name ] = true;
		}
	});

	var supportTouch = $.mobile.support.touch,
		scrollEvent = "touchmove scroll",
		touchStartEvent = supportTouch ? "touchstart" : "mousedown",
		touchStopEvent = supportTouch ? "touchend" : "mouseup",
		touchMoveEvent = supportTouch ? "touchmove" : "mousemove";

	function triggerCustomEvent( obj, eventType, event ) {
		var originalType = event.type;
		event.type = eventType;
		$.event.handle.call( obj, event );
		event.type = originalType;
	}

	// also handles scrollstop
	$.event.special.scrollstart = {

		enabled: true,

		setup: function() {

			var thisObject = this,
				$this = $( thisObject ),
				scrolling,
				timer;

			function trigger( event, state ) {
				scrolling = state;
				triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
			}

			// iPhone triggers scroll after a small delay; use touchmove instead
			$this.bind( scrollEvent, function( event ) {

				if ( !$.event.special.scrollstart.enabled ) {
					return;
				}

				if ( !scrolling ) {
					trigger( event, true );
				}

				clearTimeout( timer );
				timer = setTimeout( function() {
					trigger( event, false );
				}, 50 );
			});
		}
	};

	// also handles taphold
	$.event.special.tap = {
		tapholdThreshold: 750,

		setup: function() {
			var thisObject = this,
				$this = $( thisObject );

			$this.bind( "vmousedown", function( event ) {

				if ( event.which && event.which !== 1 ) {
					return false;
				}

				var origTarget = event.target,
					origEvent = event.originalEvent,
					timer;

				function clearTapTimer() {
					clearTimeout( timer );
				}

				function clearTapHandlers() {
					clearTapTimer();

					$this.unbind( "vclick", clickHandler )
						.unbind( "vmouseup", clearTapTimer );
					$( document ).unbind( "vmousecancel", clearTapHandlers );
				}

				function clickHandler( event ) {
					clearTapHandlers();

					// ONLY trigger a 'tap' event if the start target is
					// the same as the stop target.
					if ( origTarget === event.target ) {
						triggerCustomEvent( thisObject, "tap", event );
					}
				}

				$this.bind( "vmouseup", clearTapTimer )
					.bind( "vclick", clickHandler );
				$( document ).bind( "vmousecancel", clearTapHandlers );

				timer = setTimeout( function() {
					triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
				}, $.event.special.tap.tapholdThreshold );
			});
		}
	};

	// also handles swipeleft, swiperight
	$.event.special.swipe = {
		scrollSupressionThreshold: 30, // More than this horizontal displacement, and we will suppress scrolling.

		durationThreshold: 1000, // More time than this, and it isn't a swipe.

		horizontalDistanceThreshold: 30,  // Swipe horizontal displacement must be more than this.

		verticalDistanceThreshold: 75,  // Swipe vertical displacement must be less than this.

		start: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event;
			return {
						time: ( new Date() ).getTime(),
						coords: [ data.pageX, data.pageY ],
						origin: $( event.target )
					};
		},

		stop: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event;
			return {
						time: ( new Date() ).getTime(),
						coords: [ data.pageX, data.pageY ]
					};
		},

		handleSwipe: function( start, stop ) {
			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

				start.origin.trigger( "swipe" )
					.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
			}
		},

		setup: function() {
			var thisObject = this,
				$this = $( thisObject );

			$this.bind( touchStartEvent, function( event ) {
				var start = $.event.special.swipe.start( event ),
					stop;

				function moveHandler( event ) {
					if ( !start ) {
						return;
					}

					stop = $.event.special.swipe.stop( event );

					// prevent scrolling
					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
						event.preventDefault();
					}
				}

				$this.bind( touchMoveEvent, moveHandler )
					.one( touchStopEvent, function( event ) {
						$this.unbind( touchMoveEvent, moveHandler );

						if ( start && stop ) {
							$.event.special.swipe.handleSwipe( start, stop );
						}
						start = stop = undefined;
					});
			});
		}
	};
	$.each({
		scrollstop: "scrollstart",
		taphold: "tap",
		swipeleft: "swipe",
		swiperight: "swipe"
	}, function( event, sourceEvent ) {

		$.event.special[ event ] = {
			setup: function() {
				$( this ).bind( sourceEvent, $.noop );
			}
		};
	});

})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>swipe: remove unused variable<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Touch events: touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight, scrollstart, scrollstop
//>>label: touch
//>>group: Events

define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");

(function( $, window, undefined ) {
	// add new event shortcuts
	$.each( ( "touchstart touchmove touchend " +
		"tap taphold " +
		"swipe swipeleft swiperight " +
		"scrollstart scrollstop" ).split( " " ), function( i, name ) {

		$.fn[ name ] = function( fn ) {
			return fn ? this.bind( name, fn ) : this.trigger( name );
		};

		// jQuery < 1.8
		if ( $.attrFn ) {
			$.attrFn[ name ] = true;
		}
	});

	var supportTouch = $.mobile.support.touch,
		scrollEvent = "touchmove scroll",
		touchStartEvent = supportTouch ? "touchstart" : "mousedown",
		touchStopEvent = supportTouch ? "touchend" : "mouseup",
		touchMoveEvent = supportTouch ? "touchmove" : "mousemove";

	function triggerCustomEvent( obj, eventType, event ) {
		var originalType = event.type;
		event.type = eventType;
		$.event.handle.call( obj, event );
		event.type = originalType;
	}

	// also handles scrollstop
	$.event.special.scrollstart = {

		enabled: true,

		setup: function() {

			var thisObject = this,
				$this = $( thisObject ),
				scrolling,
				timer;

			function trigger( event, state ) {
				scrolling = state;
				triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
			}

			// iPhone triggers scroll after a small delay; use touchmove instead
			$this.bind( scrollEvent, function( event ) {

				if ( !$.event.special.scrollstart.enabled ) {
					return;
				}

				if ( !scrolling ) {
					trigger( event, true );
				}

				clearTimeout( timer );
				timer = setTimeout( function() {
					trigger( event, false );
				}, 50 );
			});
		}
	};

	// also handles taphold
	$.event.special.tap = {
		tapholdThreshold: 750,

		setup: function() {
			var thisObject = this,
				$this = $( thisObject );

			$this.bind( "vmousedown", function( event ) {

				if ( event.which && event.which !== 1 ) {
					return false;
				}

				var origTarget = event.target,
					origEvent = event.originalEvent,
					timer;

				function clearTapTimer() {
					clearTimeout( timer );
				}

				function clearTapHandlers() {
					clearTapTimer();

					$this.unbind( "vclick", clickHandler )
						.unbind( "vmouseup", clearTapTimer );
					$( document ).unbind( "vmousecancel", clearTapHandlers );
				}

				function clickHandler( event ) {
					clearTapHandlers();

					// ONLY trigger a 'tap' event if the start target is
					// the same as the stop target.
					if ( origTarget === event.target ) {
						triggerCustomEvent( thisObject, "tap", event );
					}
				}

				$this.bind( "vmouseup", clearTapTimer )
					.bind( "vclick", clickHandler );
				$( document ).bind( "vmousecancel", clearTapHandlers );

				timer = setTimeout( function() {
					triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
				}, $.event.special.tap.tapholdThreshold );
			});
		}
	};

	// also handles swipeleft, swiperight
	$.event.special.swipe = {
		scrollSupressionThreshold: 30, // More than this horizontal displacement, and we will suppress scrolling.

		durationThreshold: 1000, // More time than this, and it isn't a swipe.

		horizontalDistanceThreshold: 30,  // Swipe horizontal displacement must be more than this.

		verticalDistanceThreshold: 75,  // Swipe vertical displacement must be less than this.

		start: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event;
			return {
						time: ( new Date() ).getTime(),
						coords: [ data.pageX, data.pageY ],
						origin: $( event.target )
					};
		},

		stop: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event;
			return {
						time: ( new Date() ).getTime(),
						coords: [ data.pageX, data.pageY ]
					};
		},

		handleSwipe: function( start, stop ) {
			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {

				start.origin.trigger( "swipe" )
					.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
			}
		},

		setup: function() {
			var thisObject = this,
				$this = $( thisObject );

			$this.bind( touchStartEvent, function( event ) {
				var start = $.event.special.swipe.start( event ),
					stop;

				function moveHandler( event ) {
					if ( !start ) {
						return;
					}

					stop = $.event.special.swipe.stop( event );

					// prevent scrolling
					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
						event.preventDefault();
					}
				}

				$this.bind( touchMoveEvent, moveHandler )
					.one( touchStopEvent, function() {
						$this.unbind( touchMoveEvent, moveHandler );

						if ( start && stop ) {
							$.event.special.swipe.handleSwipe( start, stop );
						}
						start = stop = undefined;
					});
			});
		}
	};
	$.each({
		scrollstop: "scrollstart",
		taphold: "tap",
		swipeleft: "swipe",
		swiperight: "swipe"
	}, function( event, sourceEvent ) {

		$.event.special[ event ] = {
			setup: function() {
				$( this ).bind( sourceEvent, $.noop );
			}
		};
	});

})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>
function Grid(width, height)
{
  this.width = width;
  this.height = height;
  this.bombs = 0;
  this.flags = 0;

  this.cells = [];

  for (var x = 0; x < width; x++)
  {
    this.cells[x] = [];
    for (var y = 0; y < width; y++)
    {
      this.cells[x][y] = new Case(0,x,y);
    }
  }
}

Grid.prototype.isValidCoordinate = function (x, y)
{
  return x >= 0 && x < this.width && y >= 0 && y < this.height;
};

Grid.prototype.addBomb = function (x, y)
{
  this.cells[x][y].value = 'B';

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      if (!this.cells[x2][y2].isBomb())
      {
        this.cells[x2][y2].value++;
      }
    }
  }
};

Grid.prototype.addBombs = function (nbBombs)
{
  this.bombs = nbBombs;
  this.flags = nbBombs;

  for (var i = 0; i < nbBombs; i++)
  {
    var x = Math.floor((Math.random() * this.width));
    var y = Math.floor((Math.random() * this.height));

    while (this.cells[x][y].isBomb())
    {
      x = Math.floor((Math.random() * this.width));
      y = Math.floor((Math.random() * this.height));
    }

    this.addBomb(x, y);
  }
};

Grid.prototype.removeCases = function () {
  for (var x = 0; x < width; x++) {
    for (var y = 0; y < width; y++) {
      this.cells[x][y] = null;
    }
  }

};

Grid.prototype.reveal = function (x,y)
{
  if (this.cells[x][y].shown || this.cells[x][y].flagged)
  {
    return [];
  }

  this.cells[x][y].shown = true;

  if (this.cells[x][y].isBomb())
  {
    return false;
  }

  var listCaseChanged = [this.cells[x][y]];

  if (this.cells[x][y].value === 0)
  {
    for (var i = -1 ; i <= 1 ; i++)
    {
      for (var j = -1 ; j <= 1 ; j++)
      {
        var x2 = x + i;
        var y2 = y + j;

        if (!this.isValidCoordinate(x2, y2))
        {
          continue;
        }

        listCaseChanged = listCaseChanged.concat(this.reveal(x2, y2));
      }
    }
  }

  return listCaseChanged;
};

Grid.prototype.getNbFlagsAround = function (x, y)
{
  var nbFlagsAround = 0;

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      if (this.cells[x2][y2].flagged)
      {
        nbFlagsAround++;
      }
    }
  }

  return nbFlagsAround;
}

Grid.prototype.quickReveal = function (x, y)
{
  if (this.cells[x][y].isBomb())
  {
    return false;
  }

  if (this.getNbFlagsAround(x, y) != this.cells[x][y].value)
  {
      return [];
  }

  var listCaseChanged = [];

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      this.cells[x2][y3].shown = true;

      if (this.cells[x2][y3].isBomb())
      {
        return false;
      }

      listCaseChanged = listCaseChanged.concat(this.reveal(x2, y2));
    }
  }

  return listCaseChanged;
}
<commit_msg>fixes<commit_after>
function Grid(width, height)
{
  this.width = width;
  this.height = height;
  this.bombs = 0;
  this.flags = 0;

  this.cells = [];

  for (var x = 0; x < width; x++)
  {
    this.cells[x] = [];
    for (var y = 0; y < width; y++)
    {
      this.cells[x][y] = new Case(0,x,y);
    }
  }
}

Grid.prototype.isValidCoordinate = function (x, y)
{
  return x >= 0 && x < this.width && y >= 0 && y < this.height;
};

Grid.prototype.addBomb = function (x, y)
{
  this.cells[x][y].value = 'B';

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      if (!this.cells[x2][y2].isBomb())
      {
        this.cells[x2][y2].value++;
      }
    }
  }
};

Grid.prototype.addBombs = function (nbBombs)
{
  this.bombs = nbBombs;
  this.flags = nbBombs;

  for (var i = 0; i < nbBombs; i++)
  {
    var x = Math.floor((Math.random() * this.width));
    var y = Math.floor((Math.random() * this.height));

    while (this.cells[x][y].isBomb())
    {
      x = Math.floor((Math.random() * this.width));
      y = Math.floor((Math.random() * this.height));
    }

    this.addBomb(x, y);
  }
};

Grid.prototype.removeCases = function () {
  for (var x = 0; x < width; x++) {
    for (var y = 0; y < width; y++) {
      this.cells[x][y] = null;
    }
  }

};

Grid.prototype.reveal = function (x,y)
{
  if (this.cells[x][y].shown || this.cells[x][y].flagged)
  {
    return [];
  }

  this.cells[x][y].shown = true;

  if (this.cells[x][y].isBomb())
  {
    return false;
  }

  var listCaseChanged = [this.cells[x][y]];

  if (this.cells[x][y].value === 0)
  {
    for (var i = -1 ; i <= 1 ; i++)
    {
      for (var j = -1 ; j <= 1 ; j++)
      {
        var x2 = x + i;
        var y2 = y + j;

        if (!this.isValidCoordinate(x2, y2))
        {
          continue;
        }

        listCaseChanged = listCaseChanged.concat(this.reveal(x2, y2));
      }
    }
  }

  return listCaseChanged;
};

Grid.prototype.getNbFlagsAround = function (x, y)
{
  var nbFlagsAround = 0;

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      if (this.cells[x2][y2].flagged)
      {
        nbFlagsAround++;
      }
    }
  }

  return nbFlagsAround;
}

Grid.prototype.quickReveal = function (x, y)
{
  if (this.cells[x][y].isBomb())
  {
    return false;
  }

  if (this.getNbFlagsAround(x, y) != this.cells[x][y].value)
  {
      return [];
  }

  var listCaseChanged = [];

  for (var i = -1 ; i <= 1 ; i++)
  {
    for (var j = -1 ; j <= 1 ; j++)
    {
      var x2 = x + i;
      var y2 = y + j;

      if (!this.isValidCoordinate(x2, y2))
      {
        continue;
      }

      this.cells[x2][y3].shown = true;

      if (this.cells[x2][y3].isBomb())
      {
        return false;
      }

      listCaseChanged = listCaseChanged.concat(this.reveal(x2, y2));
    }
  }

  return listCaseChanged;
}
<|endoftext|>


<commit_before>/**
 * @author Pedro Sanders
 * @since v1
 */
import RegisterHandler from 'core/processor/register_handler'
import CancelHandler from 'core/processor/cancel_handler'
import RouteInfo from 'core/processor/route_info'
import Context from 'core/context'
import AclUtil from 'core/acl/acl_util'
import getConfig from 'core/config_util'
import { Status } from 'location/status'
import { RoutingType } from 'core/routing_type'
import isEmpty from 'utils/obj_util'
import IPUtil from 'core/ip_util'

const SipFactory = Packages.javax.sip.SipFactory
const RouteHeader = Packages.javax.sip.header.RouteHeader
const ToHeader = Packages.javax.sip.header.ToHeader
const FromHeader = Packages.javax.sip.header.FromHeader
const ContactHeader = Packages.javax.sip.header.ContactHeader
const ViaHeader = Packages.javax.sip.header.ViaHeader
const MaxForwardsHeader = Packages.javax.sip.header.MaxForwardsHeader
const ProxyAuthorizationHeader = Packages.javax.sip.header.ProxyAuthorizationHeader
const Request = Packages.javax.sip.message.Request
const Response = Packages.javax.sip.message.Response
const HashMap = Packages.java.util.HashMap
const LogManager = Packages.org.apache.logging.log4j.LogManager
const LOG = LogManager.getLogger()

export default class RequestProcessor {

    constructor(sipProvider, locator, registry, registrar, dataAPIs, contextStorage) {
        this.sipProvider = sipProvider
        this.sipStack = this.sipProvider.getSipStack()
        this.contextStorage = contextStorage
        this.locator = locator
        this.registry = registry
        this.dataAPIs = dataAPIs
        this.domainsAPI = dataAPIs.DomainsAPI
        this.peersAPI = dataAPIs.PeersAPI
        this.agentsAPI = dataAPIs.AgentsAPI
        this.didsAPI = dataAPIs.DIDsAPI
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.dsam = new Packages.gov.nist.javax.sip.clientauthutils.DigestServerAuthenticationHelper()
        this.config = getConfig()
        this.generalAcl = this.config.spec.accessControlList
        this.registerHandler = new RegisterHandler(locator, registrar)
        this.cancelHandler = new CancelHandler(sipProvider, contextStorage)
        this.ipUtil = new IPUtil()
    }

    process(event) {
        const requestIn = event.getRequest()
        const method = requestIn.getMethod()
        let serverTransaction = event.getServerTransaction()

        // ACK does not need a transaction
        if (serverTransaction == null && !method.equals(Request.ACK)) {
            serverTransaction = this.sipProvider.getNewServerTransaction(requestIn)
        }

        const requestOut = requestIn.clone()

        if (method.equals(Request.REGISTER)) {
            // Should we apply ACL rules here too?
            this.registerHandler.register(requestIn, serverTransaction)
            return
        } else if(method.equals(Request.CANCEL)) {
            this.cancelHandler.cancel(requestIn, serverTransaction)
            return
        } else {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const fromURI = fromHeader.getAddress().getURI()
            const remoteIp = event.getRemoteIpAddress()
            const routeInfo = new RouteInfo(requestIn, this.dataAPIs)

            LOG.debug('routing type -> ' + routeInfo.getRoutingType())

            // 1. Security check
            // This routing type is not yet supported
            if (routeInfo.getRoutingType().equals(RoutingType.INTER_DOMAIN_ROUTING)) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.FORBIDDEN, requestIn))
                LOG.debug(requestIn)
                return
            }

            // Other routing types are assume to be already login(registered)
            /*if (!routeInfo.getRoutingType().equals(RoutingType.DOMAIN_INGRESS_ROUTING)) {
                // Do not need to authorized ACK or BYE messages...
                if (!method.equals(Request.ACK)
                    && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'UNAUTHORIZED') {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                } else if (!method.equals(Request.ACK) && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'SENT_CHALLENGE') {
                    LOG.debug(requestIn)
                    return
                }
            } else {
                if (!this.registry.hasIp(remoteIp)) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                }
            }*/

            let addressOfRecord = this.getAOR(requestIn)

            // We only apply ACL rules to Domain Routing.
            if (routeInfo.getRoutingType().equals(RoutingType.INTRA_DOMAIN_ROUTING)) {
                const result = this.domainsAPI.getDomain(addressOfRecord.getHost())
                if (result.status == Status.OK) {
                    const domainObj = result.obj
                    if(!new AclUtil(this.generalAcl).isIpAllowed(domainObj, remoteIp)) {
                        serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                        LOG.debug(requestIn)
                        return
                    }
                }
            }

            // 2. Decrement the max forwards value
            const maxForwardsHeader = requestOut.getHeader(MaxForwardsHeader.NAME)
            maxForwardsHeader.decrementMaxForwards()

            // 3. Determine route
            // 3.0 Peer Egress Routing (PR)
            if (routeInfo.getRoutingType().equals(RoutingType.PEER_EGRESS_ROUTING)) {
                let telUrl

                // First look for the header 'DIDRef'
                if (requestOut.getHeader('DIDRef')) {
                    telUrl = this.addressFactory.createTelURL(requestOut.getHeader('DIDRef'))
                } else {
                    telUrl = this.addressFactory.createTelURL(fromURI.getUser())
                }

                let result = this.didsAPI.getDIDByTelUrl(telUrl)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                const didRef = result.obj.metadata.ref
                result = this.locator.getEgressRouteForPeer(addressOfRecord, didRef)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                this.processRoute(requestIn, requestOut, result.obj, serverTransaction, routeInfo)

                LOG.debug(requestOut)
                return
            }

            // 3.1 Intra-Domain Routing(IDR), Domain Ingress Routing (DIR), & Domain Egress Routing (DER)
            const result = this.locator.findEndpoint(addressOfRecord)

            if (result.status == Status.NOT_FOUND) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                LOG.debug(requestIn)
                return
            }

            // 4. Send response
            const location = result.obj

            if (location instanceof HashMap) {
                let caIterator

                try {
                    caIterator = location.values().iterator()
                } catch(e) {}

                if (!caIterator.hasNext()) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                // Fork the call if needed
                while(caIterator.hasNext()) {
                    const route = caIterator.next()
                    this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
                }
            } else {
                const route = location
                this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
            }

            return
        }
        LOG.debug(requestIn)
    }

    processRoute(requestIn, requestOut, route, serverTransaction, routeInfo) {
        requestOut.setRequestURI(route.contactURI)
        const routeHeader = requestIn.getHeader(RouteHeader.NAME)
        const rVia = requestIn.getHeader(ViaHeader.NAME)
        const transport = rVia.getTransport().toLowerCase()
        const lp = this.sipProvider.getListeningPoint(transport)
        const localPort = lp.getPort()
        const localIp = lp.getIPAddress().toString()
        const method = requestIn.getMethod()
        const rcvHost = route.contactURI.getHost()

        LOG.debug('route is -> ' + JSON.stringify(route))

        let advertisedAddr
        let advertisedPort

        // No egress routing has sentByAddress. They are assume to be entities outside the local network.
        if (this.config.spec.externAddr && (route.sentByAddress == undefined || !this.ipUtil.isLocalnet(route.sentByAddress))) {
            advertisedAddr = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[0] : this.config.spec.externAddr
            advertisedPort = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[1] : localPort
        }  else {
            advertisedAddr = localIp
            advertisedPort = localPort
        }

        LOG.debug('advertisedAddr is -> ' + advertisedAddr)
        LOG.debug('advertisedPort is -> ' + advertisedPort)

        // Remove route header if host's address is the same as the proxy's address
        if (routeHeader) {
            const h = routeHeader.getAddress().getURI().getHost()
            const routeHost = this.ipUtil.isIp(h)? h : Packages.java.net.InetAddress.getByName(h).getHostAddress()
            const routePort = routeHeader.getAddress().getURI().getPort()
            if ((routeHost.equals(localIp) && routePort.equals(localPort))
                || ((routeHost.equals(advertisedAddr) && routePort.equals(advertisedPort)))) {
                requestOut.removeFirst(RouteHeader.NAME)
            }
        }

        // Stay in the signaling path
        if (this.config.spec.recordRoute) {
            const proxyURI = this.addressFactory.createSipURI(null, advertisedAddr)
            proxyURI.setLrParam()
            proxyURI.setPort(advertisedPort)
            const proxyAddress = this.addressFactory.createAddress(proxyURI)
            const recordRouteHeader = this.headerFactory.createRecordRouteHeader(proxyAddress)
            requestOut.addHeader(recordRouteHeader)
        }

        // Request RPort to enable Symmetric Response in accordance with RFC 3581 and RFC 6314
        const viaHeader = this.headerFactory.createViaHeader(advertisedAddr, advertisedPort, transport, null)
        viaHeader.setRPort()
        requestOut.addFirst(viaHeader)

        if (route.thruGw) {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const toHeader = requestIn.getHeader(ToHeader.NAME)
            const gwRefHeader = this.headerFactory.createHeader('X-Gateway-Ref', route.gwRef)
            const remotePartyIdHeader = this.headerFactory
                .createHeader('Remote-Party-ID', '<sip:'+ route.did + '@' + route.gwHost+ '>;screen=yes;party=calling')

            const from = 'sip:' + route.gwUsername + '@' + route.gwHost
            const to = 'sip:' + toHeader.getAddress().toString().match('sips?:(.*)@(.*)')[1] + '@' + route.gwHost

            // This might not work with all provider
            const fromAddress = this.addressFactory.createAddress(from)
            const toAddress = this.addressFactory.createAddress(to)
            fromHeader.setAddress(fromAddress)
            toHeader.setAddress(toAddress)
            requestOut.setHeader(fromHeader)
            requestOut.setHeader(toHeader)

            requestOut.setHeader(gwRefHeader)
            requestOut.setHeader(remotePartyIdHeader)
        }

        requestOut.removeHeader("Proxy-Authorization")

        // Does not need a transaction
        if(method.equals(Request.ACK)) {
            this.sipProvider.sendRequest(requestOut)
        } else {
            try {
                // The request must be cloned or the stack will not fork the call
                const clientTransaction = this.sipProvider.getNewClientTransaction(requestOut.clone())
                clientTransaction.sendRequest()

                // Transaction context
                const context = new Context()
                context.clientTransaction = clientTransaction
                context.serverTransaction = serverTransaction
                context.method = method
                context.requestIn = requestIn
                context.requestOut = requestOut
                this.contextStorage.saveContext(context)
            } catch (e) {
                if (e instanceof java.net.ConnectException) {
                    LOG.error('Connection refused. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/ConnectException.html')
                } else if (e instanceof java.net.NoRouteToHostException) {
                    LOG.error('No route to host. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/NoRouteToHostException.html')
                } else {
                    LOG.error(e.getMessage())
                }
            }
        }

        LOG.debug(requestOut)
    }

    authorized(request, serverTransaction) {
        const authHeader = request.getHeader(ProxyAuthorizationHeader.NAME)
        const fromHeader = request.getHeader(FromHeader.NAME)
        const fromURI = fromHeader.getAddress().getURI()

        // WARNING: Should limit the amount of attempts...
        if (authHeader == null) {
            const challengeResponse = this.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED, request)
            this.dsam.generateChallenge(this.headerFactory, challengeResponse, fromURI.getHost())
            serverTransaction.sendResponse(challengeResponse)
            LOG.debug(request)
            return 'SENT_CHALLENGE'
        }

        // WARNING: If they are multiple peers with the same name this might be an issue
        let result = this.peersAPI.getPeer(authHeader.getUsername())

        let user

        if (result.status == Status.OK) {
            user = result.obj
        } else {
            // This is also a security check. The user in the authentication must exist for the 'fromURI.getHost()' domain
            result = this.agentsAPI.getAgent(fromURI.getHost(), authHeader.getUsername())
            if (result.status == Status.OK ) {
                user = result.obj
            }
        }

        if (!user || !this.dsam.doAuthenticatePlainTextPassword(request, user.spec.credentials.secret)) {
            return 'UNAUTHORIZED'
        }

        return 'AUTHORIZED'
    }

    /**
     * Discover DIDs sent via a non-standard header
     * The header must be added at config.spec.addressInfo[*]
     * If the such header is present then overwrite the AOR
     */
    getAOR (request) {
        for (let x in this.config.spec.addressInfo) {
            let info = this.config.spec.addressInfo[x]
            if (!!request.getHeader(info)) {
                let v = request.getHeader(info).getValue()
                if (/sips?:.*@.*/.test(v) || /tel:\d+/.test(v)) {
                    return this.addressFactory.createURI(v)
                }
                LOG.error('Invalid address: ' + v)
            }
        }
        return request.getHeader(ToHeader.NAME).getAddress().getURI()
    }
}
<commit_msg>Now advertising external address(if defined) for all devices ending on .invalid<commit_after>/**
 * @author Pedro Sanders
 * @since v1
 */
import RegisterHandler from 'core/processor/register_handler'
import CancelHandler from 'core/processor/cancel_handler'
import RouteInfo from 'core/processor/route_info'
import Context from 'core/context'
import AclUtil from 'core/acl/acl_util'
import getConfig from 'core/config_util'
import { Status } from 'location/status'
import { RoutingType } from 'core/routing_type'
import isEmpty from 'utils/obj_util'
import IPUtil from 'core/ip_util'

const SipFactory = Packages.javax.sip.SipFactory
const RouteHeader = Packages.javax.sip.header.RouteHeader
const ToHeader = Packages.javax.sip.header.ToHeader
const FromHeader = Packages.javax.sip.header.FromHeader
const ContactHeader = Packages.javax.sip.header.ContactHeader
const ViaHeader = Packages.javax.sip.header.ViaHeader
const MaxForwardsHeader = Packages.javax.sip.header.MaxForwardsHeader
const ProxyAuthorizationHeader = Packages.javax.sip.header.ProxyAuthorizationHeader
const Request = Packages.javax.sip.message.Request
const Response = Packages.javax.sip.message.Response
const HashMap = Packages.java.util.HashMap
const LogManager = Packages.org.apache.logging.log4j.LogManager
const LOG = LogManager.getLogger()

export default class RequestProcessor {

    constructor(sipProvider, locator, registry, registrar, dataAPIs, contextStorage) {
        this.sipProvider = sipProvider
        this.sipStack = this.sipProvider.getSipStack()
        this.contextStorage = contextStorage
        this.locator = locator
        this.registry = registry
        this.dataAPIs = dataAPIs
        this.domainsAPI = dataAPIs.DomainsAPI
        this.peersAPI = dataAPIs.PeersAPI
        this.agentsAPI = dataAPIs.AgentsAPI
        this.didsAPI = dataAPIs.DIDsAPI
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.dsam = new Packages.gov.nist.javax.sip.clientauthutils.DigestServerAuthenticationHelper()
        this.config = getConfig()
        this.generalAcl = this.config.spec.accessControlList
        this.registerHandler = new RegisterHandler(locator, registrar)
        this.cancelHandler = new CancelHandler(sipProvider, contextStorage)
        this.ipUtil = new IPUtil()
    }

    process(event) {
        const requestIn = event.getRequest()
        const method = requestIn.getMethod()
        let serverTransaction = event.getServerTransaction()

        // ACK does not need a transaction
        if (serverTransaction == null && !method.equals(Request.ACK)) {
            serverTransaction = this.sipProvider.getNewServerTransaction(requestIn)
        }

        const requestOut = requestIn.clone()

        if (method.equals(Request.REGISTER)) {
            // Should we apply ACL rules here too?
            this.registerHandler.register(requestIn, serverTransaction)
            return
        } else if(method.equals(Request.CANCEL)) {
            this.cancelHandler.cancel(requestIn, serverTransaction)
            return
        } else {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const fromURI = fromHeader.getAddress().getURI()
            const remoteIp = event.getRemoteIpAddress()
            const routeInfo = new RouteInfo(requestIn, this.dataAPIs)

            LOG.debug('routing type -> ' + routeInfo.getRoutingType())

            // 1. Security check
            // This routing type is not yet supported
            if (routeInfo.getRoutingType().equals(RoutingType.INTER_DOMAIN_ROUTING)) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.FORBIDDEN, requestIn))
                LOG.debug(requestIn)
                return
            }

            // Other routing types are assume to be already login(registered)
            /*if (!routeInfo.getRoutingType().equals(RoutingType.DOMAIN_INGRESS_ROUTING)) {
                // Do not need to authorized ACK or BYE messages...
                if (!method.equals(Request.ACK)
                    && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'UNAUTHORIZED') {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                } else if (!method.equals(Request.ACK) && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'SENT_CHALLENGE') {
                    LOG.debug(requestIn)
                    return
                }
            } else {
                if (!this.registry.hasIp(remoteIp)) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                }
            }*/

            let addressOfRecord = this.getAOR(requestIn)

            // We only apply ACL rules to Domain Routing.
            if (routeInfo.getRoutingType().equals(RoutingType.INTRA_DOMAIN_ROUTING)) {
                const result = this.domainsAPI.getDomain(addressOfRecord.getHost())
                if (result.status == Status.OK) {
                    const domainObj = result.obj
                    if(!new AclUtil(this.generalAcl).isIpAllowed(domainObj, remoteIp)) {
                        serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                        LOG.debug(requestIn)
                        return
                    }
                }
            }

            // 2. Decrement the max forwards value
            const maxForwardsHeader = requestOut.getHeader(MaxForwardsHeader.NAME)
            maxForwardsHeader.decrementMaxForwards()

            // 3. Determine route
            // 3.0 Peer Egress Routing (PR)
            if (routeInfo.getRoutingType().equals(RoutingType.PEER_EGRESS_ROUTING)) {
                let telUrl

                // First look for the header 'DIDRef'
                if (requestOut.getHeader('DIDRef')) {
                    telUrl = this.addressFactory.createTelURL(requestOut.getHeader('DIDRef'))
                } else {
                    telUrl = this.addressFactory.createTelURL(fromURI.getUser())
                }

                let result = this.didsAPI.getDIDByTelUrl(telUrl)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                const didRef = result.obj.metadata.ref
                result = this.locator.getEgressRouteForPeer(addressOfRecord, didRef)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                this.processRoute(requestIn, requestOut, result.obj, serverTransaction, routeInfo)

                LOG.debug(requestOut)
                return
            }

            // 3.1 Intra-Domain Routing(IDR), Domain Ingress Routing (DIR), & Domain Egress Routing (DER)
            const result = this.locator.findEndpoint(addressOfRecord)

            if (result.status == Status.NOT_FOUND) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                LOG.debug(requestIn)
                return
            }

            // 4. Send response
            const location = result.obj

            if (location instanceof HashMap) {
                let caIterator

                try {
                    caIterator = location.values().iterator()
                } catch(e) {}

                if (!caIterator.hasNext()) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                // Fork the call if needed
                while(caIterator.hasNext()) {
                    const route = caIterator.next()
                    this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
                }
            } else {
                const route = location
                this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
            }

            return
        }
        LOG.debug(requestIn)
    }

    processRoute(requestIn, requestOut, route, serverTransaction, routeInfo) {
        requestOut.setRequestURI(route.contactURI)
        const routeHeader = requestIn.getHeader(RouteHeader.NAME)
        const rVia = requestIn.getHeader(ViaHeader.NAME)
        const transport = rVia.getTransport().toLowerCase()
        const lp = this.sipProvider.getListeningPoint(transport)
        const localPort = lp.getPort()
        const localIp = lp.getIPAddress().toString()
        const method = requestIn.getMethod()
        const rcvHost = route.contactURI.getHost()

        LOG.debug('route is -> ' + JSON.stringify(route))

        let advertisedAddr
        let advertisedPort

        // No egress routing has sentByAddress. They are assume to be entities outside the local network.
        if (this.config.spec.externAddr && (route.sentByAddress == undefined
            || route.sentByAddress.endsWith(".invalid")
            || !this.ipUtil.isLocalnet(route.sentByAddress))) {
            advertisedAddr = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[0] : this.config.spec.externAddr
            advertisedPort = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[1] : localPort
        }  else {
            advertisedAddr = localIp
            advertisedPort = localPort
        }

        LOG.debug('advertisedAddr is -> ' + advertisedAddr)
        LOG.debug('advertisedPort is -> ' + advertisedPort)

        // Remove route header if host's address is the same as the proxy's address
        if (routeHeader) {
            const h = routeHeader.getAddress().getURI().getHost()
            const routeHost = this.ipUtil.isIp(h)? h : Packages.java.net.InetAddress.getByName(h).getHostAddress()
            const routePort = routeHeader.getAddress().getURI().getPort()
            if ((routeHost.equals(localIp) && routePort.equals(localPort))
                || ((routeHost.equals(advertisedAddr) && routePort.equals(advertisedPort)))) {
                requestOut.removeFirst(RouteHeader.NAME)
            }
        }

        // Stay in the signaling path
        if (this.config.spec.recordRoute) {
            const proxyURI = this.addressFactory.createSipURI(null, advertisedAddr)
            proxyURI.setLrParam()
            proxyURI.setPort(advertisedPort)
            const proxyAddress = this.addressFactory.createAddress(proxyURI)
            const recordRouteHeader = this.headerFactory.createRecordRouteHeader(proxyAddress)
            requestOut.addHeader(recordRouteHeader)
        }

        // Request RPort to enable Symmetric Response in accordance with RFC 3581 and RFC 6314
        const viaHeader = this.headerFactory.createViaHeader(advertisedAddr, advertisedPort, transport, null)
        viaHeader.setRPort()
        requestOut.addFirst(viaHeader)

        if (route.thruGw) {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const toHeader = requestIn.getHeader(ToHeader.NAME)
            const gwRefHeader = this.headerFactory.createHeader('X-Gateway-Ref', route.gwRef)
            const remotePartyIdHeader = this.headerFactory
                .createHeader('Remote-Party-ID', '<sip:'+ route.did + '@' + route.gwHost+ '>;screen=yes;party=calling')

            const from = 'sip:' + route.gwUsername + '@' + route.gwHost
            const to = 'sip:' + toHeader.getAddress().toString().match('sips?:(.*)@(.*)')[1] + '@' + route.gwHost

            // This might not work with all provider
            const fromAddress = this.addressFactory.createAddress(from)
            const toAddress = this.addressFactory.createAddress(to)
            fromHeader.setAddress(fromAddress)
            toHeader.setAddress(toAddress)
            requestOut.setHeader(fromHeader)
            requestOut.setHeader(toHeader)

            requestOut.setHeader(gwRefHeader)
            requestOut.setHeader(remotePartyIdHeader)
        }

        requestOut.removeHeader("Proxy-Authorization")

        // Does not need a transaction
        if(method.equals(Request.ACK)) {
            this.sipProvider.sendRequest(requestOut)
        } else {
            try {
                // The request must be cloned or the stack will not fork the call
                const clientTransaction = this.sipProvider.getNewClientTransaction(requestOut.clone())
                clientTransaction.sendRequest()

                // Transaction context
                const context = new Context()
                context.clientTransaction = clientTransaction
                context.serverTransaction = serverTransaction
                context.method = method
                context.requestIn = requestIn
                context.requestOut = requestOut
                this.contextStorage.saveContext(context)
            } catch (e) {
                if (e instanceof java.net.ConnectException) {
                    LOG.error('Connection refused. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/ConnectException.html')
                } else if (e instanceof java.net.NoRouteToHostException) {
                    LOG.error('No route to host. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/NoRouteToHostException.html')
                } else {
                    LOG.error(e.getMessage())
                }
            }
        }

        LOG.debug(requestOut)
    }

    authorized(request, serverTransaction) {
        const authHeader = request.getHeader(ProxyAuthorizationHeader.NAME)
        const fromHeader = request.getHeader(FromHeader.NAME)
        const fromURI = fromHeader.getAddress().getURI()

        // WARNING: Should limit the amount of attempts...
        if (authHeader == null) {
            const challengeResponse = this.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED, request)
            this.dsam.generateChallenge(this.headerFactory, challengeResponse, fromURI.getHost())
            serverTransaction.sendResponse(challengeResponse)
            LOG.debug(request)
            return 'SENT_CHALLENGE'
        }

        // WARNING: If they are multiple peers with the same name this might be an issue
        let result = this.peersAPI.getPeer(authHeader.getUsername())

        let user

        if (result.status == Status.OK) {
            user = result.obj
        } else {
            // This is also a security check. The user in the authentication must exist for the 'fromURI.getHost()' domain
            result = this.agentsAPI.getAgent(fromURI.getHost(), authHeader.getUsername())
            if (result.status == Status.OK ) {
                user = result.obj
            }
        }

        if (!user || !this.dsam.doAuthenticatePlainTextPassword(request, user.spec.credentials.secret)) {
            return 'UNAUTHORIZED'
        }

        return 'AUTHORIZED'
    }

    /**
     * Discover DIDs sent via a non-standard header
     * The header must be added at config.spec.addressInfo[*]
     * If the such header is present then overwrite the AOR
     */
    getAOR (request) {
        for (let x in this.config.spec.addressInfo) {
            let info = this.config.spec.addressInfo[x]
            if (!!request.getHeader(info)) {
                let v = request.getHeader(info).getValue()
                if (/sips?:.*@.*/.test(v) || /tel:\d+/.test(v)) {
                    return this.addressFactory.createURI(v)
                }
                LOG.error('Invalid address: ' + v)
            }
        }
        return request.getHeader(ToHeader.NAME).getAddress().getURI()
    }
}
<|endoftext|>


<commit_before>const path = require("path");
const webpack = require("webpack");
const babel = require("./config/babel");
const uglify = require("./config/uglify");

const env = process.env.NODE_ENV || "development";
const useCordova = (process.env.USE_CORDOVA || "false") === "true";
const isProd = env === "production";
const hotReload = process.env.LIVERELOAD === "true" && !isProd;
const out = path.resolve(__dirname, "dist");
const exclusions = /node_modules/;

const ExtractText = require("extract-text-webpack-plugin");
const extractShellCss = new ExtractText("shell.[hash].css");
const extractOtherCss = new ExtractText("styles.[hash].css");

process.stderr.write(`Building with env = ${env}\n`);

// plugin management
const HTML = require("html-webpack-plugin");
const Clean = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
const plugins = [
  ...require("maji/lib/webpack").plugins,
  new HTML({
    template: "src/index.html",
    useCordova,
    inject: false,
    minify: false
  }),
  new Clean(["dist"], { verbose: false, exclude: [".keep"] }),
  extractShellCss,
  extractOtherCss,
  new SpriteLoaderPlugin()
];

const optimization = {
  splitChunks: {
    chunks: "all"
  },
  minimize: isProd,
  // prints more readable module names in the browser console on HMR updates, in dev
  namedModules: !isProd,
  // prevent emitting assets with errors, in dev
  noEmitOnErrors: !isProd
};

if (!isProd && hotReload) {
  plugins.push(
    // enable HMR globally
    new webpack.HotModuleReplacementPlugin()
  );
}
// end of plugin management

// optionally live-reloadable entry points
const entryPoints = function() {
  const items = hotReload
    ? ["webpack-hot-middleware/client?noInfo=true&reload=true"]
    : [];
  items.push(...arguments);
  return items;
};

const postcssLoader = {
  loader: "postcss-loader",
  options: {
    plugins: () => [require("autoprefixer")]
  }
};

/**
 * All of Maji's peerDependencies will be aliased to the versions
 * in this app's node_modules folder. This prevents building with
 * multiple versions of the same dependency.
 *
 * See: https://medium.com/@penx/managing-dependencies-in-a-node-package-so-that-they-are-compatible-with-npm-link-61befa5aaca7
 */
const majiAliases = (function() {
  const dependencies = require("maji/package.json").peerDependencies || {};
  return Object.keys(dependencies).reduce((aliases, packageName) => {
    aliases[packageName] = path.resolve(
      __dirname,
      `./node_modules/${packageName}`
    );
    return aliases;
  }, {});
})();

module.exports = {
  mode: isProd ? "production" : "development",
  entry: {
    app: entryPoints("./src/index.js")
  },
  output: {
    path: out,
    filename: "[name].[hash].js",
    publicPath: "./"
  },
  module: {
    rules: [
      {
        test: /.*/,
        include: path.resolve(__dirname, "src/assets"),
        exclude: path.resolve(__dirname, "src/assets/icons"),
        options: {
          name: "[name]-[hash].[ext]"
        },
        loader: "file-loader"
      },
      {
        test: /\.jsx?$/,
        exclude: exclusions,
        loader: "babel-loader",
        options: babel
      },
      { test: /\.yml$/, loader: "json-loader!yaml-loader" },
      {
        test: /\.scss$/,
        loader: isProd
          ? extractOtherCss.extract({
              use: ["css-loader?modules", postcssLoader, "sass-loader"]
            })
          : [
              "style-loader",
              {
                loader: "css-loader",
                options: {
                  modules: true,
                  localIdentName: "[path][name]__[local]--[hash:base64:5]"
                }
              },
              postcssLoader,
              "sass-loader"
            ],
        exclude: /shell.scss$/
      },
      {
        test: /shell.scss$/,
        loader: isProd
          ? extractShellCss.extract({
              use: ["css-loader", postcssLoader, "sass-loader"]
            })
          : ["style-loader", "css-loader", postcssLoader, "sass-loader"]
      },
      {
        test: /\.svg$/,
        include: path.resolve(__dirname, "src/assets/icons"),
        loader: "svg-sprite-loader",
        options: {
          extract: true
        }
      }
    ]
  },
  resolve: {
    alias: Object.assign(
      {
        src: path.resolve(__dirname, "./src"),
        config: path.resolve(__dirname, "./config")
      },
      majiAliases
    ),
    symlinks: false
  },
  devtool: isProd ? "source-map" : "eval",
  plugins,
  optimization
};
<commit_msg>Only split chunks in production<commit_after>const path = require("path");
const webpack = require("webpack");
const babel = require("./config/babel");
const uglify = require("./config/uglify");

const env = process.env.NODE_ENV || "development";
const useCordova = (process.env.USE_CORDOVA || "false") === "true";
const isProd = env === "production";
const hotReload = process.env.LIVERELOAD === "true" && !isProd;
const out = path.resolve(__dirname, "dist");
const exclusions = /node_modules/;

const ExtractText = require("extract-text-webpack-plugin");
const extractShellCss = new ExtractText("shell.[hash].css");
const extractOtherCss = new ExtractText("styles.[hash].css");

process.stderr.write(`Building with env = ${env}\n`);

// plugin management
const HTML = require("html-webpack-plugin");
const Clean = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
const plugins = [
  ...require("maji/lib/webpack").plugins,
  new HTML({
    template: "src/index.html",
    useCordova,
    inject: false,
    minify: false
  }),
  new Clean(["dist"], { verbose: false, exclude: [".keep"] }),
  extractShellCss,
  extractOtherCss,
  new SpriteLoaderPlugin()
];

const optimization = {
  splitChunks: isProd && { chunks: "all" },
  minimize: isProd,
  // prints more readable module names in the browser console on HMR updates, in dev
  namedModules: !isProd,
  // prevent emitting assets with errors, in dev
  noEmitOnErrors: !isProd
};

if (!isProd && hotReload) {
  plugins.push(
    // enable HMR globally
    new webpack.HotModuleReplacementPlugin()
  );
}
// end of plugin management

// optionally live-reloadable entry points
const entryPoints = function() {
  const items = hotReload
    ? ["webpack-hot-middleware/client?noInfo=true&reload=true"]
    : [];
  items.push(...arguments);
  return items;
};

const postcssLoader = {
  loader: "postcss-loader",
  options: {
    plugins: () => [require("autoprefixer")]
  }
};

/**
 * All of Maji's peerDependencies will be aliased to the versions
 * in this app's node_modules folder. This prevents building with
 * multiple versions of the same dependency.
 *
 * See: https://medium.com/@penx/managing-dependencies-in-a-node-package-so-that-they-are-compatible-with-npm-link-61befa5aaca7
 */
const majiAliases = (function() {
  const dependencies = require("maji/package.json").peerDependencies || {};
  return Object.keys(dependencies).reduce((aliases, packageName) => {
    aliases[packageName] = path.resolve(
      __dirname,
      `./node_modules/${packageName}`
    );
    return aliases;
  }, {});
})();

module.exports = {
  mode: isProd ? "production" : "development",
  entry: {
    app: entryPoints("./src/index.js")
  },
  output: {
    path: out,
    filename: "[name].[hash].js",
    publicPath: "./"
  },
  module: {
    rules: [
      {
        test: /.*/,
        include: path.resolve(__dirname, "src/assets"),
        exclude: path.resolve(__dirname, "src/assets/icons"),
        options: {
          name: "[name]-[hash].[ext]"
        },
        loader: "file-loader"
      },
      {
        test: /\.jsx?$/,
        exclude: exclusions,
        loader: "babel-loader",
        options: babel
      },
      { test: /\.yml$/, loader: "json-loader!yaml-loader" },
      {
        test: /\.scss$/,
        loader: isProd
          ? extractOtherCss.extract({
              use: ["css-loader?modules", postcssLoader, "sass-loader"]
            })
          : [
              "style-loader",
              {
                loader: "css-loader",
                options: {
                  modules: true,
                  localIdentName: "[path][name]__[local]--[hash:base64:5]"
                }
              },
              postcssLoader,
              "sass-loader"
            ],
        exclude: /shell.scss$/
      },
      {
        test: /shell.scss$/,
        loader: isProd
          ? extractShellCss.extract({
              use: ["css-loader", postcssLoader, "sass-loader"]
            })
          : ["style-loader", "css-loader", postcssLoader, "sass-loader"]
      },
      {
        test: /\.svg$/,
        include: path.resolve(__dirname, "src/assets/icons"),
        loader: "svg-sprite-loader",
        options: {
          extract: true
        }
      }
    ]
  },
  resolve: {
    alias: Object.assign(
      {
        src: path.resolve(__dirname, "./src"),
        config: path.resolve(__dirname, "./config")
      },
      majiAliases
    ),
    symlinks: false
  },
  devtool: isProd ? "source-map" : "eval",
  plugins,
  optimization
};
<|endoftext|>


<commit_before>'use strict';

/**
* Module dependencies.
*/
const mongoose = require('mongoose');
const Game = require('../models/game');
const Score = require('../models/score');
const Team = require('../models/team');
const Player = require('../models/player');

/**
* GET /api/games/
* Get all the games
*/
exports.getGames = function getGames(req, res) {
    Game.find({}, (err, games) => {
        if (err) {
            res.status(403).send('${err}');
            return;
        }
        res.json(games);
    });
}

/**
* POST /api/games/
* Create a new game
*/
exports.postGame = function game(req, res) {
    const newGame = new Game({ teams: [], scores: [] });
    const teamIds = req.body.teams;

    const saveGame = game.save(err, (game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(game);
    });

    if (teamIds && teamIds.length > 0) {
        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    saveGame();
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    if (newGame.teams.indexOf(id) === -1) {
                        newGame.teams.push(id);
                        newGame.scores.push(new Score({ team: id }));
                    }
                }

                if (--tasksToGo === 0) {
                    saveGame();
                }
            });
        });
    } else {
        saveGame();
    }
}

/**
* PUT /api/games/:gameId/addTeam
* Add teams to a game
*/
exports.addTeam = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        if (game.started_at) {
            res.status(403).send('Game has started cannot add a team');
            return;
        }

        const teamIds = req.body.teams;

        if (!teamIds && teamIds.length <= 0) {
            res.status(403).send('body empty');
            return;
        }

        var tasksToGo = teamIds.length;

        const saveGame = game.save(err, (game) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }
            res.status(201).json(game);
        });

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    saveGame();
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    if (game.teams.indexOf(id) === -1) {
                        game.teams.push(id);
                    }
                }

                if (--tasksToGo === 0) {
                    saveGame();
                }
            });
        });
    });
}

/**
* DELETE /api/games/:gameId
* Delete a game
*/
exports.deleteGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findByIdAndRemove(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        res.status(201).json(game);
    });
}

/**
* PUT /api/games/:gameId/start
* Start game
*/
exports.startGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('player not found');
            return;
        }

        game.start(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

/**
* PUT /api/games/:gameId/finish
* Finish game
*/
exports.finishGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('player not found');
            return;
        }

        game.finish(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

/**
* PUT /api/games/:gameId/score
* Update score of game
*/
exports.gameScore = function game(req, res) {
    const gameId = req.params.gameId;
    const teamId = req.body.teamId;
    const points = req.body.points;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send('Invalid game id');
        return;
    }

    if (!teamId || !mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Invalid team id');
        return;
    }

    if (!points) {
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('Game not found');
            return;
        }

        if (!game.started_at) {
            res.status(403).send('Game not started');
            return;
        }

        if (game.ended_at) {
            res.status(403).send('Game has ended');
            return;
        }

        const scores = game.scores;

        if (scores.length <= 0) {
            res.status(403).send('Game has no scores');
            return;
        }

        var updated = false;

        for (var i = 0; i < scores.length; i++) {
            const score = scores[i];
            if (score.team == teamId) {
                score.points = points;
                updated = true;
                break;
            }
        }

        if (!updated) {
            res.status(403).send('No score found to update');
            return;
        }

        game.save((err, saveGame) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }

            res.status(201).json(saveGame);
        });
    });
}

/**
* GET /api/teams
* List of teams
*/
exports.getTeams = function get(req, res) {
    Team.find({}, (err, teams) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(200).json(teams);
    });
};

/**
* POST /api/teams
* Create a new team
*/
exports.postTeam = function post(req, res) {
    const teamName = req.body.name;
    if (!teamName) {
        res.status(403).send("Request body missing name");
        return;
    }
    const newTeam = new Team({ name: teamName });
    newTeam.save((err) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(newTeam);
    });
}

/**
* POST /api/teams/:teamId
* Update a team by id
*/
exports.putTeam = function put(req, res, next) {
    const teamId = req.params.teamId;

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Team id is not valid');
        return;
    }

    Team.findByIdAndUpdate(teamId, { name: req.body.name }, { new: true }, (err, team) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!team) {
            res.status(401).send('No team found');
            return;
        }

        res.status(201).json(team);
    });
}

/**
* DELETE /api/teams/:teamId
* Delete a team by id
*/
exports.deleteTeam = function deleteTeam(req, res) {
    const teamId = req.params.teamId;

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Team id is not valid');
        return;
    }

    Team.findByIdAndRemove(teamId, (err, team) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!team) {
            res.status(403).send('No team found');
            return;
        }

        res.status(201).json(team);
    });
}

/**
* GET /api/players/
* Get all players
*/
exports.getPlayers = function getPlayers(req, res) {
    Player.find({}, (err, players) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(200).json(players);
    });
}

/**
* POST /api/players/
* Create a new player
*/
exports.postPlayer = function postPlayer(req, res) {
    const username = req.body.username;
    const name = req.body.name;

    if (!username) {
        res.status(401).send('Missing player username');
        return;
    }

    if (!name) {
        res.status(401).send('Missing player name');
        return;
    }

    const newPlayer = new Player({ username: `${username}`, name: `${name}` });

    newPlayer.save((err) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(newPlayer);
    });
}

exports.putPlayer = function putPlayer(req, res) {
    const playerId = req.params.playerId;

    if (!mongoose.Types.ObjectId.isValid(playerId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Player.findByIdAndUpdate(playerId, { name: req.body.name }, (err, player) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        if (!player) {
            res.status(403).send('No player updated');
            return;
        }

        res.status(201).json(player);
    });
}

/**
* PUT /api/players/:playerId/addTeam
* Add a team to player
*/
exports.putPlayerTeam = function addTeamToPlayer(req, res) {
    const playerId = req.params.playerId;
    const teamId = req.body.teamId;

    if (!mongoose.Types.ObjectId.isValid(playerId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send("Invalid team id");
        return;
    }

    const teamQuery = Team.findById(teamId);

    Player.findById(playerId, (err, player) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        if (!player) {
            res.status(403).send('player not found');
            return;
        }

        teamQuery.exec((err, team) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }

            if (!team) {
                res.status(403).send('Team not found');
                return;
            }

            player.team = team._id;
            player.save((err, player) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(player);
            });
        });
    });
}
<commit_msg>Return proper error message<commit_after>'use strict';

/**
* Module dependencies.
*/
const mongoose = require('mongoose');
const Game = require('../models/game');
const Score = require('../models/score');
const Team = require('../models/team');
const Player = require('../models/player');

/**
* GET /api/games/
* Get all the games
*/
exports.getGames = function getGames(req, res) {
    Game.find({}, (err, games) => {
        if (err) {
            res.status(403).send('${err}');
            return;
        }
        res.json(games);
    });
}

/**
* POST /api/games/
* Create a new game
*/
exports.postGame = function game(req, res) {
    const newGame = new Game({ teams: [], scores: [] });
    const teamIds = req.body.teams;

    const saveGame = game.save(err, (game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(game);
    });

    if (teamIds && teamIds.length > 0) {
        var tasksToGo = teamIds.length;

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    saveGame();
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    if (newGame.teams.indexOf(id) === -1) {
                        newGame.teams.push(id);
                        newGame.scores.push(new Score({ team: id }));
                    }
                }

                if (--tasksToGo === 0) {
                    saveGame();
                }
            });
        });
    } else {
        saveGame();
    }
}

/**
* PUT /api/games/:gameId/addTeam
* Add teams to a game
*/
exports.addTeam = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        if (game.started_at) {
            res.status(403).send('Game has started cannot add a team');
            return;
        }

        const teamIds = req.body.teams;

        if (!teamIds && teamIds.length <= 0) {
            res.status(403).send('body empty');
            return;
        }

        var tasksToGo = teamIds.length;

        const saveGame = game.save(err, (game) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }
            res.status(201).json(game);
        });

        teamIds.forEach(function (id) {
            if (!mongoose.Types.ObjectId.isValid(id)) {
                if (--tasksToGo === 0) {
                    saveGame();
                }
                return;
            }

            Team.findById(id, (err, team) => {
                if (!err && team) {
                    if (game.teams.indexOf(id) === -1) {
                        game.teams.push(id);
                    }
                }

                if (--tasksToGo === 0) {
                    saveGame();
                }
            });
        });
    });
}

/**
* DELETE /api/games/:gameId
* Delete a game
*/
exports.deleteGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Game.findByIdAndRemove(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('No game found');
            return;
        }

        res.status(201).json(game);
    });
}

/**
* PUT /api/games/:gameId/start
* Start game
*/
exports.startGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid game id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('Game not found');
            return;
        }

        game.start(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

/**
* PUT /api/games/:gameId/finish
* Finish game
*/
exports.finishGame = function game(req, res) {
    const gameId = req.params.gameId;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send("Invalid game id");
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('Game not found');
            return;
        }

            return;
        }

        game.finish(() => {
            game.save((err, game) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(game);
            });
        });
    });
}

/**
* PUT /api/games/:gameId/score
* Update score of game
*/
exports.gameScore = function game(req, res) {
    const gameId = req.params.gameId;
    const teamId = req.body.teamId;
    const points = req.body.points;

    if (!mongoose.Types.ObjectId.isValid(gameId)) {
        res.status(403).send('Invalid game id');
        return;
    }

    if (!teamId || !mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Invalid team id');
        return;
    }

    if (!points) {
        return;
    }

    Game.findById(gameId, (err, game) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!game) {
            res.status(403).send('Game not found');
            return;
        }

        if (!game.started_at) {
            res.status(403).send('Game not started');
            return;
        }

        if (game.ended_at) {
            res.status(403).send('Game has ended');
            return;
        }

        const scores = game.scores;

        if (scores.length <= 0) {
            res.status(403).send('Game has no scores');
            return;
        }

        var updated = false;

        for (var i = 0; i < scores.length; i++) {
            const score = scores[i];
            if (score.team == teamId) {
                score.points = points;
                updated = true;
                break;
            }
        }

        if (!updated) {
            res.status(403).send('No score found to update');
            return;
        }

        game.save((err, saveGame) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }

            res.status(201).json(saveGame);
        });
    });
}

/**
* GET /api/teams
* List of teams
*/
exports.getTeams = function get(req, res) {
    Team.find({}, (err, teams) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(200).json(teams);
    });
};

/**
* POST /api/teams
* Create a new team
*/
exports.postTeam = function post(req, res) {
    const teamName = req.body.name;
    if (!teamName) {
        res.status(403).send("Request body missing name");
        return;
    }
    const newTeam = new Team({ name: teamName });
    newTeam.save((err) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(newTeam);
    });
}

/**
* POST /api/teams/:teamId
* Update a team by id
*/
exports.putTeam = function put(req, res, next) {
    const teamId = req.params.teamId;

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Team id is not valid');
        return;
    }

    Team.findByIdAndUpdate(teamId, { name: req.body.name }, { new: true }, (err, team) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!team) {
            res.status(401).send('No team found');
            return;
        }

        res.status(201).json(team);
    });
}

/**
* DELETE /api/teams/:teamId
* Delete a team by id
*/
exports.deleteTeam = function deleteTeam(req, res) {
    const teamId = req.params.teamId;

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send('Team id is not valid');
        return;
    }

    Team.findByIdAndRemove(teamId, (err, team) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }

        if (!team) {
            res.status(403).send('No team found');
            return;
        }

        res.status(201).json(team);
    });
}

/**
* GET /api/players/
* Get all players
*/
exports.getPlayers = function getPlayers(req, res) {
    Player.find({}, (err, players) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(200).json(players);
    });
}

/**
* POST /api/players/
* Create a new player
*/
exports.postPlayer = function postPlayer(req, res) {
    const username = req.body.username;
    const name = req.body.name;

    if (!username) {
        res.status(401).send('Missing player username');
        return;
    }

    if (!name) {
        res.status(401).send('Missing player name');
        return;
    }

    const newPlayer = new Player({ username: `${username}`, name: `${name}` });

    newPlayer.save((err) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        res.status(201).json(newPlayer);
    });
}

exports.putPlayer = function putPlayer(req, res) {
    const playerId = req.params.playerId;

    if (!mongoose.Types.ObjectId.isValid(playerId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    Player.findByIdAndUpdate(playerId, { name: req.body.name }, (err, player) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        if (!player) {
            res.status(403).send('No player updated');
            return;
        }

        res.status(201).json(player);
    });
}

/**
* PUT /api/players/:playerId/addTeam
* Add a team to player
*/
exports.putPlayerTeam = function addTeamToPlayer(req, res) {
    const playerId = req.params.playerId;
    const teamId = req.body.teamId;

    if (!mongoose.Types.ObjectId.isValid(playerId)) {
        res.status(403).send("Invalid player id");
        return;
    }

    if (!mongoose.Types.ObjectId.isValid(teamId)) {
        res.status(403).send("Invalid team id");
        return;
    }

    const teamQuery = Team.findById(teamId);

    Player.findById(playerId, (err, player) => {
        if (err) {
            res.status(403).send(`${err}`);
            return;
        }
        if (!player) {
            res.status(403).send('player not found');
            return;
        }

        teamQuery.exec((err, team) => {
            if (err) {
                res.status(403).send(`${err}`);
                return;
            }

            if (!team) {
                res.status(403).send('Team not found');
                return;
            }

            player.team = team._id;
            player.save((err, player) => {
                if (err) {
                    res.status(403).send(`${err}`);
                    return;
                }
                res.status(201).json(player);
            });
        });
    });
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var items = require('./services.json');
var transform = {
  nid: {
    newName: 'id',
    props: {value:String}
  },
  uuid: {
    props: {value:String}
  },
  title: {
    props: {value: String}
  },
  body: {
    props: {value: String}
  },
  field_location: {
    newName: "library",
    props: {target_id:{newName:'id',type:Number},target_uuid:{newName:'uuid',type:String}}
  },
  field_service_email_address: {
    newName: "emailAddress",
    props: {value:String}
  },
  field_service_phone_number: {
    newName: "phoneNumber",
    props: {value:String}
  },
  field_site_link: {
    newName: "siteLink",
    props: {uri:String}
  }
};

var processProp = function(key, trDef, prop){
  var type = trDef.type || trDef;
  var newKey = trDef.newName || key;
  if (!prop) {
    return {};
  } else if (type == String) {
    return {[newKey]:prop[key]};
  } else if (type == Boolean) {
    return {[newKey]:(prop[key]=="0")?false:true};
  } else if (type == Number) {
    return {[newKey]:Number(prop[key])};
  } else {
    return {};
  }
};

items = _.map(items, function(item){
  newProps = {};
  for (allowedPropName in transform) {
    if (item.hasOwnProperty(allowedPropName)) {
      var proptr = transform[allowedPropName];
      newPropName = proptr['newName'] || allowedPropName;
      newProps[newPropName] = []
      for (i=0; i<item[allowedPropName].length; i++) {
        newProps[newPropName][i] = {};
        for (pkey in proptr.props) {
          newProps[newPropName][i] = Object.assign(newProps[newPropName][i], processProp(pkey, proptr.props[pkey], item[allowedPropName][i]) );
        }
      }
      if (newProps[newPropName].length == 1) {
        newProps[newPropName] = newProps[newPropName][0];
        // If only one property just use the value insead of the whole object
        if (Object.keys(proptr.props).length == 1) {
          newProps[newPropName] = _.values(newProps[newPropName])[0];
        }
      }
    }
  }
  return newProps;
});

//console.log(items);
console.log(JSON.stringify(items));
<commit_msg>added featured field to services<commit_after>var _ = require('lodash');
var items = require('./services.json');
var transform = {
  nid: {
    newName: 'id',
    props: {value:String}
  },
  uuid: {
    props: {value:String}
  },
  title: {
    props: {value: String}
  },
  body: {
    props: {value: String}
  },
  field_location: {
    newName: "library",
    props: {target_id:{newName:'id',type:Number},target_uuid:{newName:'uuid',type:String}}
  },
  field_service_email_address: {
    newName: "emailAddress",
    props: {value:String}
  },
  field_service_phone_number: {
    newName: "phoneNumber",
    props: {value:String}
  },
  field_site_link: {
    newName: "siteLink",
    props: {uri:String}
  },
  field_featured: {
    newName: "featured",
    props: {value:Number}
  }
};

var processProp = function(key, trDef, prop){
  var type = trDef.type || trDef;
  var newKey = trDef.newName || key;
  if (!prop) {
    return {};
  } else if (type == String) {
    return {[newKey]:prop[key]};
  } else if (type == Boolean) {
    return {[newKey]:(prop[key]=="0")?false:true};
  } else if (type == Number) {
    return {[newKey]:Number(prop[key])};
  } else {
    return {};
  }
};

items = _.map(items, function(item){
  newProps = {};
  for (allowedPropName in transform) {
    if (item.hasOwnProperty(allowedPropName)) {
      var proptr = transform[allowedPropName];
      newPropName = proptr['newName'] || allowedPropName;
      newProps[newPropName] = []
      for (i=0; i<item[allowedPropName].length; i++) {
        newProps[newPropName][i] = {};
        for (pkey in proptr.props) {
          newProps[newPropName][i] = Object.assign(newProps[newPropName][i], processProp(pkey, proptr.props[pkey], item[allowedPropName][i]) );
        }
      }
      if (newProps[newPropName].length == 1) {
        newProps[newPropName] = newProps[newPropName][0];
        // If only one property just use the value insead of the whole object
        if (Object.keys(proptr.props).length == 1) {
          newProps[newPropName] = _.values(newProps[newPropName])[0];
        }
      }
    }
  }
  return newProps;
});

//console.log(items);
console.log(JSON.stringify(items));
<|endoftext|>


<commit_before>$(function() {
  // responsive iframe
  // see: http://blog.apps.npr.org/pym.js/
  var child = new pym.Child({id: 'councillor-iframe'});

  // Use parent URL as fb share URL
  function addFacebookShare(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3";
      fjs.parentNode.insertBefore(js, fjs);
  }

  function setShareUrl(url) {
    $('.fb-share-button').attr('data-href', url);
    addFacebookShare(document, 'script', 'facebook-jssdk');
  }

  child.onMessage('setShareUrl', setShareUrl);
  child.sendMessage('getShareUrl', '1');

});

$(function() {
  var $locate = $('.btn.locate');
  $locate.toggleClass('hidden', !navigator.geolocation);

  $locate.on('click', function(e) {
    // find user's location
    e.preventDefault();

    function foundLocation(position) {
      lat = position.coords.latitude;
      lng = position.coords.longitude;
      window.location = '/councillor?lat=' + lat + '&lng=' + lng;
    }

    function noLocation() {
      $('.btn.locate span').text('Use your location');
      alert('Sorry, your browser was unable to determine your location.');
    }

    if (navigator.geolocation) {
      $('.btn.locate span').text('Locating...');
      navigator.geolocation.getCurrentPosition(foundLocation, noLocation, {timeout:10000});
    } else {
      noLocation();
    }
  });
});

$(function() {
  $('form.find-councillor').on('submit', function(e) {
    $('form.find-councillor [type=submit]').text('Searching...').prop('disabled', true);
  });
});

$(function() {
  if ($("#map").length > 0) {
    var map = new L.Map("map", {
      scrollWheelZoom: false,
      zoomControl: false,
    });
    map.attributionControl.setPrefix('');
    var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'Map © OpenStreetMap contributors',
      maxZoom: 18
    });
    map.addLayer(osm);

    var wardId = $('#map').attr('data');
    var url = "http://mapit.code4sa.org/area/MDB:" + wardId + ".geojson?type=WD";

    $.getJSON(url).
      then(function(data) {
        var area = new L.GeoJSON(data);
        map.addLayer(area);
        map.fitBounds(area.getBounds());
      });
  }
});

$(function() {
  // typeahead
  var mapit = new Bloodhound({
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    datumTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
      url: 'http://mapit.code4sa.org/address?partial=1&generation=1&type=WD&address=QUERY',
      wildcard: 'QUERY',
      rateLimitWait: 600,
      transform: function(response) {
        var results = [];

        for (var i = 0; i < response.addresses.length; i++) {
          var address = response.addresses[i];

          for (var j = 0; j < address.areas.length; j++) {
            var area = response[address.areas[j]];
            results.push({
              'address': address.formatted_address,
              'ward_id': area.codes.MDB,
              'name': 'Ward ' + area.name,
            });
          }
        }

        return results;
      },
    }
  });

  var $q = $('form.find-councillor input[name=address]');
  $q.typeahead(
    {
      minLength: 5,
      highlight: false,
    },
    {
      name: 'mapit',
      source: mapit,
      display: 'address',
      templates: {
        suggestion: Handlebars.compile(
          '
{{name}}{{address}}
'
        )
      }
    }
  ).on('typeahead:select', function(e, item) {
    $('form.find-councillor [type=submit]').text('Searching...').prop('disabled', true);
    window.location = '/councillor/ward-' + item.ward_id;
  });
});

$(function() {
  $('#suggest-modal form').on('submit', function(e) {
    e.preventDefault();

    var $form = $(e.target);
    $.post($form.attr('action'), $form.serialize());
    $('#suggest-modal').modal('hide');
    alert("Thanks for your suggestion, we'll take a look and update our data.");
  });
});
<commit_msg>Mapit generation 2<commit_after>$(function() {
  // responsive iframe
  // see: http://blog.apps.npr.org/pym.js/
  var child = new pym.Child({id: 'councillor-iframe'});

  // Use parent URL as fb share URL
  function addFacebookShare(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3";
      fjs.parentNode.insertBefore(js, fjs);
  }

  function setShareUrl(url) {
    $('.fb-share-button').attr('data-href', url);
    addFacebookShare(document, 'script', 'facebook-jssdk');
  }

  child.onMessage('setShareUrl', setShareUrl);
  child.sendMessage('getShareUrl', '1');

});

$(function() {
  var $locate = $('.btn.locate');
  $locate.toggleClass('hidden', !navigator.geolocation);

  $locate.on('click', function(e) {
    // find user's location
    e.preventDefault();

    function foundLocation(position) {
      lat = position.coords.latitude;
      lng = position.coords.longitude;
      window.location = '/councillor?lat=' + lat + '&lng=' + lng;
    }

    function noLocation() {
      $('.btn.locate span').text('Use your location');
      alert('Sorry, your browser was unable to determine your location.');
    }

    if (navigator.geolocation) {
      $('.btn.locate span').text('Locating...');
      navigator.geolocation.getCurrentPosition(foundLocation, noLocation, {timeout:10000});
    } else {
      noLocation();
    }
  });
});

$(function() {
  $('form.find-councillor').on('submit', function(e) {
    $('form.find-councillor [type=submit]').text('Searching...').prop('disabled', true);
  });
});

$(function() {
  if ($("#map").length > 0) {
    var map = new L.Map("map", {
      scrollWheelZoom: false,
      zoomControl: false,
    });
    map.attributionControl.setPrefix('');
    var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'Map © OpenStreetMap contributors',
      maxZoom: 18
    });
    map.addLayer(osm);

    var wardId = $('#map').attr('data');
    var url = "http://mapit.code4sa.org/area/MDB:" + wardId + ".geojson?type=WD&generation=2";

    $.getJSON(url).
      then(function(data) {
        var area = new L.GeoJSON(data);
        map.addLayer(area);
        map.fitBounds(area.getBounds());
      });
  }
});

$(function() {
  // typeahead
  var mapit = new Bloodhound({
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    datumTokenizer: Bloodhound.tokenizers.whitespace,
    remote: {
      url: 'http://mapit.code4sa.org/address?partial=1&generation=2&type=WD&address=QUERY',
      wildcard: 'QUERY',
      rateLimitWait: 600,
      transform: function(response) {
        var results = [];

        for (var i = 0; i < response.addresses.length; i++) {
          var address = response.addresses[i];

          for (var j = 0; j < address.areas.length; j++) {
            var area = response[address.areas[j]];
            results.push({
              'address': address.formatted_address,
              'ward_id': area.codes.MDB,
              'name': 'Ward ' + area.name,
            });
          }
        }

        return results;
      },
    }
  });

  var $q = $('form.find-councillor input[name=address]');
  $q.typeahead(
    {
      minLength: 5,
      highlight: false,
    },
    {
      name: 'mapit',
      source: mapit,
      display: 'address',
      templates: {
        suggestion: Handlebars.compile(
          '
{{name}}{{address}}
'
        )
      }
    }
  ).on('typeahead:select', function(e, item) {
    $('form.find-councillor [type=submit]').text('Searching...').prop('disabled', true);
    window.location = '/councillor/ward-' + item.ward_id;
  });
});

$(function() {
  $('#suggest-modal form').on('submit', function(e) {
    e.preventDefault();

    var $form = $(e.target);
    $.post($form.attr('action'), $form.serialize());
    $('#suggest-modal').modal('hide');
    alert("Thanks for your suggestion, we'll take a look and update our data.");
  });
});
<|endoftext|>


<commit_before>(function () {
  'use strict';

  var app = angular.module('status', []);

  app.factory('showGlobalError', [
    '$rootScope',
    function ($rootScope) {
      return function (msg, excp) {
        $rootScope.globalErrorMsg = $rootScope.globalErrorMsg || [];
        $rootScope.globalErrorMsg.push(msg);
        if (excp) {
          console.error(excp);
        }
      };
    }
  ]);
})();<commit_msg>using NavCtrl from extras module<commit_after>(function () {
  'use strict';

  var app = angular.module('status', ['status-extras']);

  app.factory('showGlobalError', [
    '$rootScope',
    function ($rootScope) {
      return function (msg, excp) {
        $rootScope.globalErrorMsg = $rootScope.globalErrorMsg || [];
        $rootScope.globalErrorMsg.push(msg);
        if (excp) {
          console.error(excp);
        }
      };
    }
  ]);
})();<|endoftext|>