<commit_before>chorus.dialogs.DatasetImport = chorus.dialogs.Base.extend({
    className: "dataset_import",
    title: t("dataset.import.title"),

    events: {
        "change input:radio": "onRadioSelect",
        "submit form": "uploadFile"
    },

    onRadioSelect: function(e) {
        this.$(".new_table input:text").attr("disabled", "disabled");
        this.$(".existing_table select").attr("disabled", "disabled");

        var target = $(e.currentTarget).val();
        if (target == "new") {
            this.$(".new_table input:text").attr("disabled", false);

        } else if (target == "existing") {
            this.$(".existing_table select").attr("disabled", false);
        }

        chorus.styleSelect(self.$("select"));
    },

    additionalContext : function() {
        return {
            canonicalName : this.options.launchElement.data("canonicalName")
        }
    },

    uploadFile: function(e) {
        e && e.preventDefault();
        this.$("button.submit").startLoading("actions.uploading");
        this.uploadObj.url = "/edc/workspace/" + this.options.launchElement.data("workspaceId") + "/csv/sample"
        this.request = this.uploadObj.submit();
    },

    modalClosed : function() {
        if (this.request) {
            this.request.abort();
        }

        this._super("modalClosed");
    },

    postRender: function() {
        var self = this;
        this.$("input[type=file]").fileupload({
            change: fileChosen,
            add: fileChosen,
            done: uploadFinished,
            dataType: "json"
        });

        function fileChosen(e, data) {
            self.$("button.submit").attr("disabled", false);
            self.$('.empty_selection').addClass('hidden');

            self.uploadObj = data;
            var filename = data.files[0].name;
            var filenameComponents = filename.split('.');
            var basename = _.first(filenameComponents);
            var extension = _.last(filenameComponents);
            self.$(".file_name").text(filename);
            self.$(".new_table input[type='text']").val(basename.toLowerCase().replace(/ /g, '_'));

            self.$("img").removeClass("hidden");
            self.$("img").attr("src", chorus.urlHelpers.fileIconUrl(extension, "medium"));

            self.$(".import_controls").removeClass("hidden");

            self.$(".file-wrapper a").removeClass("hidden");
            self.$(".file-wrapper button").addClass("hidden");

            chorus.styleSelect(self.$("select"));
        }

        function uploadFinished(e, data) {
            e && e.preventDefault();
            self.$("button.submit").stopLoading();
            self.csv = new chorus.models.CSVImport({
                workspaceId: self.options.launchElement.data("workspaceid"),
                toTable: chorus.models.CSVImport.normalizeForDatabase(self.$(".new_table input[type='text']").val())
            });
            self.csv.set(self.csv.parse(data.result));
            var dialog = new chorus.dialogs.TableImportCSV({csv: self.csv});
            dialog.launchModal();
        }
    }
});
<commit_msg>Fix another bad request url in csv import<commit_after>chorus.dialogs.DatasetImport = chorus.dialogs.Base.extend({
    className: "dataset_import",
    title: t("dataset.import.title"),

    events: {
        "change input:radio": "onRadioSelect",
        "submit form": "uploadFile"
    },

    onRadioSelect: function(e) {
        this.$(".new_table input:text").attr("disabled", "disabled");
        this.$(".existing_table select").attr("disabled", "disabled");

        var target = $(e.currentTarget).val();
        if (target == "new") {
            this.$(".new_table input:text").attr("disabled", false);

        } else if (target == "existing") {
            this.$(".existing_table select").attr("disabled", false);
        }

        chorus.styleSelect(self.$("select"));
    },

    additionalContext : function() {
        return {
            canonicalName : this.options.launchElement.data("canonicalName")
        }
    },

    uploadFile: function(e) {
        e && e.preventDefault();
        this.$("button.submit").startLoading("actions.uploading");
        this.uploadObj.url = "/edc/workspace/" + this.options.launchElement.data("workspaceId") + "/csv/sample"
        this.request = this.uploadObj.submit();
    },

    modalClosed : function() {
        if (this.request) {
            this.request.abort();
        }

        this._super("modalClosed");
    },

    postRender: function() {
        var self = this;
        this.$("input[type=file]").fileupload({
            change: fileChosen,
            add: fileChosen,
            done: uploadFinished,
            dataType: "json"
        });

        function fileChosen(e, data) {
            self.$("button.submit").attr("disabled", false);
            self.$('.empty_selection').addClass('hidden');

            self.uploadObj = data;
            var filename = data.files[0].name;
            var filenameComponents = filename.split('.');
            var basename = _.first(filenameComponents);
            var extension = _.last(filenameComponents);
            self.$(".file_name").text(filename);
            self.$(".new_table input[type='text']").val(basename.toLowerCase().replace(/ /g, '_'));

            self.$("img").removeClass("hidden");
            self.$("img").attr("src", chorus.urlHelpers.fileIconUrl(extension, "medium"));

            self.$(".import_controls").removeClass("hidden");

            self.$(".file-wrapper a").removeClass("hidden");
            self.$(".file-wrapper button").addClass("hidden");

            chorus.styleSelect(self.$("select"));
        }

        function uploadFinished(e, data) {
            e && e.preventDefault();
            self.$("button.submit").stopLoading();
            self.csv = new chorus.models.CSVImport({
                workspaceId: self.options.launchElement.data("workspaceId"),
                toTable: chorus.models.CSVImport.normalizeForDatabase(self.$(".new_table input[type='text']").val())
            });
            self.csv.set(self.csv.parse(data.result));
            var dialog = new chorus.dialogs.TableImportCSV({csv: self.csv});
            dialog.launchModal();
        }
    }
});
<|endoftext|>


<commit_before>/*
 * Server entry point file for the Book Trading Club app.
 */
'use strict';

var $DEBUG = 0;

loadDotEnv();

// Load required npm modules
const express = require('express');
const mongoose = require('mongoose');
const passport = require('passport');
const session = require('express-session');
const bodyParser = require('body-parser');
const morgan = require('morgan');

// App-specific requires
const routes = require('./server/routes/routes.js');

var app = express();
app.set('view engine', 'pug');

require('./server/config/passport')(passport);

app.url = process.env.APP_URL;
console.log('The full APP url: ' + app.url);

mongoose.connect(process.env.MONGO_URI);
mongoose.Promise = global.Promise;

// Initialize resource paths for the server
app.use('/build', express.static(process.cwd() + '/build'));
app.use('/ctrl', express.static(process.cwd() + '/server/ctrl'));
app.use('/public', express.static(process.cwd() + '/public'));
app.use('/common', express.static(process.cwd() + '/server/common'));
app.use('/pug', express.static(process.cwd() + '/pug'));

app.use(session({
	secret: process.env.SECRET_KEY,
	resave: false,
	saveUninitialized: true
}));

app.locals.pretty = true;

app.use(passport.initialize());
app.use(passport.session());

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.use(morgan('combined'));

routes(app, passport);

var port = process.env.PORT || 8080;
app.listen(port, () => {
	console.log('BookWyrms Server listening on port ' + port + '...');
});

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function loadDotEnv() {
    // When deployed to heroku, don't use .env
    if (process.env.NODE_ENV !== 'production') {
        require('dotenv').load();
        $DEBUG = process.env.DEBUG || 0;
        if ($DEBUG) {
            console.log('Loaded .env file OK. Node env: '
            + process.env.NODE_ENV);
        }
        console.log('BookWyrms server Running in development environment');
    }
    else {
        console.log('BookWyrms server Running now in production environment');
    }
}

<commit_msg>Added helmet and debug.<commit_after>/*
 * Server entry point file for the Book Trading Club app.
 */
'use strict';

const debug = require('debug')('book:server');

loadDotEnv();

// Load required npm modules
const express = require('express');
const mongoose = require('mongoose');
const passport = require('passport');
const session = require('express-session');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const helmet = require('helmet');

// App-specific requires
const routes = require('./server/routes/routes.js');

debug('All requires loaded.');

var app = express();
app.set('view engine', 'pug');

require('./server/config/passport')(passport);

app.url = process.env.APP_URL;
console.log('The full APP url: ' + app.url);

mongoose.connect(process.env.MONGO_URI);
mongoose.Promise = global.Promise;

// Initialize resource paths for the server
app.use('/build', express.static(process.cwd() + '/build'));
app.use('/ctrl', express.static(process.cwd() + '/server/ctrl'));
app.use('/public', express.static(process.cwd() + '/public'));
app.use('/common', express.static(process.cwd() + '/server/common'));
app.use('/pug', express.static(process.cwd() + '/pug'));

app.use(helmet());

app.use(session({
	secret: process.env.SECRET_KEY,
	resave: false,
	saveUninitialized: true
}));

app.locals.pretty = true;

app.use(passport.initialize());
app.use(passport.session());

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.use(morgan('combined'));

routes(app, passport);

var port = process.env.PORT || 8080;
app.listen(port, () => {
	console.log('BookWyrms Server listening on port ' + port + '...');
});

//---------------------------------------------------------------------------
// HELPER FUNCTIONS
//---------------------------------------------------------------------------

function loadDotEnv() {
    // When deployed to heroku, don't use .env
    if (process.env.NODE_ENV !== 'production') {
        debug('BookWyrms server Not in prod. Loading local .env file.');
        require('dotenv').load();
        debug('Loaded .env file OK. Node env: '
        + process.env.NODE_ENV);
    }
    else {
        debug('BookWyrms server Running in PRODUCTION environment');
    }
}

<|endoftext|>


<commit_before>/*global pulse, app, jQuery, require, document, esri, esriuk, Handlebars, console, $, mynearest, window, alert, unescape, define */

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
/**
 * Execute the Query Task to a Layer
 */
define(["dojo/Deferred", "esri/layers/FeatureLayer", "esri/renderers/jsonUtils", "esri/tasks/query", "esri/tasks/QueryTask", "esri/geometry/Circle", "esri/units"],
    function (Deferred, FeatureLayer, jsonUtils, Query, QueryTask, Circle, Units) {
    var taskOutput = function LayerInfoTask(props) {
        this.properties = props;

        this.getLayerInfo = function () {
            var _this = this, result = new Deferred(), featureLayer;

            // Need to also get the symbology for each layer
            featureLayer = new FeatureLayer(_this.properties.serviceUrl);

            featureLayer.on("error", function (err) {
                result.resolve({ id: _this.properties.layerId, layerInfo: null, results:null, error: err, itemId: _this.properties.itemId });
            });
            featureLayer.on("load", function (data) {
                var layerInf = { renderer: null, id: _this.properties.layerId, itemId: _this.properties.itemId, opacity: _this.properties.layerOpacity };

                if (props.layerRenderer !== undefined && props.layerRenderer !== null) {
                    layerInf.renderer = jsonUtils.fromJson(props.layerRenderer);
                }
                else {
                    layerInf.renderer = data.layer.renderer;
                }

                _this.queryLayer(data.layer.maxRecordCount).then(function (res) {
                    result.resolve({ id: _this.properties.layerId, layerInfo: layerInf, results: res.results, error: null, itemId: _this.properties.itemId, url: _this.properties.serviceUrl });
                });
            });

            return result.promise;
        };

        this.getUnits = function (distanceUnits) {
            switch (distanceUnits) {
                case "m":
                    return Units.MILES;

                case "km":
                    return Units.KILOMETERS;

                case "me":
                    return Units.METERS;

                default:
                    return Units.MILES;
            }
        };

        this.queryLayer = function (maxRecords) {
            var _this = this, result = new Deferred(), query, queryTask, geom;

            if (parseFloat(_this.properties.searchRadius) > 0) {
                geom = new Circle({
                    center: [_this.properties.currentPoint.x, _this.properties.currentPoint.y],
                    geodesic: true,
                    radius: _this.properties.searchRadius,
                    radiusUnit: _this.getUnits(_this.properties.distanceUnits)
                });
            }
            else {
                geom = _this.properties.currentPoint;
            }

            // Use the current location and buffer the point to create a search radius
            query = new Query();
            queryTask = new QueryTask(_this.properties.serviceUrl);

            query.where = "1=1"; // Get everything
            query.geometry = geom;
            query.outFields = ["*"];
            query.returnGeometry = true;
            query.outSpatialReference = _this.properties.currentPoint.spatialReference;
            query.num = maxRecords || 1000;

            queryTask.execute(query, function (features) {
                result.resolve({ error: null, id: _this.properties.layerId, results: features, itemId: _this.properties.itemId});
            },
            function (error) {
                result.resolve({ error: error, id: _this.properties.layerId, results: null, itemId: _this.properties.itemId });
            });

            return result.promise;
        };

        this.execute = function () {
            return this.getLayerInfo();
        };
    };

    return taskOutput;
});<commit_msg>Tidy Up  Radius Check<commit_after>/*global pulse, app, jQuery, require, document, esri, esriuk, Handlebars, console, $, mynearest, window, alert, unescape, define */

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */
/**
 * Execute the Query Task to a Layer
 */
define(["dojo/Deferred", "esri/layers/FeatureLayer", "esri/renderers/jsonUtils", "esri/tasks/query", "esri/tasks/QueryTask", "esri/geometry/Circle", "esri/units"],
    function (Deferred, FeatureLayer, jsonUtils, Query, QueryTask, Circle, Units) {
    var taskOutput = function LayerInfoTask(props) {
        this.properties = props;

        this.getLayerInfo = function () {
            var _this = this, result = new Deferred(), featureLayer;

            // Need to also get the symbology for each layer
            featureLayer = new FeatureLayer(_this.properties.serviceUrl);

            featureLayer.on("error", function (err) {
                result.resolve({ id: _this.properties.layerId, layerInfo: null, results:null, error: err, itemId: _this.properties.itemId });
            });
            featureLayer.on("load", function (data) {
                var layerInf = { renderer: null, id: _this.properties.layerId, itemId: _this.properties.itemId, opacity: _this.properties.layerOpacity };

                if (props.layerRenderer !== undefined && props.layerRenderer !== null) {
                    layerInf.renderer = jsonUtils.fromJson(props.layerRenderer);
                }
                else {
                    layerInf.renderer = data.layer.renderer;
                }

                _this.queryLayer(data.layer.maxRecordCount).then(function (res) {
                    result.resolve({ id: _this.properties.layerId, layerInfo: layerInf, results: res.results, error: null, itemId: _this.properties.itemId, url: _this.properties.serviceUrl });
                });
            });

            return result.promise;
        };

        this.getUnits = function (distanceUnits) {
            switch (distanceUnits) {
                case "m":
                    return Units.MILES;

                case "km":
                    return Units.KILOMETERS;

                case "me":
                    return Units.METERS;

                default:
                    return Units.MILES;
            }
        };

        this.queryLayer = function (maxRecords) {
            var _this = this, result = new Deferred(), query, queryTask, geom, searchradius;

            searchradius = parseFloat(_this.properties.searchRadius);

            if (searchradius > 0) {
                geom = new Circle({
                    center: [_this.properties.currentPoint.x, _this.properties.currentPoint.y],
                    geodesic: true,
                    radius: searchradius,
                    radiusUnit: _this.getUnits(_this.properties.distanceUnits)
                });
            }
            else {
                geom = _this.properties.currentPoint;
            }

            // Use the current location and buffer the point to create a search radius
            query = new Query();
            queryTask = new QueryTask(_this.properties.serviceUrl);

            query.where = "1=1"; // Get everything
            query.geometry = geom;
            query.outFields = ["*"];
            query.returnGeometry = true;
            query.outSpatialReference = _this.properties.currentPoint.spatialReference;
            query.num = maxRecords || 1000;

            queryTask.execute(query, function (features) {
                result.resolve({ error: null, id: _this.properties.layerId, results: features, itemId: _this.properties.itemId});
            },
            function (error) {
                result.resolve({ error: error, id: _this.properties.layerId, results: null, itemId: _this.properties.itemId });
            });

            return result.promise;
        };

        this.execute = function () {
            return this.getLayerInfo();
        };
    };

    return taskOutput;
});<|endoftext|>


<commit_before>/**
 * jquery.dlmenu.js v1.0.1
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
(function($,window,undefined){var Modernizr=window.Modernizr,$body=$("body");$.DLMenu=function(options,element){this.$el=$(element);this._init(options)};$.DLMenu.defaults={animationClasses:{classin:"dl-animate-in-1",classout:"dl-animate-out-1"},onLevelClick:function(el,name){return false},onLinkClick:function(el,ev){return false}};$.DLMenu.prototype={_init:function(options){this.options=$.extend(true,{},$.DLMenu.defaults,options);this._config();var animEndEventNames={"WebkitAnimation":"webkitAnimationEnd",
"OAnimation":"oAnimationEnd","msAnimation":"MSAnimationEnd","animation":"animationend"},transEndEventNames={"WebkitTransition":"webkitTransitionEnd","MozTransition":"transitionend","OTransition":"oTransitionEnd","msTransition":"MSTransitionEnd","transition":"transitionend"};this.animEndEventName=animEndEventNames[Modernizr.prefixed("animation")]+".dlmenu";this.transEndEventName=transEndEventNames[Modernizr.prefixed("transition")]+".dlmenu",this.supportAnimations=Modernizr.cssanimations,this.supportTransitions=
Modernizr.csstransitions;this._initEvents()},_config:function(){this.open=false;this.$trigger=this.$el.children(".dl-trigger");this.$menu=this.$el.children("ul.dl-menu");this.$menuitems=this.$menu.find("li:not(.dl-back)");this.$el.find("ul.dl-submenu").prepend('
back
');this.$back=this.$menu.find("li.dl-back")},_initEvents:function(){var self=this;this.$trigger.on("click.dlmenu",function(){if(self.open)self._closeMenu();else self._openMenu();return false});this.$menuitems.on("click.dlmenu",
function(event){event.stopPropagation();var $item=$(this),$submenu=$item.children("ul.dl-submenu");if($submenu.length>0){var $flyin=$submenu.clone().css("opacity",0).insertAfter(self.$menu),onAnimationEndFn=function(){self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass("dl-subview");$item.addClass("dl-subviewopen").parents(".dl-subviewopen:first").removeClass("dl-subviewopen").addClass("dl-subview");$flyin.remove()};setTimeout(function(){$flyin.addClass(self.options.animationClasses.classin);
self.$menu.addClass(self.options.animationClasses.classout);if(self.supportAnimations)self.$menu.on(self.animEndEventName,onAnimationEndFn);else onAnimationEndFn.call();self.options.onLevelClick($item,$item.children("a:first").text())});return false}else self.options.onLinkClick($item,event)});this.$back.on("click.dlmenu",function(event){var $this=$(this),$submenu=$this.parents("ul.dl-submenu:first"),$item=$submenu.parent(),$flyin=$submenu.clone().insertAfter(self.$menu);var onAnimationEndFn=function(){self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classin);
$flyin.remove()};setTimeout(function(){$flyin.addClass(self.options.animationClasses.classout);self.$menu.addClass(self.options.animationClasses.classin);if(self.supportAnimations)self.$menu.on(self.animEndEventName,onAnimationEndFn);else onAnimationEndFn.call();$item.removeClass("dl-subviewopen");var $subview=$this.parents(".dl-subview:first");if($subview.is("li"))$subview.addClass("dl-subviewopen");$subview.removeClass("dl-subview")});return false})},closeMenu:function(){if(this.open)this._closeMenu()},
_closeMenu:function(){var self=this,onTransitionEndFn=function(){self.$menu.off(self.transEndEventName);self._resetMenu()};this.$menu.removeClass("dl-menuopen");this.$menu.addClass("dl-menu-toggle");this.$trigger.removeClass("dl-active");if(this.supportTransitions)this.$menu.on(this.transEndEventName,onTransitionEndFn);else onTransitionEndFn.call();this.open=false},openMenu:function(){if(!this.open)this._openMenu()},_openMenu:function(){var self=this;$body.off("click").on("click.dlmenu",function(){self._closeMenu()});
this.$menu.addClass("dl-menuopen dl-menu-toggle").on(this.transEndEventName,function(){$(this).removeClass("dl-menu-toggle")});this.$trigger.addClass("dl-active");this.open=true},_resetMenu:function(){this.$menu.removeClass("dl-subview");this.$menuitems.removeClass("dl-subview dl-subviewopen")}};var logError=function(message){if(window.console)window.console.error(message)};$.fn.dlmenu=function(options){if(typeof options==="string"){var args=Array.prototype.slice.call(arguments,1);this.each(function(){var instance=
$.data(this,"dlmenu");if(!instance){logError("cannot call methods on dlmenu prior to initialization; "+"attempted to call method '"+options+"'");return}if(!$.isFunction(instance[options])||options.charAt(0)==="_"){logError("no such method '"+options+"' for dlmenu instance");return}instance[options].apply(instance,args)})}else this.each(function(){var instance=$.data(this,"dlmenu");if(instance)instance._init();else instance=$.data(this,"dlmenu",new $.DLMenu(options,this))});return this}})(jQuery,window);
<commit_msg>Delete jquery.dlmenu.min.js<commit_after><|endoftext|>


<commit_before>// app.js
//
// This is the main hub of the client-side application. This never runs server-side.
//
// It has two primary jobs:
//    1. configure the main application object for the client (this is a Marionette-style Application)
//    2. connect to the sever and manage the flow of messages
//

require([
    "jquery", "underscore", "backbone", "logger", "client-models",
    "event-views", "sockjs", "auth",
    // plugins
    "bootstrap", "backbone.marionette", "underscore-template-config"
], function($, _, Backbone, logging, models, eventViews, SockJS, auth) {

var sock;
var curEvent, users, messages;
var app;
var curSession = null;
var logger = new logging.Logger("event-app");

$(document).ready(function() {
    logger.log("Starting app!");

    var interval = 0;
    var messageShown = false ;
    var aboutShown = false;

    //------------------------------------------------------------------------//
    //                                                                          //
    //                                NETWORKING                                  //
    //                                                                          //
    //------------------------------------------------------------------------//
    //
    // From here down, we're mostly concerned with managing networking and
    // communication.
    sock = new SockJS(document.location.protocol + "//" + document.location.hostname +
            (document.location.port ? ":" + document.location.port : "") + "/sock");
    // Register a bunch of listeners on the major events it will fire.
    sock.onopen = function() {
        // on connect, send the auth message.
        sock.send(JSON.stringify({
            type: "auth",
            args: {key: auth.SOCK_KEY, id: auth.USER_ID}
        }));
    };

    // This is the big one - handles every incoming message.
    sock.onmessage = function(message) {
        var session;

        // logger.log(message);

        // messages come across the wire as raw strings in the data field.
        // parse them into a proper object here.
        var msg = JSON.parse(message.data);

        if(msg.type.indexOf("-err")!=-1) {
            logger.error("Got an error from the server!", message);
            if (msg.type === "chat-err" && msg.args === "Over capacity") {
                messages.trigger("over-capacity");
            }
        }
        // All messages have a type field.
        switch(msg.type) {
            // join an EVENT
            case "join":
                users.add(new models.User(msg.args.user));
                break;

            // leave an EVENT
            case "leave":
                users.remove(users.get(msg.args.user.id));
                break;

            // chat message received
            case "chat":
                messages.add(new models.ChatMessage(msg.args));
                app.vent.trigger("new-chat-message");

                break;

            // the embed for this event has been updated
            case "embed":
                var originalYoutubeId = curEvent.get("youtubeEmbed") || "";

                curEvent.setEmbed(msg.args.ytId);
                logger.log("added yt embed id: " + JSON.stringify(msg.args));
                break;

            case "control-video":
                app.youtubeEmbedView.control(msg.args);
                break;

            case "set-hoa":
                if (_.isNull(msg.args)) {
                    curEvent.setHoA(null);
                } else if (curEvent.get("hoa")) {
                    logger.debug("set hoa attrs", msg.args);
                    curEvent.get("hoa").set(msg.args);
                } else {
                    session = new models.Session(msg.args);
                    curEvent.setHoA(session);
                }
                break;

            case "delete-session":
                session = curEvent.get("sessions").get(msg.args.id);
                // app.paginatedSessions.remove(session);
                curEvent.removeSession(session);

                logger.log("removing session: " + msg.args.id);
                break;

            // create a new session
            case "create-session":
                session = new models.Session(msg.args);

                // this is sort of ugly to have to edit both.
                // i'm not sure the former one is critical, but it is definitely
                // important that we add it to the special paginated sessions list.
                // after startup, we have to edit it directly.
                curEvent.get("sessions").add(session);
                // app.paginatedSessions.add(session);
                break;

            // update the list of a session's not-yet-connected-but-joining participants
            case "joining-participants":
                logger.log("joining participants "+ msg.args.id, msg.args.participants);
                session = curEvent.get("sessions").get(msg.args.id);
                session.set("joiningParticipants", msg.args.participants);
                break;

            // update the list of a session's participants
            case "session-participants":
                logger.log("participants in session "+msg.args.id, msg.args.participants);
                session = curEvent.get("sessions").get(msg.args.id);
                session.setConnectedParticipants(msg.args.participants);
                break;

            // mark a session as having its hangout connected and communicating
            case "session-hangout-connected":
                session = curEvent.get("sessions").get(msg.args.id);
                session.set("hangoutConnected", true);
                break;

            // mark a session as disconnected
            case "session-hangout-disconnected":
                session = curEvent.get("sessions").get(msg.args.id);
                session.setConnectedParticipants([]);
                session.set("hangoutConnected", false);
                break;

            case "open-sessions":
                curEvent.openSessions();
                app.sessionListView.render();
                break;

            case "close-sessions":
                curEvent.closeSessions();
                app.sessionListView.render();
                break;

            // sent in cases when the event's information has been updated.
            // includes the entire event JSON object as the server sees it.
            // copy it into curEvent.
            case "event-update":
                curEvent.set(msg.args);

                logger.log("updated current event: " + JSON.stringify(msg.args));
                break;

            // *-ack message types are just acknowledgmeents from the server
            // of the receipt of a particular message type and that the
            // message was properly formatted and accepted.
            //
            // mostly we don't do anything with these messages, but
            // in some situations we do react to them. They're used
            // more for testing.
            case "auth-ack":
                sock.send(JSON.stringify({type:"join", args:{id:curEvent.getRoomId()}}));
                break;

            case "join-ack":
                logger.log("joined!");
                break;

            case "attend-ack":
                logger.log("attend-ack");
                break;
        }
    };

    // handle losing the connection to the server.
    // we want to put up a notice so the user knows that they've been disconnected (in
    // case they can do anything about it, like unpugged cable or wifi outage)
    // at the same time, we also want to attempt to reconnect if it was a server
    // outage and the server is restarting. So we occasionally ping the server
    // with an http request and when it responds successfully, we reload the page
    // which will trigger a full reconnection and state reset.
    sock.onclose = function() {
        $('#disconnected-modal').modal('show');
        messages.add(new models.ChatMessage({text:"You have been disconnected from the server. Please reload the page to reconnect!"}));

        var checkIfServerUp = function () {
             var ping = document.location;

             $.ajax({
                  url: ping,
                  type: "HEAD",
                  cache: false
              }).done(function() {
                  // reload window when ajax call is successful
                  window.location.reload();
              }).fail(function() {
                  timeout = setTimeout(checkIfServerUp, 1000);
              });
        };
        // Run the first check at a random interval to hopefully spread out
        // requests to a seiged server trying to restart.
        setTimeout(checkIfServerUp, 1000 * Math.random());
    };

    //------------------------------------------------------------------------//
    //                                                                          //
    //                                APP SETUP                                   //
    //                                                                          //
    //------------------------------------------------------------------------//

    // The EVENT_ATTRS constant comes from the event.ejs file. They are the way
    // that the server communicates the initial state of the event to the
    // client - in a big JSON blob. Subsequent updates all happen over the
    // sockJS channel, but the initial state is embedded there.
    curEvent = new models.ClientEvent(EVENT_ATTRS);
    if (HOA_ATTRS) {
        curEvent.set("hoa", new models.Session(HOA_ATTRS));
        curEvent.get("hoa").event = curEvent;
    }
    curEvent.get("sessions").add(EVENT_ATTRS.sessions);
    users = new models.UserList(EVENT_ATTRS.connectedUsers);
    messages = new models.ChatMessageList();

    logger.log("Inflated models.");

    // documentation for Marionette applications can be found here:
    // https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.md
    app = new Backbone.Marionette.Application();

    // the notion of regions comes from Marionette.
    // https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md
    //
    // Basically, they give us a way to create containers in the application, that different
    // views are added and removed from. It handles various event cleanup work on add/remove.
    // In this app, we don't often swap stuff in and out. It's primarily just a useful
    // organizational abstraction.
    app.addRegions({
        right: '#main-right',
        main: '#main-left',
        topLeft: '#top-left',
        global: '#global',
        dialogs: '#dialogs',
        admin: '#admin-region',
        bar:'#bar',
        top:'#top'
    });

    // This is code that runs when the application initializes.
    app.addInitializer(function(options) {

        // include the youtube JS api per docs:
        // https://developers.google.com/youtube/iframe_api_reference
        var tag = document.createElement('script');
        tag.src = "//www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        // create all the basic views
        this.sessionListView = new eventViews.SessionListView({
            collection: curEvent.get("sessions"),
            event: curEvent,
            sock: sock
        });
        this.chatView = new eventViews.ChatLayout({
            messages: messages,
            users: users,
            event: curEvent,
            sock: sock
        });
        this.youtubeEmbedView = new eventViews.VideoEmbedView({
            model: curEvent, sock: sock
        });
        this.dialogView = new eventViews.DialogView({
            event: curEvent, sock: sock
        });

        this.aboutView = new eventViews.AboutEventView({model: curEvent});

        // present the views in their respective regions
        this.right.show(this.chatView);
        this.main.show(this.sessionListView);
        this.topLeft.show(this.youtubeEmbedView);
        this.dialogs.show(this.dialogView);
        this.top.show(this.aboutView);

        // this is a little unorthodox, but not sure how else
        // to do it.
        $(this.bar.el).hide();

        // obviously this is not secure, but any admin requests are re-authenticated on
        // the server. Showing the admin UI is harmless if a non-admin messes with it.
        if(IS_ADMIN) {
            this.adminButtonView = new eventViews.AdminButtonView({
                event: curEvent, sock: sock
            });
            curEvent.on("change:sessionsOpen change:start", _.bind(function() {
                this.adminButtonView.render();
            }, this));
            this.admin.show(this.adminButtonView);
        }
        var maybeMute = function() {
            var hoa = curEvent.get("hoa");
            if (hoa && _.findWhere(hoa.get("connectedParticipants"), {id: auth.USER_ID})) {
                app.youtubeEmbedView.control({"mute": true});
            }
        };
        curEvent.on("update-hoa", maybeMute);
        maybeMute();

        logger.log("Initialized app.");

        $("#admin-page-for-event").attr("href", "/admin/event/" + curEvent.id);

    }, app);

    app.vent.on("about-nav", _.bind(function(hide) {

        if (_.isUndefined(hide)) {
            hide = aboutShown;
        }

        var el = this.top.$el;

        $(".updated").addClass("hide");
        if (hide) {
            if(!curEvent.isLive()) {
                // don't let people dismiss the about screen if the event isn't live.
                return;
            }

            el.animate({
                "top": -1 * el.outerHeight() - 15
            }, {
                done: function() {
                    el.hide();
                }
            });

            aboutShown = false;
            $("#about-nav").removeClass("active");
        } else {
            el.show().animate({"top":0});
            aboutShown = true;

            $("#about-nav").addClass("active");
        }

    }, app));

    app.start();

    // if the event isn't live yet, force the about page to show.
    if(!curEvent.isLive()) {
        // Force about pane to show itself.
        app.vent.trigger("about-nav", false);
    } else {
        // Make about pane hide itself.
        app.vent.trigger("about-nav", true);
    }

    // Handles clicks on the nav bar links.
    $("#about-nav").click(function(jqevt) {
        jqevt.preventDefault();
        app.vent.trigger("about-nav");
    });

    logger.log("Setup regions.");

});

});
<commit_msg>Mute on video add even if player isn't ready<commit_after>// app.js
//
// This is the main hub of the client-side application. This never runs server-side.
//
// It has two primary jobs:
//    1. configure the main application object for the client (this is a Marionette-style Application)
//    2. connect to the sever and manage the flow of messages
//

require([
    "jquery", "underscore", "backbone", "logger", "client-models",
    "event-views", "sockjs", "auth",
    // plugins
    "bootstrap", "backbone.marionette", "underscore-template-config"
], function($, _, Backbone, logging, models, eventViews, SockJS, auth) {

var sock;
var curEvent, users, messages;
var app;
var curSession = null;
var logger = new logging.Logger("event-app");

$(document).ready(function() {
    logger.log("Starting app!");

    var interval = 0;
    var messageShown = false ;
    var aboutShown = false;

    //------------------------------------------------------------------------//
    //                                                                          //
    //                                NETWORKING                                  //
    //                                                                          //
    //------------------------------------------------------------------------//
    //
    // From here down, we're mostly concerned with managing networking and
    // communication.
    sock = new SockJS(document.location.protocol + "//" + document.location.hostname +
            (document.location.port ? ":" + document.location.port : "") + "/sock");
    // Register a bunch of listeners on the major events it will fire.
    sock.onopen = function() {
        // on connect, send the auth message.
        sock.send(JSON.stringify({
            type: "auth",
            args: {key: auth.SOCK_KEY, id: auth.USER_ID}
        }));
    };

    // This is the big one - handles every incoming message.
    sock.onmessage = function(message) {
        var session;

        // logger.log(message);

        // messages come across the wire as raw strings in the data field.
        // parse them into a proper object here.
        var msg = JSON.parse(message.data);

        if(msg.type.indexOf("-err")!=-1) {
            logger.error("Got an error from the server!", message);
            if (msg.type === "chat-err" && msg.args === "Over capacity") {
                messages.trigger("over-capacity");
            }
        }
        // All messages have a type field.
        switch(msg.type) {
            // join an EVENT
            case "join":
                users.add(new models.User(msg.args.user));
                break;

            // leave an EVENT
            case "leave":
                users.remove(users.get(msg.args.user.id));
                break;

            // chat message received
            case "chat":
                messages.add(new models.ChatMessage(msg.args));
                app.vent.trigger("new-chat-message");

                break;

            // the embed for this event has been updated
            case "embed":
                var originalYoutubeId = curEvent.get("youtubeEmbed") || "";

                curEvent.setEmbed(msg.args.ytId);
                logger.log("added yt embed id: " + JSON.stringify(msg.args));
                break;

            case "control-video":
                app.youtubeEmbedView.control(msg.args);
                break;

            case "set-hoa":
                if (_.isNull(msg.args)) {
                    curEvent.setHoA(null);
                } else if (curEvent.get("hoa")) {
                    logger.debug("set hoa attrs", msg.args);
                    curEvent.get("hoa").set(msg.args);
                } else {
                    session = new models.Session(msg.args);
                    curEvent.setHoA(session);
                }
                break;

            case "delete-session":
                session = curEvent.get("sessions").get(msg.args.id);
                // app.paginatedSessions.remove(session);
                curEvent.removeSession(session);

                logger.log("removing session: " + msg.args.id);
                break;

            // create a new session
            case "create-session":
                session = new models.Session(msg.args);

                // this is sort of ugly to have to edit both.
                // i'm not sure the former one is critical, but it is definitely
                // important that we add it to the special paginated sessions list.
                // after startup, we have to edit it directly.
                curEvent.get("sessions").add(session);
                // app.paginatedSessions.add(session);
                break;

            // update the list of a session's not-yet-connected-but-joining participants
            case "joining-participants":
                logger.log("joining participants "+ msg.args.id, msg.args.participants);
                session = curEvent.get("sessions").get(msg.args.id);
                session.set("joiningParticipants", msg.args.participants);
                break;

            // update the list of a session's participants
            case "session-participants":
                logger.log("participants in session "+msg.args.id, msg.args.participants);
                session = curEvent.get("sessions").get(msg.args.id);
                session.setConnectedParticipants(msg.args.participants);
                break;

            // mark a session as having its hangout connected and communicating
            case "session-hangout-connected":
                session = curEvent.get("sessions").get(msg.args.id);
                session.set("hangoutConnected", true);
                break;

            // mark a session as disconnected
            case "session-hangout-disconnected":
                session = curEvent.get("sessions").get(msg.args.id);
                session.setConnectedParticipants([]);
                session.set("hangoutConnected", false);
                break;

            case "open-sessions":
                curEvent.openSessions();
                app.sessionListView.render();
                break;

            case "close-sessions":
                curEvent.closeSessions();
                app.sessionListView.render();
                break;

            // sent in cases when the event's information has been updated.
            // includes the entire event JSON object as the server sees it.
            // copy it into curEvent.
            case "event-update":
                curEvent.set(msg.args);

                logger.log("updated current event: " + JSON.stringify(msg.args));
                break;

            // *-ack message types are just acknowledgmeents from the server
            // of the receipt of a particular message type and that the
            // message was properly formatted and accepted.
            //
            // mostly we don't do anything with these messages, but
            // in some situations we do react to them. They're used
            // more for testing.
            case "auth-ack":
                sock.send(JSON.stringify({type:"join", args:{id:curEvent.getRoomId()}}));
                break;

            case "join-ack":
                logger.log("joined!");
                break;

            case "attend-ack":
                logger.log("attend-ack");
                break;
        }
    };

    // handle losing the connection to the server.
    // we want to put up a notice so the user knows that they've been disconnected (in
    // case they can do anything about it, like unpugged cable or wifi outage)
    // at the same time, we also want to attempt to reconnect if it was a server
    // outage and the server is restarting. So we occasionally ping the server
    // with an http request and when it responds successfully, we reload the page
    // which will trigger a full reconnection and state reset.
    sock.onclose = function() {
        $('#disconnected-modal').modal('show');
        messages.add(new models.ChatMessage({text:"You have been disconnected from the server. Please reload the page to reconnect!"}));

        var checkIfServerUp = function () {
             var ping = document.location;

             $.ajax({
                  url: ping,
                  type: "HEAD",
                  cache: false
              }).done(function() {
                  // reload window when ajax call is successful
                  window.location.reload();
              }).fail(function() {
                  timeout = setTimeout(checkIfServerUp, 1000);
              });
        };
        // Run the first check at a random interval to hopefully spread out
        // requests to a seiged server trying to restart.
        setTimeout(checkIfServerUp, 1000 * Math.random());
    };

    //------------------------------------------------------------------------//
    //                                                                          //
    //                                APP SETUP                                   //
    //                                                                          //
    //------------------------------------------------------------------------//

    // The EVENT_ATTRS constant comes from the event.ejs file. They are the way
    // that the server communicates the initial state of the event to the
    // client - in a big JSON blob. Subsequent updates all happen over the
    // sockJS channel, but the initial state is embedded there.
    curEvent = new models.ClientEvent(EVENT_ATTRS);
    if (HOA_ATTRS) {
        curEvent.set("hoa", new models.Session(HOA_ATTRS));
        curEvent.get("hoa").event = curEvent;
    }
    curEvent.get("sessions").add(EVENT_ATTRS.sessions);
    users = new models.UserList(EVENT_ATTRS.connectedUsers);
    messages = new models.ChatMessageList();

    logger.log("Inflated models.");

    // documentation for Marionette applications can be found here:
    // https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.application.md
    app = new Backbone.Marionette.Application();

    // the notion of regions comes from Marionette.
    // https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.region.md
    //
    // Basically, they give us a way to create containers in the application, that different
    // views are added and removed from. It handles various event cleanup work on add/remove.
    // In this app, we don't often swap stuff in and out. It's primarily just a useful
    // organizational abstraction.
    app.addRegions({
        right: '#main-right',
        main: '#main-left',
        topLeft: '#top-left',
        global: '#global',
        dialogs: '#dialogs',
        admin: '#admin-region',
        bar:'#bar',
        top:'#top'
    });

    // This is code that runs when the application initializes.
    app.addInitializer(function(options) {

        // include the youtube JS api per docs:
        // https://developers.google.com/youtube/iframe_api_reference
        var tag = document.createElement('script');
        tag.src = "//www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        // create all the basic views
        this.sessionListView = new eventViews.SessionListView({
            collection: curEvent.get("sessions"),
            event: curEvent,
            sock: sock
        });
        this.chatView = new eventViews.ChatLayout({
            messages: messages,
            users: users,
            event: curEvent,
            sock: sock
        });
        this.youtubeEmbedView = new eventViews.VideoEmbedView({
            model: curEvent, sock: sock
        });
        this.dialogView = new eventViews.DialogView({
            event: curEvent, sock: sock
        });

        this.aboutView = new eventViews.AboutEventView({model: curEvent});

        // present the views in their respective regions
        this.right.show(this.chatView);
        this.main.show(this.sessionListView);
        this.topLeft.show(this.youtubeEmbedView);
        this.dialogs.show(this.dialogView);
        this.top.show(this.aboutView);

        // this is a little unorthodox, but not sure how else
        // to do it.
        $(this.bar.el).hide();

        // obviously this is not secure, but any admin requests are re-authenticated on
        // the server. Showing the admin UI is harmless if a non-admin messes with it.
        if(IS_ADMIN) {
            this.adminButtonView = new eventViews.AdminButtonView({
                event: curEvent, sock: sock
            });
            curEvent.on("change:sessionsOpen change:start", _.bind(function() {
                this.adminButtonView.render();
            }, this));
            this.admin.show(this.adminButtonView);
        }
        var maybeMute = function() {
            var hoa = curEvent.get("hoa");
            if (hoa && _.findWhere(hoa.get("connectedParticipants"), {id: auth.USER_ID})) {
                app.youtubeEmbedView.control({"mute": true});
            }
        };
        curEvent.on("update-hoa", maybeMute);
        curEvent.on("change:youtubeEmbed", maybeMute);
        maybeMute();

        logger.log("Initialized app.");

        $("#admin-page-for-event").attr("href", "/admin/event/" + curEvent.id);

    }, app);

    app.vent.on("about-nav", _.bind(function(hide) {

        if (_.isUndefined(hide)) {
            hide = aboutShown;
        }

        var el = this.top.$el;

        $(".updated").addClass("hide");
        if (hide) {
            if(!curEvent.isLive()) {
                // don't let people dismiss the about screen if the event isn't live.
                return;
            }

            el.animate({
                "top": -1 * el.outerHeight() - 15
            }, {
                done: function() {
                    el.hide();
                }
            });

            aboutShown = false;
            $("#about-nav").removeClass("active");
        } else {
            el.show().animate({"top":0});
            aboutShown = true;

            $("#about-nav").addClass("active");
        }

    }, app));

    app.start();

    // if the event isn't live yet, force the about page to show.
    if(!curEvent.isLive()) {
        // Force about pane to show itself.
        app.vent.trigger("about-nav", false);
    } else {
        // Make about pane hide itself.
        app.vent.trigger("about-nav", true);
    }

    // Handles clicks on the nav bar links.
    $("#about-nav").click(function(jqevt) {
        jqevt.preventDefault();
        app.vent.trigger("about-nav");
    });

    logger.log("Setup regions.");

});

});
<|endoftext|>


<commit_before> function doClick(e) {
     alert($.label.text);
}
//
// $.index.open();

// Add in the module
var MapModule = require('ti.map');
var win = Ti.UI.createWindow({backgroundColor: 'white'});

//believe this enables the app to find the location of the device
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;

//
//  Sets the distance filter
//Dictates how often an event fires based on the distance the device moves
//  this value is in meters
//
Titanium.Geolocation.distanceFilter = 10;

Titanium.Geolocation.getCurrentPosition(function(e)
{
    if (e.error)
    {
        alert('Cannot get your current location');
        return;
    }

    var longitude = e.coords.longitude;
    var latitude = e.coords.latitude;
    var altitude = e.coords.altitude;
    var heading = e.coords.heading;
    var accuracy = e.coords.accuracy;
    var speed = e.coords.speed;
    var timestamp = e.coords.timestamp;
    var altitudeAccuracy = e.coords.altitudeAccuracy;

var opera = MapModule.createAnnotation({
    latitude: 35.13314,
    longitude: -101.897468,
    title: 'Valero Energy',
    subtitle: '7201 CANYON DR, Amarillo,TX'
});
var bridge = MapModule.createAnnotation({
    latitude: 35.221803,
    longitude: -101.848697,
    pincolor: MapModule.ANNOTATION_AZURE,
 // Even though we are creating a button, it does not respond to Button events or animates.
 // Use the Map View's click event and monitor the clicksource property for 'leftPane'.
    leftView: Ti.UI.createButton({title: 'Detail'}),
 // For eventing, use the Map View's click event
 // and monitor the clicksource property for 'rightPane'.
    rightButton: 'appicon.jpg',
    title: '1425 UNIVERSITY NE/',
    subtitle: 'Valero Station, Amarillo,TX'
});

//creates map - Nhat/Ez
var map1 = MapModule.createView({
    userLocation: true,
    mapType: MapModule.NORMAL_TYPE,
    animate: true,
    region: {latitude: latitude, longitude: longitude, latitudeDelta: 0.1, longitudeDelta: 0.1 },
    // latitude: 35.13314, longitude: -101.897468
    height: Titanium.UI.FILL,
    width: Titanium.UI.FILL,
	annotations:[bridge,opera]
});

win.add(map1);
win.open();
});

//
//
// var MapModule = require('ti.map');
// var win = Ti.UI.createWindow({backgroundColor: 'white'});
// var opera = MapModule.createAnnotation({
    // latitude: -33.8569,
    // longitude: 151.2153,
    // title: 'Sydney Opera House',
    // subtitle: 'Sydney, New South Wales, Australia'
// });
// var bridge = MapModule.createAnnotation({
    // latitude: -33.852222,
    // longitude: 151.210556,
    // pincolor: MapModule.ANNOTATION_AZURE,
 // // Even though we are creating a button, it does not respond to Button events or animates.
 // // Use the Map View's click event and monitor the clicksource property for 'leftPane'.
    // leftView: Ti.UI.createButton({title: 'Detail'}),
 // // For eventing, use the Map View's click event
 // // and monitor the clicksource property for 'rightPane'.
    // rightButton: 'appicon.jpg',
    // title: 'Sydney Harbour Bridge',
    // subtitle: 'Port Jackson'
// });
// var random = MapModule.createAnnotation({
    // latitude: -33.87365,
    // longitude: 151.20689,
    // pincolor: MapModule.ANNOTATION_VIOLET,
 // // Even though we are creating a label, it does not respond to Label events.
 // // Use the Map View's events instead.
    // customView: Ti.UI.createLabel({
        // text: 'MOVE ME!',
        // opacity: '80%',
        // color: 'red',
        // backgroundColor: 'gray',
        // font: {
            // fontSize: '16dp',
            // fontWeight: 'bold'
        // }
    // }),
    // draggable: true
// });
// var mapview = MapModule.createView({
    // mapType: MapModule.NORMAL_TYPE,
    // region: {latitude: -33.87365, longitude: 151.20689, latitudeDelta: 0.1, longitudeDelta: 0.1 },
    // annotations: [bridge,opera] //< add these annotations upon creation
// });
// // Add this annotation after creation
// mapview.addAnnotation(random);
// win.add(mapview);
// win.open();<commit_msg>added route code(attempt one)<commit_after> function doClick(e) {
     alert($.label.text);
}
//
// $.index.open();

// Add in the module
var MapModule = require('ti.map');
var win = Ti.UI.createWindow({backgroundColor: 'white'});

//believe this enables the app to find the location of the device
Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;

//
//  Sets the distance filter
//Dictates how often an event fires based on the distance the device moves
//  this value is in meters
//
Titanium.Geolocation.distanceFilter = 10;

Titanium.Geolocation.getCurrentPosition(function(e)
{
    if (e.error)
    {
        alert('Cannot get your current location');
        return;
    }

    var longitude = e.coords.longitude;
    var latitude = e.coords.latitude;
    var altitude = e.coords.altitude;
    var heading = e.coords.heading;
    var accuracy = e.coords.accuracy;
    var speed = e.coords.speed;
    var timestamp = e.coords.timestamp;
    var altitudeAccuracy = e.coords.altitudeAccuracy;

var opera = MapModule.createAnnotation({
    latitude: 35.13314,
    longitude: -101.897468,
    title: 'Valero Energy',
    subtitle: '7201 CANYON DR, Amarillo,TX'
});
var bridge = MapModule.createAnnotation({
    latitude: 35.221803,
    longitude: -101.848697,
    pincolor: MapModule.ANNOTATION_AZURE,
 // Even though we are creating a button, it does not respond to Button events or animates.
 // Use the Map View's click event and monitor the clicksource property for 'leftPane'.
    leftView: Ti.UI.createButton({title: 'Detail'}),
 // For eventing, use the Map View's click event
 // and monitor the clicksource property for 'rightPane'.
    rightButton: 'appicon.jpg',
    title: '1425 UNIVERSITY NE/',
    subtitle: 'Valero Station, Amarillo,TX'
});

//creates map - Nhat/Ez
var map1 = MapModule.createView({
    userLocation: true,
    mapType: MapModule.NORMAL_TYPE,
    animate: true,
    region: {latitude: latitude, longitude: longitude, latitudeDelta: 0.1, longitudeDelta: 0.1 },
    // latitude: 35.13314, longitude: -101.897468
    height: Titanium.UI.FILL,
    width: Titanium.UI.FILL,
	annotations:[bridge,opera]
});

var route = MapModule.createRoute({
    width: 4,
    color: '#f00',
    points: [
        {latitude:opera.latitude, longitude:opera.longitude},
        {latitude:bridge.latitude, longitude:bridge.longitude},
    ]
});
var mapview = MapModule.createView({
    mapType: MapModule.NORMAL_TYPE,
    region: {latitude: latitude, longitude: longitude, latitudeDelta: 0.2, longitudeDelta: 0.2},
    annotations: [opera,bridge]
});
mapview.addRoute(route);

win.add(map1);
win.open();
});

//
//
// var MapModule = require('ti.map');
// var win = Ti.UI.createWindow({backgroundColor: 'white'});
// var opera = MapModule.createAnnotation({
    // latitude: -33.8569,
    // longitude: 151.2153,
    // title: 'Sydney Opera House',
    // subtitle: 'Sydney, New South Wales, Australia'
// });
// var bridge = MapModule.createAnnotation({
    // latitude: -33.852222,
    // longitude: 151.210556,
    // pincolor: MapModule.ANNOTATION_AZURE,
 // // Even though we are creating a button, it does not respond to Button events or animates.
 // // Use the Map View's click event and monitor the clicksource property for 'leftPane'.
    // leftView: Ti.UI.createButton({title: 'Detail'}),
 // // For eventing, use the Map View's click event
 // // and monitor the clicksource property for 'rightPane'.
    // rightButton: 'appicon.jpg',
    // title: 'Sydney Harbour Bridge',
    // subtitle: 'Port Jackson'
// });
// var random = MapModule.createAnnotation({
    // latitude: -33.87365,
    // longitude: 151.20689,
    // pincolor: MapModule.ANNOTATION_VIOLET,
 // // Even though we are creating a label, it does not respond to Label events.
 // // Use the Map View's events instead.
    // customView: Ti.UI.createLabel({
        // text: 'MOVE ME!',
        // opacity: '80%',
        // color: 'red',
        // backgroundColor: 'gray',
        // font: {
            // fontSize: '16dp',
            // fontWeight: 'bold'
        // }
    // }),
    // draggable: true
// });
// var mapview = MapModule.createView({
    // mapType: MapModule.NORMAL_TYPE,
    // region: {latitude: -33.87365, longitude: 151.20689, latitudeDelta: 0.1, longitudeDelta: 0.1 },
    // annotations: [bridge,opera] //< add these annotations upon creation
// });
// // Add this annotation after creation
// mapview.addAnnotation(random);
// win.add(mapview);
// win.open();<|endoftext|>


<commit_before>import Flax from 'flax';
import CounterActions from '../actions/CounterActions.jsx';

const CounterStore = Flax.createStore({
  displayName: 'CounterStore',

  getInitialState: function() {
    return {
      x: 5
    }
  },

  getActionBinds() {
    return [
      [CounterActions.incX, this._handleIncX],
      [CounterActions.decX, this._handleDecX]
    ];
  },

  events: {
    INC_X: null,
    DEC_X: null
  },

  getters: {
    getX() {
      return this.state.x;
    }
  },

  _handleIncX() {
    this.state.x = this.state.x > 9 ? 10 : this.state.x + 1;

    this.emitChange(this.INC_X);
    // this.emitChange(this.events.INC_X);
  },

  _handleDecX() {
    this.state.x = this.state.x < 1 ? 0 : this.state.x - 1;

    this.emitChange(this.DEC_X.append(2));
  }
});

export default CounterStore;<commit_msg>Small fix in CounterStore syntax<commit_after>import Flax from 'flax';
import CounterActions from '../actions/CounterActions.jsx';

const CounterStore = Flax.createStore({
  displayName: 'CounterStore',

  getInitialState() {
    return {
      x: 5
    };
  },

  getActionBinds() {
    return [
      [CounterActions.incX, this._handleIncX],
      [CounterActions.decX, this._handleDecX]
    ];
  },

  events: {
    INC_X: null,
    DEC_X: null
  },

  getters: {
    getX() {
      return this.state.x;
    }
  },

  _handleIncX() {
    this.state.x = this.state.x > 9 ? 10 : this.state.x + 1;

    this.emitChange(this.INC_X);
    // this.emitChange(this.events.INC_X);
  },

  _handleDecX() {
    this.state.x = this.state.x < 1 ? 0 : this.state.x - 1;

    this.emitChange(this.DEC_X.append(2));
  }
});

export default CounterStore;<|endoftext|>


<commit_before>'use strict';

// A wrapper to retrieve, validate and decode CF OAuth token

const { difference, each, isEmpty, intersection, pick } = require('underscore');

const jwt = require('jsonwebtoken');
const lru = require('abacus-lrucache');
const request = require('abacus-request');
const retry = require('abacus-retry');
const basic = require('abacus-basic');

const isBasicRequest = basic.check.isBasicRequest;
const basicCredentials = basic.credentials;

const debug = require('abacus-debug')('abacus-oauth');
const edebug = require('abacus-debug')('e-abacus-oauth');

// retry GET and POST 5 times (default) with randomized (default) exponential back-off [200ms, 5s)
const get = retry(request.get, undefined, 200, 5000);
const post = retry(request.post, undefined, 200, 5000);

const tokenEndpoints = lru({
  max: 100,
  maxAge: 1000 * 60 * 60 // 1 hour
});

const defaultTimeout = 120000;
const shortlyBefore = 500;

// Retrieve token endpoint from an authorization server
const tokenEndpoint = (apiHostName, cb) => {
  debug('Retrieving token endpoint information from authorization server %o', apiHostName);

  const cachedEndpoint = tokenEndpoints.get(apiHostName);
  if (cachedEndpoint) {
    debug('Retrieved token endpoint %o from cache', cachedEndpoint);
    setImmediate(() => cb(undefined, cachedEndpoint));
  } else
    /* eslint complexity: [1, 7] */
    get(apiHostName + '/v2/info', (err, val) => {
      if (err) {
        debug('Error getting OAuth server information, %o', err);
        cb(err);
        return;
      }

      if (val.statusCode >= 400) {
        debug(
          '%s - %s - has returned an error - response %d' + (val.body ? ' %o' : '%s'),
          val.request.method,
          val.request.path,
          val.statusCode,
          val.body || ''
        );
        cb(new Error('Unable to get OAuth server information'));
        return;
      }

      debug('Retrieved token endpoint %o from authorization server', val.body.token_endpoint);

      // Return endpoint host
      if (val.body && val.body.token_endpoint) {
        tokenEndpoints.set(apiHostName, val.body.token_endpoint);
        cb(undefined, val.body.token_endpoint);
      } else cb(new Error('Unable to get token endpoint from oauth server'));
    });
};

// Retrieve token from the endpoint using client credentials
// OAuth trusted client flow.
const newToken = (endpoint, path, clientId, secret, scopes, cb) => {
  debug('Retrieving token from endpoint %o with client %s and scopes %s', endpoint, clientId, scopes);

  post(
    `${endpoint}/${path}?grant_type=client_credentials` + (scopes ? '&scope=' + encodeURIComponent(scopes) : ''),
    {
      headers: {
        authorization: 'Basic ' + new Buffer(clientId + ':' + secret).toString('base64')
      }
    },
    (err, val) => {
      if (err) {
        debug('Error getting token : %o', err);
        cb(err);
        return;
      }

      if (val.statusCode >= 400) {
        debug('Error getting token, response %s, error %o', val.statusCode, val.body || '');
        cb(new Error('Unable to get OAuth token'));
        return;
      }

      cb(undefined, val.body);
    }
  );
};

// Decode token and return its JSON representation.
// The complete token, including header and signature is returned
const decode = (token) => {
  return jwt.decode(token, {
    complete: true
  });
};

// Retrieve the scope array from the token
const getScope = (token) => {
  return decode(token).payload.scope;
};

// Retrieve pair of properties describing user: user_id and user_name
// or a client: client_id
const getUserInfo = (token) => {
  const decoded = decode(token);
  if (decoded === null) {
    debug('Invalid token: %o', token);
    return undefined;
  }
  return pick(decoded.payload, decoded.payload.user_id ? ['user_id', 'user_name'] : 'client_id');
};

// Validate token signature with the given secret and algorithm.
// It is an error not to provide algorithm as the one specified in the
// token cannot be trusted
// Returns decoded token
const validate = (token, secret, algorithm, cb) => {
  let decoded;
  try {
    decoded = jwt.verify(token, secret, { algorithms: algorithm });
  } catch (error) {
    debug('Token validation failed %o', error);
    cb(error);
    return;
  }
  debug('Token validated successfully');
  cb(null, decoded);
};

// Return an Express middleware that verifies an oauth bearer access token
const validator = (secret, algorithm) => {
  return (req, res, next) => {
    debug('Authenticating request using OAuth bearer access token');

    // Check authorization header field for a bearer access token
    // then verify the access token using jwt
    if (req.headers && req.headers.authorization && /^bearer /i.test(req.headers.authorization)) {
      debug('Validating OAuth bearer access token');

      validate(req.headers.authorization.replace(/^bearer /i, ''), secret, algorithm, (err, val) => {
        if (err) {
          edebug('OAuth bearer access token validation failed, %s', err.message);
          debug('OAuth bearer access token validation failed, %s', err.message);

          res
            .status(401)
            .header(
              'WWW-Authenticate',
              `Bearer realm="cf", error="invalid_token", error_description="${err.message}"`
            )
            .end();
          return;
        }

        debug('Validated OAuth bearer access token');
        // has a valid token, so proceed to process the request
        next();
      });
    } else {
      edebug('Invalid OAuth bearer access token, %o', req.headers ? req.headers.authorization : '');
      debug('Invalid OAuth bearer access token, %o', req.headers ? req.headers.authorization : '');

      res
        .status(401)
        .header('WWW-Authenticate', 'Bearer realm="cf"')
        .end();
    }
  };
};

const scopesMissing = (scopes) => !scopes || scopes.length === 0;

const allScopesContained = (wantedScopes, scopes) => difference(wantedScopes, scopes).length === 0;

const anyScopeContained = (wantedScopes, scopes) => intersection(wantedScopes, scopes).length > 0;

const containsRequiredScopes = (expectedScope, scopes) => {
  if (anyScopeContained(expectedScope.system, scopes)) return true;

  return !scopesMissing(expectedScope.resource) && allScopesContained(expectedScope.resource, scopes);
};

const buildError = (statusCode, header) => {
  const error = new Error();
  error.statusCode = statusCode;
  error.header = header;
  return error;
};

// Authorize a given OAuth bearer access token using expected scope
// Expected scope is undefined when no authorization needed
// Expected scope has two parts: resource scope  and/or system scope
// Expect the token to have all of the resource scopes or
// at least one of the system scopes
const authorize = (auth, expectedScope) => {
  debug('Authorizing OAuth token using expected OAuth scope, %o', expectedScope);

  // Authorization not required
  if (!expectedScope || isEmpty(expectedScope)) {
    debug('Authorization not required');
    return;
  }

  let authScopes = [];
  try {
    // Get scope from OAuth bearer access token
    authScopes = getScope(auth.replace(/^bearer /i, ''));
  } catch (exception) {
    edebug('Exception when checking authorization, %o', exception);
    debug('Exception when checking authorization, %o', exception);

    throw buildError(401, {
      'WWW-Authenticate': 'Bearer realm="cf", error="invalid_token", error_description="malformed"'
    });
  }

  if (!containsRequiredScopes(expectedScope, authScopes)) {
    // Request does not have expected scopes
    edebug('Unauthorized request with scope %o', authScopes);
    debug('Unauthorized request with scope %o', authScopes);

    throw buildError(403,{
      'WWW-Authenticate':
        `Bearer realm="cf", error="insufficient_scope", error_description="${expectedScope.resource || ''}"`
    });
  }

  debug('Authorized request with scope %o', authScopes);
};

const authorizer = (secret, algorithm, scopes) => {
  const validate = validator(secret, algorithm);
  return (req, res, next) => {
    validate(req, res, () => {
      const authHeader = req && req.headers && req.headers.authorization;
      try {
        authorize(authHeader, {
          resource: scopes
        });
      } catch (err) {
        res
          .status(err.statusCode)
          .header('WWW-Authenticate', err.header['WWW-Authenticate'])
          .end();
        return;
      }
      next();
    });
  };
};

const cache = (authServer, id, secret, scopes, path = 'oauth/token', isAuthServer = false) => {
  // Store OAuth bearer access token for reuse
  let token;

  // Wrapper to get OAuth bearer access token
  const wrapper = () => token ? 'Bearer ' + token.access_token : undefined;

  // Get a OAuth bearer access token and then
  // start a timer to refresh the token 2 minutes before expiration
  wrapper.start = (cb) => {
    let cbCalled = false;

    const done = (err) => {
      if (!cbCalled && cb) {
        // callback only one time
        cbCalled = true;
        cb(err);
      }
    };

    if (token) {
      done();
      return;
    }

    // Schedule a timer to refresh OAuth bearer access token
    const refresh = (after) => {
      debug('Scheduling refresh/retry getting OAuth bearer access token after %d msecs', after);
      setTimeout(() => get(), after).unref();
    };

    // Report the error and retry after 2 minutes
    const error = (err) => {
      edebug('Error getting OAuth bearer access token, %o', err);
      debug('Error getting OAuth bearer access token, %o', err);

      // Retry after 2 minutes
      refresh(defaultTimeout);
      done(err);
    };

    const getToken = (endpoint) => {
      debug(
        'Getting OAuth bearer access token from endpoint %s for client %s and scopes %s',
        endpoint,
        id,
        scopes
      );

      newToken(endpoint, path, id, secret, scopes, (err, t) => {
        if (err) {
          error(err);
          return;
        }

        debug('Got OAuth bearer access token');
        token = t;
        // Convert token expiration period from seconds to milliseconds
        // As expires_in is optional, use 2 minutes (~= HTTP timeout) by default
        const expirationInMs = token.expires_in ? token.expires_in * 1000 : defaultTimeout;

        // refresh "shortly before" expiration
        const before = Math.min(Math.abs(expirationInMs - shortlyBefore), expirationInMs);
        refresh(before);

        done();
      });
    };

    // Get OAuth bearer access token
    const get = () => {
      if (isAuthServer)
        getToken(authServer);
      else
        tokenEndpoint(authServer, (err, endpoint) => {
          if (err) {
            error(err);
            return;
          }

          getToken(endpoint);
        });
    };

    // start to get OAuth bearer access token
    get();
  };

  return wrapper;
};

// Get OAuth bearer access token
const getBearerToken = (authServer, id, secret, scopes, cb) => {
  // Get token endpoint from OAuth server
  debug('Getting OAuth bearer access token from endpoint %s for client %s and scopes %o', authServer, id, scopes);
  tokenEndpoint(authServer, (err, endpoint) => {
    if (err) {
      edebug('Error getting OAuth bearer access token, %o', err);
      debug('Error getting OAuth bearer access token, %o', err);
      cb(err, undefined);
      return;
    }

    // Get token endpoint from OAuth token endpoint
    newToken(endpoint, 'oauth/token', id, secret, scopes, (err, t) => {
      if (err) {
        edebug('Error getting OAuth bearer access token, %o', err);
        debug('Error getting OAuth bearer access token, %o', err);
        cb(err, undefined);
        return;
      }

      // Return the OAuth bearer access token
      debug('Got OAuth bearer access token');
      cb(undefined, 'Bearer ' + t.access_token);
    });
  });
};

// Return an Express middleware that verifies basic authentication
const basicStrategy = (authServer, scopes, secret, algorithm) => (req, res, next) => {
  debug('Authenticating request using basic strategy');

  if (isBasicRequest(req))
    try {
      const { username, password } = basicCredentials.fromRequest(req);
      getBearerToken(authServer, username, password, scopes, (err, token) => {
        if (err) {
          edebug('Error while retrieving bearer token due to %o', err);
          res.status(500).send({ error: err.message });
          return;
        }
        validate(token.replace(/^bearer /i, ''), secret, algorithm, (err, decoded) => {
          if (err) {
            edebug('OAuth bearer access token validation failed, %s', err.message);

            res
              .status(401)
              .header(
                'WWW-Authenticate',
                `Bearer realm="cf", error="invalid_token", error_description="${err.message}"`
              )
              .end();
            return;
          }

          debug('Validated OAuth bearer access token');
          next();
        });
      });
    } catch (e) {
      edebug('Error decoding basic auth token due to %o', e);
      res
        .status(e.statusCode)
        .header(e.header)
        .end();
    }
  else {
    edebug('Invalid authorization token, %o', req.headers ? req.headers.authorization : '');

    res
      .status(401)
      .header('WWW-Authenticate', 'Basic realm="cf"')
      .end();
  }
};

const parseScopes = (scopes) => {
  const result = {
    readResourceScopes: [],
    writeResourceScopes: [],
    hasSystemReadScope: false,
    hasSystemWriteScope: false
  };

  each(scopes, (scope) => {
    if (scope.match('abacus.usage.*(read|write)')) {
      let resource = scope.substring('abacus.usage.'.length);
      if (resource.endsWith('read'))
        if (resource === 'read') result.hasSystemReadScope = true;
        else result.readResourceScopes.push(resource.substring(0, resource.length - '.read'.length));
      else if (resource === 'write') result.hasSystemWriteScope = true;
      else result.writeResourceScopes.push(resource.substring(0, resource.length - '.write'.length));
    }
  });
  return result;
};

const parseTokenScope = (auth) => {
  if (!auth)
    throw buildError(401, {
      'WWW-Authenticate': 'Bearer realm="cf", error="invalid_token", error_description="malformed"'
    });
  const token = auth.replace(/^bearer /i, '');
  const scopes = getScope(token);
  return parseScopes(scopes);
};

module.exports.cache = cache;
module.exports.validate = validate;
module.exports.validator = validator;
module.exports.authorize = authorize;
module.exports.authorizer = authorizer;
module.exports.getUserInfo = getUserInfo;
module.exports.getBearerToken = getBearerToken;
module.exports.basicStrategy = basicStrategy;
module.exports.parseTokenScope = parseTokenScope;
module.exports.parseScopes = parseScopes;
<commit_msg>Remove oauth redundant debug messages (#1076)<commit_after>'use strict';

// A wrapper to retrieve, validate and decode CF OAuth token

const { difference, each, isEmpty, intersection, pick } = require('underscore');

const jwt = require('jsonwebtoken');
const lru = require('abacus-lrucache');
const request = require('abacus-request');
const retry = require('abacus-retry');
const basic = require('abacus-basic');

const isBasicRequest = basic.check.isBasicRequest;
const basicCredentials = basic.credentials;

const debug = require('abacus-debug')('abacus-oauth');
const edebug = require('abacus-debug')('e-abacus-oauth');

// retry GET and POST 5 times (default) with randomized (default) exponential back-off [200ms, 5s)
const get = retry(request.get, undefined, 200, 5000);
const post = retry(request.post, undefined, 200, 5000);

const tokenEndpoints = lru({
  max: 100,
  maxAge: 1000 * 60 * 60 // 1 hour
});

const defaultTimeout = 120000;
const shortlyBefore = 500;

// Retrieve token endpoint from an authorization server
const tokenEndpoint = (apiHostName, cb) => {
  debug('Retrieving token endpoint information from authorization server %o', apiHostName);

  const cachedEndpoint = tokenEndpoints.get(apiHostName);
  if (cachedEndpoint) {
    debug('Retrieved token endpoint %o from cache', cachedEndpoint);
    setImmediate(() => cb(undefined, cachedEndpoint));
  } else
    /* eslint complexity: [1, 7] */
    get(apiHostName + '/v2/info', (err, val) => {
      if (err) {
        debug('Error getting OAuth server information, %o', err);
        cb(err);
        return;
      }

      if (val.statusCode >= 400) {
        debug(
          '%s - %s - has returned an error - response %d' + (val.body ? ' %o' : '%s'),
          val.request.method,
          val.request.path,
          val.statusCode,
          val.body || ''
        );
        cb(new Error('Unable to get OAuth server information'));
        return;
      }

      debug('Retrieved token endpoint %o from authorization server', val.body.token_endpoint);

      // Return endpoint host
      if (val.body && val.body.token_endpoint) {
        tokenEndpoints.set(apiHostName, val.body.token_endpoint);
        cb(undefined, val.body.token_endpoint);
      } else cb(new Error('Unable to get token endpoint from oauth server'));
    });
};

// Retrieve token from the endpoint using client credentials
// OAuth trusted client flow.
const newToken = (endpoint, path, clientId, secret, scopes, cb) => {
  debug('Retrieving token from endpoint %o with client %s and scopes %s', endpoint, clientId, scopes);

  post(
    `${endpoint}/${path}?grant_type=client_credentials` + (scopes ? '&scope=' + encodeURIComponent(scopes) : ''),
    {
      headers: {
        authorization: 'Basic ' + new Buffer(clientId + ':' + secret).toString('base64')
      }
    },
    (err, val) => {
      if (err) {
        debug('Error getting token : %o', err);
        cb(err);
        return;
      }

      if (val.statusCode >= 400) {
        debug('Error getting token, response %s, error %o', val.statusCode, val.body || '');
        cb(new Error('Unable to get OAuth token'));
        return;
      }

      cb(undefined, val.body);
    }
  );
};

// Decode token and return its JSON representation.
// The complete token, including header and signature is returned
const decode = (token) => {
  return jwt.decode(token, {
    complete: true
  });
};

// Retrieve the scope array from the token
const getScope = (token) => {
  return decode(token).payload.scope;
};

// Retrieve pair of properties describing user: user_id and user_name
// or a client: client_id
const getUserInfo = (token) => {
  const decoded = decode(token);
  if (decoded === null) {
    debug('Invalid token: %o', token);
    return undefined;
  }
  return pick(decoded.payload, decoded.payload.user_id ? ['user_id', 'user_name'] : 'client_id');
};

// Validate token signature with the given secret and algorithm.
// It is an error not to provide algorithm as the one specified in the
// token cannot be trusted
// Returns decoded token
const validate = (token, secret, algorithm, cb) => {
  let decoded;
  try {
    decoded = jwt.verify(token, secret, { algorithms: algorithm });
  } catch (error) {
    debug('Token validation failed %o', error);
    cb(error);
    return;
  }
  debug('Token validated successfully');
  cb(null, decoded);
};

// Return an Express middleware that verifies an oauth bearer access token
const validator = (secret, algorithm) => {
  return (req, res, next) => {
    debug('Authenticating request using OAuth bearer access token');

    // Check authorization header field for a bearer access token
    // then verify the access token using jwt
    if (req.headers && req.headers.authorization && /^bearer /i.test(req.headers.authorization)) {
      debug('Validating OAuth bearer access token');

      validate(req.headers.authorization.replace(/^bearer /i, ''), secret, algorithm, (err, val) => {
        if (err) {
          edebug('OAuth bearer access token validation failed, %s', err.message);

          res
            .status(401)
            .header(
              'WWW-Authenticate',
              `Bearer realm="cf", error="invalid_token", error_description="${err.message}"`
            )
            .end();
          return;
        }

        debug('Validated OAuth bearer access token');
        // has a valid token, so proceed to process the request
        next();
      });
    } else {
      edebug('Invalid OAuth bearer access token, %o', req.headers ? req.headers.authorization : '');

      res
        .status(401)
        .header('WWW-Authenticate', 'Bearer realm="cf"')
        .end();
    }
  };
};

const scopesMissing = (scopes) => !scopes || scopes.length === 0;

const allScopesContained = (wantedScopes, scopes) => difference(wantedScopes, scopes).length === 0;

const anyScopeContained = (wantedScopes, scopes) => intersection(wantedScopes, scopes).length > 0;

const containsRequiredScopes = (expectedScope, scopes) => {
  if (anyScopeContained(expectedScope.system, scopes)) return true;

  return !scopesMissing(expectedScope.resource) && allScopesContained(expectedScope.resource, scopes);
};

const buildError = (statusCode, header) => {
  const error = new Error();
  error.statusCode = statusCode;
  error.header = header;
  return error;
};

// Authorize a given OAuth bearer access token using expected scope
// Expected scope is undefined when no authorization needed
// Expected scope has two parts: resource scope  and/or system scope
// Expect the token to have all of the resource scopes or
// at least one of the system scopes
const authorize = (auth, expectedScope) => {
  debug('Authorizing OAuth token using expected OAuth scope, %o', expectedScope);

  // Authorization not required
  if (!expectedScope || isEmpty(expectedScope)) {
    debug('Authorization not required');
    return;
  }

  let authScopes = [];
  try {
    // Get scope from OAuth bearer access token
    authScopes = getScope(auth.replace(/^bearer /i, ''));
  } catch (exception) {
    edebug('Exception when checking authorization, %o', exception);

    throw buildError(401, {
      'WWW-Authenticate': 'Bearer realm="cf", error="invalid_token", error_description="malformed"'
    });
  }

  if (!containsRequiredScopes(expectedScope, authScopes)) {
    // Request does not have expected scopes
    edebug('Unauthorized request with scope %o', authScopes);

    throw buildError(403,{
      'WWW-Authenticate':
        `Bearer realm="cf", error="insufficient_scope", error_description="${expectedScope.resource || ''}"`
    });
  }

  debug('Authorized request with scope %o', authScopes);
};

const authorizer = (secret, algorithm, scopes) => {
  const validate = validator(secret, algorithm);
  return (req, res, next) => {
    validate(req, res, () => {
      const authHeader = req && req.headers && req.headers.authorization;
      try {
        authorize(authHeader, {
          resource: scopes
        });
      } catch (err) {
        res
          .status(err.statusCode)
          .header('WWW-Authenticate', err.header['WWW-Authenticate'])
          .end();
        return;
      }
      next();
    });
  };
};

const cache = (authServer, id, secret, scopes, path = 'oauth/token', isAuthServer = false) => {
  // Store OAuth bearer access token for reuse
  let token;

  // Wrapper to get OAuth bearer access token
  const wrapper = () => token ? 'Bearer ' + token.access_token : undefined;

  // Get a OAuth bearer access token and then
  // start a timer to refresh the token 2 minutes before expiration
  wrapper.start = (cb) => {
    let cbCalled = false;

    const done = (err) => {
      if (!cbCalled && cb) {
        // callback only one time
        cbCalled = true;
        cb(err);
      }
    };

    if (token) {
      done();
      return;
    }

    // Schedule a timer to refresh OAuth bearer access token
    const refresh = (after) => {
      debug('Scheduling refresh/retry getting OAuth bearer access token after %d msecs', after);
      setTimeout(() => get(), after).unref();
    };

    // Report the error and retry after 2 minutes
    const error = (err) => {
      edebug('Error getting OAuth bearer access token, %o', err);

      // Retry after 2 minutes
      refresh(defaultTimeout);
      done(err);
    };

    const getToken = (endpoint) => {
      debug(
        'Getting OAuth bearer access token from endpoint %s for client %s and scopes %s',
        endpoint,
        id,
        scopes
      );

      newToken(endpoint, path, id, secret, scopes, (err, t) => {
        if (err) {
          error(err);
          return;
        }

        debug('Got OAuth bearer access token');
        token = t;
        // Convert token expiration period from seconds to milliseconds
        // As expires_in is optional, use 2 minutes (~= HTTP timeout) by default
        const expirationInMs = token.expires_in ? token.expires_in * 1000 : defaultTimeout;

        // refresh "shortly before" expiration
        const before = Math.min(Math.abs(expirationInMs - shortlyBefore), expirationInMs);
        refresh(before);

        done();
      });
    };

    // Get OAuth bearer access token
    const get = () => {
      if (isAuthServer)
        getToken(authServer);
      else
        tokenEndpoint(authServer, (err, endpoint) => {
          if (err) {
            error(err);
            return;
          }

          getToken(endpoint);
        });
    };

    // start to get OAuth bearer access token
    get();
  };

  return wrapper;
};

// Get OAuth bearer access token
const getBearerToken = (authServer, id, secret, scopes, cb) => {
  // Get token endpoint from OAuth server
  debug('Getting OAuth bearer access token from endpoint %s for client %s and scopes %o', authServer, id, scopes);
  tokenEndpoint(authServer, (err, endpoint) => {
    if (err) {
      edebug('Error getting OAuth bearer access token, %o', err);

      cb(err, undefined);
      return;
    }

    // Get token endpoint from OAuth token endpoint
    newToken(endpoint, 'oauth/token', id, secret, scopes, (err, t) => {
      if (err) {
        edebug('Error getting OAuth bearer access token, %o', err);

        cb(err, undefined);
        return;
      }

      // Return the OAuth bearer access token
      debug('Got OAuth bearer access token');
      cb(undefined, 'Bearer ' + t.access_token);
    });
  });
};

// Return an Express middleware that verifies basic authentication
const basicStrategy = (authServer, scopes, secret, algorithm) => (req, res, next) => {
  debug('Authenticating request using basic strategy');

  if (isBasicRequest(req))
    try {
      const { username, password } = basicCredentials.fromRequest(req);
      getBearerToken(authServer, username, password, scopes, (err, token) => {
        if (err) {
          edebug('Error while retrieving bearer token due to %o', err);
          res.status(500).send({ error: err.message });
          return;
        }
        validate(token.replace(/^bearer /i, ''), secret, algorithm, (err, decoded) => {
          if (err) {
            edebug('OAuth bearer access token validation failed, %s', err.message);

            res
              .status(401)
              .header(
                'WWW-Authenticate',
                `Bearer realm="cf", error="invalid_token", error_description="${err.message}"`
              )
              .end();
            return;
          }

          debug('Validated OAuth bearer access token');
          next();
        });
      });
    } catch (e) {
      edebug('Error decoding basic auth token due to %o', e);
      res
        .status(e.statusCode)
        .header(e.header)
        .end();
    }
  else {
    edebug('Invalid authorization token, %o', req.headers ? req.headers.authorization : '');

    res
      .status(401)
      .header('WWW-Authenticate', 'Basic realm="cf"')
      .end();
  }
};

const parseScopes = (scopes) => {
  const result = {
    readResourceScopes: [],
    writeResourceScopes: [],
    hasSystemReadScope: false,
    hasSystemWriteScope: false
  };

  each(scopes, (scope) => {
    if (scope.match('abacus.usage.*(read|write)')) {
      let resource = scope.substring('abacus.usage.'.length);
      if (resource.endsWith('read'))
        if (resource === 'read') result.hasSystemReadScope = true;
        else result.readResourceScopes.push(resource.substring(0, resource.length - '.read'.length));
      else if (resource === 'write') result.hasSystemWriteScope = true;
      else result.writeResourceScopes.push(resource.substring(0, resource.length - '.write'.length));
    }
  });
  return result;
};

const parseTokenScope = (auth) => {
  if (!auth)
    throw buildError(401, {
      'WWW-Authenticate': 'Bearer realm="cf", error="invalid_token", error_description="malformed"'
    });
  const token = auth.replace(/^bearer /i, '');
  const scopes = getScope(token);
  return parseScopes(scopes);
};

module.exports.cache = cache;
module.exports.validate = validate;
module.exports.validator = validator;
module.exports.authorize = authorize;
module.exports.authorizer = authorizer;
module.exports.getUserInfo = getUserInfo;
module.exports.getBearerToken = getBearerToken;
module.exports.basicStrategy = basicStrategy;
module.exports.parseTokenScope = parseTokenScope;
module.exports.parseScopes = parseScopes;
<|endoftext|>