<commit_before>module.exports = {
  /**
   * res.ok default success response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data opctional data
   */
  ok: function okResponse(data) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(200);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:okResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // if is edit record use the redirectTo feature
        if (req.method == 'POST' && res.locals.action == 'edit' && res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        }
        return res.view(data);
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  /**
   * Record created response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data record data
   */
  created: function createdResponse(data) {

    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(201);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:createdResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // redirect if are one html response
        if (res.locals.skipRedirect) {
          return res.view(data);
        }  else if (res.locals.redirectTo) {
           return res.redirect(res.locals.redirectTo);
        } else {
          // push id to paramsArray for use in urlTo
          req.paramsArray.push(res.locals.data.id);
          // redirect to content after create
          return res.redirect(we.router.urlTo(res.locals.model + '.findOne', req.paramsArray));
        }
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  /**
   * Record updated response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data optional data
   */
  updated: function updatedResponse(data) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(200);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:updatedResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // if is edit record use the redirectTo feature
        if (res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        } else {
          // push id to paramsArray for use in urlTo
          req.paramsArray.push(res.locals.data.id);
          // redirect to content after create
          return res.redirect(we.router.urlTo(res.locals.model + '.findOne', req.paramsArray));
        }
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  deleted: function deletedResponse() {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(204);

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:deletedResponse', {
      req: req,
      res: res
    }, function() {

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        if (res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        } else {
          res.locals.deleteRedirectUrl = we.router.urlTo(res.locals.model + '.find', req.paramsArray);
          return res.redirect(res.locals.redirectTo);
        }
      }
      res.send();
    });
  },
  view: function viewResponse(data) {
    var req = this.req;
    var res = this.res;

    if (req.haveAlias) {
      // is a target how have alias then redirect to it
      res.writeHead(307, {
        'Location': req.haveAlias.alias,
        'Content-Type': 'text/plain',
        'Cache-Control':'public, max-age=345600',
        'Expires': new Date(Date.now() + 345600000).toUTCString()
      });
      return res.end();
    }

    var responseData = req.we.responses.format(res.locals.responseType, data, req, res, req.we);
    return res.send(responseData);
  },
  forbidden: function forbiddenResponse(data) {
    var res = this.res;

    if (!data) data = {};

    res.status(403);

    res.locals.title = res.locals.__('response.forbidden.title');

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.layoutName = 'fullwidth';
      res.locals.template = '403';
      return res.view(data);
    }

    if (!res.locals.model) {
      return res.send({
        messages: res.locals.messages
      });
    }

    var response = {};
    response[res.locals.model] = data;
    response.meta = res.locals.metadata;

    // set messages
    response.messages = res.locals.messages;

    return res.send(response);
  },
  notFound: function notFoundResponse(data) {
    var res = this.res;
    var req = this.req;

    if (!data) data = {};

    if (req.we.env == 'dev') {
      console.trace('404', req.path);
    } else {
      req.we.log.info('Not found:', req.url);
    }

    res.locals.title = res.locals.__('response.notFound.title');

    res.status(404);

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.layoutName = 'fullwidth';
      res.locals.template = '404';
      return res.view(data);
    }

    data.messages = res.locals.messages;
    return res.send(data);
  },
  /**
   * Server error response
   *
   * @param  {Object} data   the error
   */
  serverError: function serverErrorResponse(data) {
    var res = this.res;

    res.status(500);

    res.locals.title = res.locals.__('response.serveError.title');

    if (!data) data = {};

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.template = '500';
      res.locals.layoutName = 'fullwidth';
      return res.view(data);
    }

    // set messages
    data.messages = res.locals.messages;
    return res.send(data);
  },
  /**
   * bad request response
   *
   * @param  {Obejct|String} data message
   */
  badRequest: function badResponse(data) {
    var res = this.res;
    var req = this.req;

    res.status(400);

    if (req.we.env == 'dev') console.trace('400', req.path);

    if (!data) {
      data = {};
    } else if (typeof data == 'string') {
      res.addMessage('warning', data);
    }

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      if (!res.locals.template) res.locals.template = '400';
      return res.view(data);
    }

    if (!res.locals.model) {
      // set messages
      data.messages = res.locals.messages;
      return res.send(data);
    }

    var response = {};
    response[res.locals.model] = data;
    response.meta = res.locals.metadata;
    // set messages
    response.messages = res.locals.messages;
    // send the response
    return res.send(response);
  },
  /**
   * Sequelize query error parser
   *
   * @param  {Object} err The database error
   */
  queryError: function queryError(err) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    if (err) {
      // parse all sequelize validation erros
      if (err.name === 'SequelizeValidationError') {
        res.locals.validationError = {};
        if (res.locals.responseType === 'html') {
          err.errors.forEach(function (err) {
            if (!res.locals.validationError[err.path])
              res.locals.validationError[err.path] = [];

            res.locals.validationError[err.path].push({
              field: err.path, rule: err.type,
              message: req.__(err.message)
            });
          });
        }
      }
      // parse sequelize database errors
      if (err.name === 'SequelizeDatabaseError') {
        if (err.message) {
          res.addMessage('error', err.message);
        }
      } else if (typeof err == 'string') {
        res.addMessage('error', err);
      }
      // and for others errors
      if (err.errors) {
         err.errors.forEach(function (err) {
          res.addMessage('error', err.message, {
            field: err.path, rule: err.type
          });
        });
      }
    }

    res.status(400);

    var responseData = we.responses.format(res.locals.responseType, {}, req, res, we);
    return res.send(responseData);
  },
  /**
   * we.js core redirect
   * @param  {String} s response status
   * @param  {String} p path
   */
  goTo: function goTo(s ,p) {
    // save locals messages to flash
    this.res.moveLocalsMessagesToFlash();
    // use default redirect
    if (p) {
      this.res.redirect(s, p);
    } else {
      this.res.redirect(s);
    }
  }
};<commit_msg>change queryError log to show log in dev env<commit_after>module.exports = {
  /**
   * res.ok default success response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data opctional data
   */
  ok: function okResponse(data) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(200);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:okResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // if is edit record use the redirectTo feature
        if (req.method == 'POST' && res.locals.action == 'edit' && res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        }
        return res.view(data);
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  /**
   * Record created response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data record data
   */
  created: function createdResponse(data) {

    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(201);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:createdResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // redirect if are one html response
        if (res.locals.skipRedirect) {
          return res.view(data);
        }  else if (res.locals.redirectTo) {
           return res.redirect(res.locals.redirectTo);
        } else {
          // push id to paramsArray for use in urlTo
          req.paramsArray.push(res.locals.data.id);
          // redirect to content after create
          return res.redirect(we.router.urlTo(res.locals.model + '.findOne', req.paramsArray));
        }
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  /**
   * Record updated response
   *
   * By defalt they will get the record from res.locals.data
   *
   * @param  {Object} data optional data
   */
  updated: function updatedResponse(data) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(200);

    if (!data) {
      data = res.locals.data || {};
    } else {
      if (!res.locals.data) res.locals.data = data;
    }

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:updatedResponse', {
      req: req,
      res: res,
      data: data
    }, function (err) {
      if (err) we.log.error(err);

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        // if is edit record use the redirectTo feature
        if (res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        } else {
          // push id to paramsArray for use in urlTo
          req.paramsArray.push(res.locals.data.id);
          // redirect to content after create
          return res.redirect(we.router.urlTo(res.locals.model + '.findOne', req.paramsArray));
        }
      }

      var responseData = we.responses.format(res.locals.responseType, data, req, res, we);
      return res.send(responseData);
    });
  },
  deleted: function deletedResponse() {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    res.status(204);

    // use this hook in one we.js plugin to change a res.ok response
    we.hooks.trigger('we:before:send:deletedResponse', {
      req: req,
      res: res
    }, function() {

      if (!res.locals.responseType || res.locals.responseType == 'html') {
        if (res.locals.redirectTo) {
          return res.redirect(res.locals.redirectTo);
        } else {
          res.locals.deleteRedirectUrl = we.router.urlTo(res.locals.model + '.find', req.paramsArray);
          return res.redirect(res.locals.redirectTo);
        }
      }
      res.send();
    });
  },
  view: function viewResponse(data) {
    var req = this.req;
    var res = this.res;

    if (req.haveAlias) {
      // is a target how have alias then redirect to it
      res.writeHead(307, {
        'Location': req.haveAlias.alias,
        'Content-Type': 'text/plain',
        'Cache-Control':'public, max-age=345600',
        'Expires': new Date(Date.now() + 345600000).toUTCString()
      });
      return res.end();
    }

    var responseData = req.we.responses.format(res.locals.responseType, data, req, res, req.we);
    return res.send(responseData);
  },
  forbidden: function forbiddenResponse(data) {
    var res = this.res;

    if (!data) data = {};

    res.status(403);

    res.locals.title = res.locals.__('response.forbidden.title');

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.layoutName = 'fullwidth';
      res.locals.template = '403';
      return res.view(data);
    }

    if (!res.locals.model) {
      return res.send({
        messages: res.locals.messages
      });
    }

    var response = {};
    response[res.locals.model] = data;
    response.meta = res.locals.metadata;

    // set messages
    response.messages = res.locals.messages;

    return res.send(response);
  },
  notFound: function notFoundResponse(data) {
    var res = this.res;
    var req = this.req;

    if (!data) data = {};

    if (req.we.env == 'dev') {
      console.trace('404', req.path);
    } else {
      req.we.log.info('Not found:', req.url);
    }

    res.locals.title = res.locals.__('response.notFound.title');

    res.status(404);

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.layoutName = 'fullwidth';
      res.locals.template = '404';
      return res.view(data);
    }

    data.messages = res.locals.messages;
    return res.send(data);
  },
  /**
   * Server error response
   *
   * @param  {Object} data   the error
   */
  serverError: function serverErrorResponse(data) {
    var res = this.res;

    res.status(500);

    res.locals.title = res.locals.__('response.serveError.title');

    if (!data) data = {};

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      res.locals.template = '500';
      res.locals.layoutName = 'fullwidth';
      return res.view(data);
    }

    // set messages
    data.messages = res.locals.messages;
    return res.send(data);
  },
  /**
   * bad request response
   *
   * @param  {Obejct|String} data message
   */
  badRequest: function badResponse(data) {
    var res = this.res;
    var req = this.req;

    res.status(400);

    if (req.we.env == 'dev') console.trace('400', req.path);

    if (!data) {
      data = {};
    } else if (typeof data == 'string') {
      res.addMessage('warning', data);
    }

    if (!res.locals.responseType || res.locals.responseType == 'html') {
      if (!res.locals.template) res.locals.template = '400';
      return res.view(data);
    }

    if (!res.locals.model) {
      // set messages
      data.messages = res.locals.messages;
      return res.send(data);
    }

    var response = {};
    response[res.locals.model] = data;
    response.meta = res.locals.metadata;
    // set messages
    response.messages = res.locals.messages;
    // send the response
    return res.send(response);
  },
  /**
   * Sequelize query error parser
   *
   * @param  {Object} err The database error
   */
  queryError: function queryError(err) {
    var res = this.res;
    var req = this.req;
    var we = req.we;

    if (req.we.env == 'dev') console.trace('queryError: ', req.path, err);

    if (err) {
      // parse all sequelize validation erros
      if (err.name === 'SequelizeValidationError') {
        res.locals.validationError = {};
        if (res.locals.responseType === 'html') {
          err.errors.forEach(function (err) {
            if (!res.locals.validationError[err.path])
              res.locals.validationError[err.path] = [];

            res.locals.validationError[err.path].push({
              field: err.path, rule: err.type,
              message: req.__(err.message)
            });
          });
        }
      }
      // parse sequelize database errors
      if (err.name === 'SequelizeDatabaseError') {
        if (err.message) {
          res.addMessage('error', err.message);
        }
      } else if (typeof err == 'string') {
        res.addMessage('error', err);
      }
      // and for others errors
      if (err.errors) {
         err.errors.forEach(function (err) {
          res.addMessage('error', err.message, {
            field: err.path, rule: err.type
          });
        });
      }
    }

    res.status(400);

    var responseData = we.responses.format(res.locals.responseType, {}, req, res, we);
    return res.send(responseData);
  },
  /**
   * we.js core redirect
   * @param  {String} s response status
   * @param  {String} p path
   */
  goTo: function goTo(s ,p) {
    // save locals messages to flash
    this.res.moveLocalsMessagesToFlash();
    // use default redirect
    if (p) {
      this.res.redirect(s, p);
    } else {
      this.res.redirect(s);
    }
  }
};<|endoftext|>


<commit_before>var Dispatcher = require('../../modules/Dispatcher');
var ItemsConstants = require('./ItemsConstants');
var ItemsModelFactories = require('./ItemsModelFactories');
var PlayersConstants = require('./PlayerConstants');
var RegisteredStore = require('../../modules/RegisteredStore');
var Immutable = require('../../modules/immutable');
var Definitions = require('../../../../config/Definitions');
var _ = require('lodash');

var ItemsStore = RegisteredStore.create('ItemsStore');

var data = {
    isFetching:false,
    map:[[]],
    flags:[],
    items:Immutable.Dictionary()
};

/**
 * Save all items to browser's local storage and trigger store change
 */
function persistAndEmitChange(){
    localStorage.setItem('items',JSON.stringify(data.items.values));
    localStorage.setItem('map',JSON.stringify(data.map));
    localStorage.setItem('flags',JSON.stringify(data.flags));
    ItemsStore.emitChange();
}

/**
 * Update the data in the store
 * @param payload Object
 */
function updateAllItems(payload){
    var flags = [];
    var transaction = data.items.transaction();
    payload.arguments.items.forEach(function(item){
        if(item.isFlag){
            flags.push(item);
        }

        transaction.addOrUpdate(item.id,item);
    });

    data.items = transaction.commit();
    buildMap();
}

function buildMap(){
    data.map = data.items.reduce(function(items,item){
        items[item.row] = items[item.row] || [];
        items[item.row][item.col] = item;

        return items;
    },[]);
}

function revealNeighbors(item){
    item.neighbors.forEach(function(id){
        var item = data.items.index(id);
        if(!item.isBomb && !item.isFlag && !item.isRevealed){
            revealItem(item);
        }
    });
}

function revealItem(item){
    var model = item.shallowClone();
    model.isRevealed = true;

    var transaction = data.items.transaction();
    transaction.addOrUpdate(item.id,new ItemsModelFactories.ItemModel(model));
    data.items = transaction.commit();

    buildMap();
    ItemsStore.emitChange();

    if(!item.label){
        revealNeighbors(item);
    }
}

function revealAllItems(){
    var transaction = data.items.transaction();
    data.items.forEach(function(item){
        if(!item.isRevealed){
            var model = item.shallowClone();
            model.isRevealed = true;
            model.isFlag = false;
            transaction.update(item.id,new ItemsModelFactories.ItemModel(model))
        }
    });
    data.items = transaction.commit();

    buildMap();
}

function _dispatcher(payload){
    switch(payload.actionType){
        case ItemsConstants.BEGIN_GENERATE_MAP:
            data.isFetching = true;
            ItemsStore.emitChange();
            break;
        case ItemsConstants.END_GENERATE_MAP_SUCCESS:
            data.isFetching = false;
            updateAllItems(payload);
            data.hasFetched = true;
            persistAndEmitChange();
            break;
        case ItemsConstants.END_GENERATE_MAP_FAILURE:
            data.isFetching = false;
            data.hasFetched = true;
            ItemsStore.emitChange();
            break;
        case ItemsConstants.REVEAL_ALL_ITEMS:
        case PlayersConstants.GAME_OVER:
            revealAllItems();
            persistAndEmitChange();
            break;
        case ItemsConstants.REVEAL_ITEM:
            var item = payload.arguments.items[0];
            revealItem(item);
            persistAndEmitChange();
            break;
        case ItemsConstants.TOGGLE_ITEM_FLAG:
            updateAllItems(payload);
            persistAndEmitChange();
            break;
    }

    return true;
}

module.exports = ItemsStore.assign({
    getDebugData:function(){
        return data;
    },
    isFetching:function(){
        return data.isFetching;
    },
    hasFetched:function(){
        return data.hasFetched;
    },
    getItems:function(){
        return data.items;
    },
    getMap:function(){
        return data.map;
    },
    getRemaining:function(){
        return data.items.filter(function(item){
            return !item.isRevealed && !item.isBomb;
        });
    },
    getFlags:function(){
        return data.flags;
    },
    getById:function(id){
        return data.items.index(id);
    },
    dispatcherIndex:Dispatcher.register(_dispatcher)
});
<commit_msg>Clear the items in the store on map generation<commit_after>var Dispatcher = require('../../modules/Dispatcher');
var ItemsConstants = require('./ItemsConstants');
var ItemsModelFactories = require('./ItemsModelFactories');
var PlayersConstants = require('./PlayerConstants');
var RegisteredStore = require('../../modules/RegisteredStore');
var Immutable = require('../../modules/immutable');
var Definitions = require('../../../../config/Definitions');
var _ = require('lodash');

var ItemsStore = RegisteredStore.create('ItemsStore');

var data = {
    isFetching:false,
    map:[[]],
    flags:[],
    items:Immutable.Dictionary()
};

/**
 * Save all items to browser's local storage and trigger store change
 */
function persistAndEmitChange(){
    localStorage.setItem('items',JSON.stringify(data.items.values));
    localStorage.setItem('map',JSON.stringify(data.map));
    localStorage.setItem('flags',JSON.stringify(data.flags));
    ItemsStore.emitChange();
}

/**
 * Update the data in the store
 * @param payload Object
 */
function updateAllItems(payload){
    var flags = [];
    var transaction = data.items.transaction();
    payload.arguments.items.forEach(function(item){
        if(item.isFlag){
            flags.push(item);
        }

        transaction.addOrUpdate(item.id,item);
    });

    data.items = transaction.commit();
    buildMap();
}

function buildMap(){
    data.map = data.items.reduce(function(items,item){
        items[item.row] = items[item.row] || [];
        items[item.row][item.col] = item;

        return items;
    },[]);
}

function revealNeighbors(item){
    item.neighbors.forEach(function(id){
        var item = data.items.index(id);
        if(!item.isBomb && !item.isFlag && !item.isRevealed){
            revealItem(item);
        }
    });
}

function revealItem(item){
    var model = item.shallowClone();
    model.isRevealed = true;

    var transaction = data.items.transaction();
    transaction.addOrUpdate(item.id,new ItemsModelFactories.ItemModel(model));
    data.items = transaction.commit();

    buildMap();
    ItemsStore.emitChange();

    if(!item.label){
        revealNeighbors(item);
    }
}

function revealAllItems(){
    var transaction = data.items.transaction();
    data.items.forEach(function(item){
        if(!item.isRevealed){
            var model = item.shallowClone();
            model.isRevealed = true;
            model.isFlag = false;
            transaction.update(item.id,new ItemsModelFactories.ItemModel(model))
        }
    });
    data.items = transaction.commit();

    buildMap();
}

function _dispatcher(payload){
    switch(payload.actionType){
        case ItemsConstants.BEGIN_GENERATE_MAP:
            data.isFetching = true;
            ItemsStore.emitChange();
            break;
        case ItemsConstants.END_GENERATE_MAP_SUCCESS:
            data.isFetching = false;
            data.items = data.items.transaction().clear().commit();
            updateAllItems(payload);
            data.hasFetched = true;
            persistAndEmitChange();
            break;
        case ItemsConstants.END_GENERATE_MAP_FAILURE:
            data.isFetching = false;
            data.hasFetched = true;
            ItemsStore.emitChange();
            break;
        case ItemsConstants.REVEAL_ALL_ITEMS:
        case PlayersConstants.GAME_OVER:
            revealAllItems();
            persistAndEmitChange();
            break;
        case ItemsConstants.REVEAL_ITEM:
            var item = payload.arguments.items[0];
            revealItem(item);
            persistAndEmitChange();
            break;
        case ItemsConstants.TOGGLE_ITEM_FLAG:
            updateAllItems(payload);
            persistAndEmitChange();
            break;
    }

    return true;
}

module.exports = ItemsStore.assign({
    getDebugData:function(){
        return data;
    },
    isFetching:function(){
        return data.isFetching;
    },
    hasFetched:function(){
        return data.hasFetched;
    },
    getItems:function(){
        return data.items;
    },
    getMap:function(){
        return data.map;
    },
    getRemaining:function(){
        return data.items.filter(function(item){
            return !item.isRevealed && !item.isBomb;
        });
    },
    getFlags:function(){
        return data.flags;
    },
    getById:function(id){
        return data.items.index(id);
    },
    dispatcherIndex:Dispatcher.register(_dispatcher)
});
<|endoftext|>


<commit_before>/*****************************************************************************/
/* Imports */
/*****************************************************************************/
var Fiber = Npm.require('fibers');
var Controller = Iron.Controller;
var Url = Iron.Url;
var MiddlewareStack = Iron.MiddlewareStack;

/*****************************************************************************/
/* RouteController */
/*****************************************************************************/

/**
 * Server specific initialization.
 */
RouteController.prototype.init = function (options) {};

/**
 * Let this controller run a dispatch process. This function will be called
 * from the router. That way, any state associated with the dispatch can go on
 * the controller instance. Note: no result returned from dispatch because its
 * run inside its own fiber. Might at some point move the fiber stuff to a
 * higher layer.
 */
RouteController.prototype.dispatch = function (stack, url, done) {
  var self = this;
  Fiber(function () {
    stack.dispatch(url, self, done);
  }).run();
};

/**
 * Run a route on the server. When the router runs its middleware stack, it
 * can run regular middleware functions or it can run a route. There should
 * only one route object per path as where there may be many middleware
 * functions.
 *
 * For example:
 *
 *   "/some/path" => [middleware1, middleware2, route, middleware3]
 *
 * When a route is dispatched, it tells the controller to _runRoute so that
 * the controller can control the process. At this point we should already be
 * in a dispatch so a computation should already exist.
 */
RouteController.prototype._runRoute = function (route, url, done) {
  var self = this;
  var stack = new MiddlewareStack;

  var onRunHooks = this._collectHooks('onRun', 'load');
  stack = stack.append(onRunHooks, {where: 'server'});

  var beforeHooks = this._collectHooks('onBeforeAction', 'before');
  actionStack.append(beforeHooks, {where: 'server'});

  // make sure the action stack has at least one handler on it that defaults
  // to the 'action' method
  if (route._actionStack.length === 0) {
    route._actionStack.push(route._path, 'action', route.options);
  }

  actionStack = actionStack.concat(route._actionStack);
  actionStack.dispatch(url, this, done);

  // run the after hooks.
  this.next = function () {};
  this.runHooks('onAfterAction', 'after');
};
<commit_msg>fix server controller issues<commit_after>/*****************************************************************************/
/* Imports */
/*****************************************************************************/
var Fiber = Npm.require('fibers');
var Controller = Iron.Controller;
var Url = Iron.Url;
var MiddlewareStack = Iron.MiddlewareStack;

/*****************************************************************************/
/* RouteController */
/*****************************************************************************/

/**
 * Server specific initialization.
 */
RouteController.prototype.init = function (options) {};

/**
 * Let this controller run a dispatch process. This function will be called
 * from the router. That way, any state associated with the dispatch can go on
 * the controller instance. Note: no result returned from dispatch because its
 * run inside its own fiber. Might at some point move the fiber stuff to a
 * higher layer.
 */
RouteController.prototype.dispatch = function (stack, url, done) {
  var self = this;
  Fiber(function () {
    stack.dispatch(url, self, done);
  }).run();
};

/**
 * Run a route on the server. When the router runs its middleware stack, it
 * can run regular middleware functions or it can run a route. There should
 * only one route object per path as where there may be many middleware
 * functions.
 *
 * For example:
 *
 *   "/some/path" => [middleware1, middleware2, route, middleware3]
 *
 * When a route is dispatched, it tells the controller to _runRoute so that
 * the controller can control the process. At this point we should already be
 * in a dispatch so a computation should already exist.
 */
RouteController.prototype._runRoute = function (route, url, done) {
  var self = this;
  var stack = new MiddlewareStack;

  var onRunHooks = this._collectHooks('onRun', 'load');
  stack = stack.append(onRunHooks, {where: 'server'});

  var beforeHooks = this._collectHooks('onBeforeAction', 'before');
  stack.append(beforeHooks, {where: 'server'});

  // make sure the action stack has at least one handler on it that defaults
  // to the 'action' method
  if (route._actionStack.length === 0) {
    route._actionStack.push(route._path, 'action', route.options);
  }

  stack = stack.concat(route._actionStack);
  stack.dispatch(url, this, done);

  // run the after hooks.
  this.next = function () {};
  this.runHooks('onAfterAction', 'after');
};
<|endoftext|>


<commit_before>import Vue from 'vue/dist/vue.js';
import Home from './Home.vue';

Vue.prototype.__ = window.__;
frappe.provide('frappe.social');

frappe.social.Home = class SocialHome {
	constructor({ parent }) {
		this.$parent = $(parent);
		this.page = parent.page;
		this.setup_header();
		this.make_body();
		this.set_primary_action();
	}
	make_body() {
		this.$social_container = this.$parent.find('.layout-main');

		new Vue({
			el: this.$social_container[0],
			render: h => h(Home)
		});
	}
	setup_header() {
		this.page.set_title(__('Social'));
	}
	set_primary_action() {
		this.page.set_primary_action(__('Post'), () => {
			frappe.social.post_dialog.show();
		});
	}
};

frappe.social.post_dialog = new frappe.ui.Dialog({
	title: __('Create Post'),
	fields: [
		{
			fieldtype: "Text Editor",
			fieldname: "content",
			label: __("Content"),
			reqd: 1
		}
	],
	primary_action_label: __('Post'),
	primary_action: (values) => {
		const post = frappe.model.get_new_doc('Post');
		post.content = values.content;
		frappe.db.insert(post).then(() => {
			frappe.social.post_dialog.clear();
			frappe.social.post_dialog.hide();
		});
	}
});

frappe.social.update_user_image = new frappe.ui.Dialog({
	title: __("User Image"),
	fields: [
		{
			fieldtype: "Attach Image",
			fieldname: "image",
			label: __("Image"),
			reqd: 1,
			default: frappe.user.image()
		},
	],
	primary_action_label: __('Set Image'),
	primary_action: (values) => {
		frappe.db.set_value('User', frappe.session.user, 'user_image', values.image)
			.then((resp) => {
				frappe.boot.user_info[frappe.session.user].image = resp.message.user_image;
				frappe.app_updates.trigger('user_image_updated');
				frappe.social.update_user_image.clear();
				frappe.social.update_user_image.hide();
			})
			.fail((err) => {
				frappe.msgprint(err);
			});
	}
});

frappe.social.is_home_page = () => {
	return frappe.get_route()[0] === 'social' && frappe.get_route()[1] === 'home';
};

frappe.social.is_profile_page = (user) => {
	return frappe.get_route()[0] === 'social'
		&& frappe.get_route()[1] === 'profile'
		&& (user ? frappe.get_route()[2] === user : true);
};

frappe.social.is_session_user_page = () => {
	return frappe.social.is_profile_page() && frappe.get_route()[2] === frappe.session.user;
};

frappe.provide('frappe.app_updates');

frappe.utils.make_event_emitter(frappe.app_updates);<commit_msg>Fix social home reload issue<commit_after>import Vue from 'vue/dist/vue.js';
import Home from './Home.vue';

Vue.prototype.__ = window.__;
frappe.provide('frappe.social');

frappe.social.Home = class SocialHome {
	constructor({ parent }) {
		this.$parent = $(parent);
		this.page = parent.page;
		this.setup_header();
		this.make_body();
		this.set_primary_action();
	}
	make_body() {
		this.$social_container = this.$parent.find('.layout-main');

		new Vue({
			el: this.$social_container[0],
			render: h => h(Home)
		});
	}
	setup_header() {
		this.page.set_title(__('Social'));
	}
	set_primary_action() {
		this.page.set_primary_action(__('Post'), () => {
			frappe.social.post_dialog.show();
		});
	}
};

frappe.social.post_dialog = new frappe.ui.Dialog({
	title: __('Create Post'),
	fields: [
		{
			fieldtype: "Text Editor",
			fieldname: "content",
			label: __("Content"),
			reqd: 1
		}
	],
	primary_action_label: __('Post'),
	primary_action: (values) => {
		const post = frappe.model.get_new_doc('Post');
		post.content = values.content;
		frappe.db.insert(post).then(() => {
			frappe.social.post_dialog.clear();
			frappe.social.post_dialog.hide();
		});
	}
});

frappe.social.update_user_image = new frappe.ui.Dialog({
	title: __("User Image"),
	fields: [
		{
			fieldtype: "Attach Image",
			fieldname: "image",
			label: __("Image"),
			reqd: 1,
			default: frappe.user.image()
		},
	],
	primary_action_label: __('Set Image'),
	primary_action: (values) => {
		const user = frappe.session.user || frappe.boot.user.name;
		frappe.db.set_value('User', user, 'user_image', values.image)
			.then((resp) => {
				frappe.boot.user_info[user].image = resp.message.user_image;
				frappe.app_updates.trigger('user_image_updated');
				frappe.social.update_user_image.clear();
				frappe.social.update_user_image.hide();
			})
			.fail((err) => {
				frappe.msgprint(err);
			});
	}
});

frappe.social.is_home_page = () => {
	return frappe.get_route()[0] === 'social' && frappe.get_route()[1] === 'home';
};

frappe.social.is_profile_page = (user) => {
	return frappe.get_route()[0] === 'social'
		&& frappe.get_route()[1] === 'profile'
		&& (user ? frappe.get_route()[2] === user : true);
};

frappe.social.is_session_user_page = () => {
	return frappe.social.is_profile_page() && frappe.get_route()[2] === frappe.session.user;
};

frappe.provide('frappe.app_updates');

frappe.utils.make_event_emitter(frappe.app_updates);<|endoftext|>


<commit_before>"use strict";

angular.module("myApp.postStream", [
    "ngRoute",
    "myApp.services.postHandler",
    "myApp.services.authenticationHandler",
    "myApp.services.urlHandler"
])

.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/stream", {
        templateUrl: "partials/postStream.html",
        controller: "PostStreamController"
    });
}])

.controller("PostStreamController", function($scope, $http, postHandler, authenticationHandler, urlHandler) {
    var targetAuthorId;
    $scope.user = authenticationHandler.user;
    $scope.posts = [];
    //TODO change to author.github
    $scope.git_username = "sjpartri";  // This will have to be changed "hard-coded for now"

    // If something else tells us what authorId to use, then
    // we know that we should load the posts of that user.
    // Otherwise, we should just load all the posts the current
    // signed in user can see.
    if($scope.postStream && $scope.postStream.authorId) {
        targetAuthorId = {id: $scope.postStream.authorId};
    }
    postHandler.getPosts(targetAuthorId).then(function(result) {

        $scope.posts = result.data.posts;

	//in $scope.posts we have to add our friend's posts as well.
	/*
	var url = 'localhost:8000/api/friends/' + targetAuthorId + '/';
	$http.get(url).then(function(friendData){

	var friends = friendData.authors;

	for(var i = 0 ; i< friends.length; i++){

	var url2 = 'localhost:8000/api/author/' + friends[i] + '/posts/';

	$http.get(url2).then(function(postData){

	$scope.posts += postData.data.posts;

	});

	}

	});

	 */

        loadGit();
    });

    // Make a http call to the github api to get all user information
    // associated with the git_username

    var loadGit = function () {
	//change $scope.git_username to the author's github user name

	var gitHubURL = $scope.user.github;
	$scope.git_username = gitHubURL.substring(gitHubURL.lastIndexOf('/')+1);

	if($scope.git_username){
            $http({method: 'GET', url:"https://api.github.com/users/"+$scope.git_username , headers:{'Authorization':undefined}}).success(function(gitdata){

	        $scope.gitUserData = gitdata;
                loadEvents();

	    });
	}

    };
    // Http call for github repos (not too sure what Abram means by "activity")
    // ** May need to make additional calls

    var loadEvents = function () {
        $http({method:'GET', url: "https://api.github.com/users/"+$scope.git_username+"/events" , headers:{'Authorization':undefined}})
            .success(function(event_data){
                $scope.eventData = event_data;

                $scope.allPost = $scope.posts.concat($scope.eventData);
                //console.log($scope.allPost);
            });
    };

    $scope.deletePost = function(post) {
        post.disabled = true;
        postHandler.deletePost(post.id).then(function(result) {
			//postHandlerService should reload the page

        });
    };

    $scope.editPost = function (post) {
        post.editMode = true;
    };

    $scope.submitPost = function (post) {
        postHandler.updatePost(post);
        post.editMode = false;

    };

//localhost/api/posts/{postid}/comments

//POST : author id, comment, postid
    $scope.AddComment = function (post, comments) {
        postHandler.commentPost({
            author: authenticationHandler.user.id,
            comment: comments,
            post: post.id
        }).then(function(){

	    comments = '';

	    $http.get(urlHandler.serviceURL()+'api/posts/'+post.id+'/').then(function(postData){

		console.log("POST STUFF BELOW");
		console.log(postData);
		post.comments = postData.data.comments;

	    });

	});
	//console.log(comments);
        comments = null;
    };
});
<commit_msg>my profile shows only your posts<commit_after>"use strict";

angular.module("myApp.postStream", [
    "ngRoute",
    "myApp.services.postHandler",
    "myApp.services.authenticationHandler",
    "myApp.services.urlHandler"
])

.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/stream", {
        templateUrl: "partials/postStream.html",
        controller: "PostStreamController"
    });
}])

.controller("PostStreamController", function($scope, $http, $location ,postHandler, authenticationHandler, urlHandler) {
    var targetAuthorId;
    $scope.user = authenticationHandler.user;
    $scope.posts = [];
    //TODO change to author.github
    $scope.git_username = "sjpartri";  // This will have to be changed "hard-coded for now"

    // If something else tells us what authorId to use, then
    // we know that we should load the posts of that user.
    // Otherwise, we should just load all the posts the current
    // signed in user can see.
    if($scope.postStream && $scope.postStream.authorId) {
        targetAuthorId = {id: $scope.postStream.authorId};
    }
    postHandler.getPosts(targetAuthorId).then(function(result) {

	if($location.url() ==='/profile'){

	    result.data.posts = result.data.posts.filter(function(post){

		return post.author.id === authenticationHandler.user.id;

	    });

	}
        $scope.posts = result.data.posts;

	//in $scope.posts we have to add our friend's posts as well.
	/*
	var url = 'localhost:8000/api/friends/' + targetAuthorId + '/';
	$http.get(url).then(function(friendData){

	var friends = friendData.authors;

	for(var i = 0 ; i< friends.length; i++){

	var url2 = 'localhost:8000/api/author/' + friends[i] + '/posts/';

	$http.get(url2).then(function(postData){

	$scope.posts += postData.data.posts;

	});

	}

	});

	 */

        loadGit();
    });

    // Make a http call to the github api to get all user information
    // associated with the git_username

    var loadGit = function () {
	//change $scope.git_username to the author's github user name

	var gitHubURL = $scope.user.github;
	$scope.git_username = gitHubURL.substring(gitHubURL.lastIndexOf('/')+1);

	if($scope.git_username){
            $http({method: 'GET', url:"https://api.github.com/users/"+$scope.git_username , headers:{'Authorization':undefined}}).success(function(gitdata){

	        $scope.gitUserData = gitdata;
                loadEvents();

	    });
	}

    };
    // Http call for github repos (not too sure what Abram means by "activity")
    // ** May need to make additional calls

    var loadEvents = function () {
        $http({method:'GET', url: "https://api.github.com/users/"+$scope.git_username+"/events" , headers:{'Authorization':undefined}})
            .success(function(event_data){
                $scope.eventData = event_data;

                $scope.allPost = $scope.posts.concat($scope.eventData);
                //console.log($scope.allPost);
            });
    };

    $scope.deletePost = function(post) {
        post.disabled = true;
        postHandler.deletePost(post.id).then(function(result) {
			//postHandlerService should reload the page

        });
    };

    $scope.editPost = function (post) {
        post.editMode = true;
    };

    $scope.submitPost = function (post) {
        postHandler.updatePost(post);
        post.editMode = false;

    };

//localhost/api/posts/{postid}/comments

//POST : author id, comment, postid
    $scope.AddComment = function (post, comments) {
        postHandler.commentPost({
            author: authenticationHandler.user.id,
            comment: comments,
            post: post.id
        }).then(function(){

	    comments = '';

	    $http.get(urlHandler.serviceURL()+'api/posts/'+post.id+'/').then(function(postData){

		console.log("POST STUFF BELOW");
		console.log(postData);
		post.comments = postData.data.comments;

	    });

	});
    };
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import ENV from '../config/environment';

export default Ember.Mixin.create({

  pageviewToGA: function(page, title) {
    var page = page ? page : this.get('url');
    var title = title ? title : this.get('url');

    if (Ember.get(ENV, 'googleAnalytics.webPropertyId') != null) {
      var trackerType = Ember.getWithDefault(ENV, 'googleAnalytics.tracker', 'analytics.js');

      if (trackerType === 'analytics.js') {
        var globalVariable = Ember.getWithDefault(ENV, 'googleAnalytics.globalVariable', 'ga');

        window[globalVariable]('send', 'pageview', {
          page: page,
          title: title
        });
      } else if (trackerType === 'ga.js') {
        window._gaq.push(['_trackPageview']);
      }
    }
  }.on('didTransition')

});
<commit_msg>Should not re-declare var when already defined in arg list<commit_after>import Ember from 'ember';
import ENV from '../config/environment';

export default Ember.Mixin.create({

  pageviewToGA: function(page, title) {
    page = page ? page : this.get('url');
    title = title ? title : this.get('url');

    if (Ember.get(ENV, 'googleAnalytics.webPropertyId') != null) {
      var trackerType = Ember.getWithDefault(ENV, 'googleAnalytics.tracker', 'analytics.js');

      if (trackerType === 'analytics.js') {
        var globalVariable = Ember.getWithDefault(ENV, 'googleAnalytics.globalVariable', 'ga');

        window[globalVariable]('send', 'pageview', {
          page: page,
          title: title
        });
      } else if (trackerType === 'ga.js') {
        window._gaq.push(['_trackPageview']);
      }
    }
  }.on('didTransition')

});
<|endoftext|>


<commit_before>import React from 'react'
import '../../style/widgets.scss'

const WIDGET_URLS = {
  timeline: 'http://mcmwidgets.azurewebsites.net/widgets/timeline-app.html?useMockups',
  relations: 'http://mcmwidgets.azurewebsites.net/widgets/relations-widget.html?useMockups',
  map: 'http://mcmwidgets.azurewebsites.net/widgets/map-app.html?useMockups'
}

export default class WidgetComponent extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      fullscreen: false
    }
  }

  componentWillMount () {
    const onMessageFromWidget = (event) => {
      const { widget, text } = event.data
      if (widget === this.props.widgetType) {
        if (text === 'full-screen activated') {
          this.setState({ fullscreen: true })
        } else if (text === 'full-screen deactivated') {
          this.setState({ fullscreen: false })
        }
      }
    }
    window.addEventListener('message', onMessageFromWidget, false)
  }

  render () {
    const { entityId, entityType, widgetType } = this.props
    return (
      <iframe
        src={`${WIDGET_URLS[widgetType]}&entityId=${entityId}&entityType=${entityType}`}
        className={`widget ${this.state.fullscreen ? 'widget--full-screen' : ''}`}
        frameBorder='0'
      />
    )
  }
}

WidgetComponent.propTypes = {
  entityId: React.PropTypes.string.isRequired,
  entityType: React.PropTypes.string.isRequired,
  widgetType: React.PropTypes.string.isRequired
}
<commit_msg>Let the map widget use real data from the API!<commit_after>import React from 'react'
import '../../style/widgets.scss'

const WIDGET_URLS = {
  timeline: 'http://mcmwidgets.azurewebsites.net/widgets/timeline-app.html?useMockups',
  relations: 'http://mcmwidgets.azurewebsites.net/widgets/relations-widget.html?useMockups',
  map: 'http://mcmwidgets.azurewebsites.net/widgets/map-app.html?'
}

export default class WidgetComponent extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      fullscreen: false
    }
  }

  componentWillMount () {
    const onMessageFromWidget = (event) => {
      const { widget, text } = event.data
      if (widget === this.props.widgetType) {
        if (text === 'full-screen activated') {
          this.setState({ fullscreen: true })
        } else if (text === 'full-screen deactivated') {
          this.setState({ fullscreen: false })
        }
      }
    }
    window.addEventListener('message', onMessageFromWidget, false)
  }

  render () {
    const { entityId, entityType, widgetType } = this.props
    const entityTypeWithoutS = entityType.substring(0, entityType.length - 1)
    return (
      <iframe
        src={`${WIDGET_URLS[widgetType]}&entityId=${entityId}&entityType=${entityTypeWithoutS}`}
        className={`widget ${this.state.fullscreen ? 'widget--full-screen' : ''}`}
        frameBorder='0'
      />
    )
  }
}

WidgetComponent.propTypes = {
  entityId: React.PropTypes.string.isRequired,
  entityType: React.PropTypes.string.isRequired,
  widgetType: React.PropTypes.string.isRequired
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

const isNil = require('lodash.isnil');
const getProp = require('lodash.get');

const backendContext = require('./modules/backendContext');
const dataStore = require('./modules/dataStore');
const email = require('./modules/email');
const entity = require('./modules/entity');
const kinveyDate = require('./modules/kinveyDate');
const push = require('./modules/push');
const query = require('./modules/query');
const requestContext = require('./modules/requestContext');
const tempObjectStore = require('./modules/tempObjectStore');

const EventEmitter = require('events').EventEmitter;
const util = require('util');

const proxyTaskEmitter = new EventEmitter();
let pendingProxyTasks = 0;

proxyTaskEmitter.on('proxyTaskStarted', () => { pendingProxyTasks += 1; });
proxyTaskEmitter.on('proxyTaskCompleted', () => { pendingProxyTasks -= 1; });

function getSecurityContextString(authorizationHeader, appMetadata) {
  let credentials = null;
  try {
    const encodedCredentials = authorizationHeader.split(' ')[1];
    credentials = new Buffer(encodedCredentials, 'base64').toString('ascii').split(':');
  } catch (e) {
    return 'unknown';
  }

  if (util.isArray(credentials)) {
    if (credentials[0] !== appMetadata._id) {
      return 'user';
    }
    if (credentials[0] === appMetadata._id && !isNil(credentials[1])) {
      if (credentials[1] === appMetadata.appsecret) {
        return 'app';
      }
      if (credentials[1] === appMetadata.mastersecret) {
        return 'master';
      }
    }
  }

  return 'unknown';
}

function generateModules(task) {
  let clientAppVersion = null;
  let customRequestProperties = {};

  for (const header in task.request.headers) {
    if (header.toLowerCase() === 'x-kinvey-client-app-version') {
      clientAppVersion = task.request.headers[header];
    }
    if (header.toLowerCase() === 'x-kinvey-custom-request-properties') {
      try {
        const customRequestPropertiesString = task.request.headers[header];
        customRequestProperties = JSON.parse(customRequestPropertiesString);
      } catch (e) {
        customRequestProperties = {};
      }
    }
  }

  const proxyURL = task.proxyURL;
  const appMetadata = {
    _id: task.appMetadata._id,
    blFlags: task.appMetadata.blFlags,
    appsecret: task.appMetadata.appsecret,
    mastersecret: task.appMetadata.mastersecret,
    authenticatedUsername: task.request.username,
    baasUrl: `${task.request.headers['x-forwarded-proto'] || 'https'}://${task.request.headers['host']}`
  };
  const requestMetadata = {
    authenticatedUsername: task.request.username,
    authenticatedUserId: task.request.userId,
    apiVersion: task.request.headers['x-kinvey-api-version'] || '1',
    authorization: task.request.headers.authorization,
    clientAppVersion,
    customRequestProperties
  };
  const taskMetadata = {
    taskType: task.taskType,
    serviceObjectName: task.serviceObjectName,
    target: task.target,
    taskId: task.taskId,
    containerId: task.containerId
  };

  appMetadata.securityContext = getSecurityContextString(
    getProp(task.request.headers, ['authorization'], []),
    appMetadata
  );

  let useBSONObjectId = false;
  const migrated = getProp(task, ['appMetadata', 'appMetadata', 'objectid_migration', 'status']);
  if (!isNil(migrated) && migrated === 'done') {
    useBSONObjectId = true;
  }

  return {
    backendContext: backendContext(appMetadata),
    dataStore: dataStore(appMetadata, requestContext),
    email: email(proxyURL, taskMetadata, proxyTaskEmitter),
    entity: entity(appMetadata._id, useBSONObjectId),
    kinveyDate,
    push: push(proxyURL, taskMetadata, proxyTaskEmitter),
    query,
    requestContext: requestContext(requestMetadata),
    tempObjectStore: tempObjectStore(task.request.tempObjectStore)
  };
}

exports.generate = generateModules;
<commit_msg>Use baasUrl in appMetadata if it's there, otherwise grab the host from the request<commit_after>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

const isNil = require('lodash.isnil');
const getProp = require('lodash.get');

const backendContext = require('./modules/backendContext');
const dataStore = require('./modules/dataStore');
const email = require('./modules/email');
const entity = require('./modules/entity');
const kinveyDate = require('./modules/kinveyDate');
const push = require('./modules/push');
const query = require('./modules/query');
const requestContext = require('./modules/requestContext');
const tempObjectStore = require('./modules/tempObjectStore');

const EventEmitter = require('events').EventEmitter;
const util = require('util');

const proxyTaskEmitter = new EventEmitter();
let pendingProxyTasks = 0;

proxyTaskEmitter.on('proxyTaskStarted', () => { pendingProxyTasks += 1; });
proxyTaskEmitter.on('proxyTaskCompleted', () => { pendingProxyTasks -= 1; });

function getSecurityContextString(authorizationHeader, appMetadata) {
  let credentials = null;
  try {
    const encodedCredentials = authorizationHeader.split(' ')[1];
    credentials = new Buffer(encodedCredentials, 'base64').toString('ascii').split(':');
  } catch (e) {
    return 'unknown';
  }

  if (util.isArray(credentials)) {
    if (credentials[0] !== appMetadata._id) {
      return 'user';
    }
    if (credentials[0] === appMetadata._id && !isNil(credentials[1])) {
      if (credentials[1] === appMetadata.appsecret) {
        return 'app';
      }
      if (credentials[1] === appMetadata.mastersecret) {
        return 'master';
      }
    }
  }

  return 'unknown';
}

function generateModules(task) {
  let clientAppVersion = null;
  let customRequestProperties = {};

  for (const header in task.request.headers) {
    if (header.toLowerCase() === 'x-kinvey-client-app-version') {
      clientAppVersion = task.request.headers[header];
    }
    if (header.toLowerCase() === 'x-kinvey-custom-request-properties') {
      try {
        const customRequestPropertiesString = task.request.headers[header];
        customRequestProperties = JSON.parse(customRequestPropertiesString);
      } catch (e) {
        customRequestProperties = {};
      }
    }
  }

  const proxyURL = task.proxyURL;
  const appMetadata = {
    _id: task.appMetadata._id,
    blFlags: task.appMetadata.blFlags,
    appsecret: task.appMetadata.appsecret,
    mastersecret: task.appMetadata.mastersecret,
    authenticatedUsername: task.request.username,
    baasUrl: task.appMetadata.baasUrl || `${task.request.headers['x-forwarded-proto'] || 'https'}://${task.request.headers['host']}`
  };
  const requestMetadata = {
    authenticatedUsername: task.request.username,
    authenticatedUserId: task.request.userId,
    apiVersion: task.request.headers['x-kinvey-api-version'] || '1',
    authorization: task.request.headers.authorization,
    clientAppVersion,
    customRequestProperties
  };
  const taskMetadata = {
    taskType: task.taskType,
    serviceObjectName: task.serviceObjectName,
    target: task.target,
    taskId: task.taskId,
    containerId: task.containerId
  };

  appMetadata.securityContext = getSecurityContextString(
    getProp(task.request.headers, ['authorization'], []),
    appMetadata
  );

  let useBSONObjectId = false;
  const migrated = getProp(task, ['appMetadata', 'appMetadata', 'objectid_migration', 'status']);
  if (!isNil(migrated) && migrated === 'done') {
    useBSONObjectId = true;
  }

  return {
    backendContext: backendContext(appMetadata),
    dataStore: dataStore(appMetadata, requestContext),
    email: email(proxyURL, taskMetadata, proxyTaskEmitter),
    entity: entity(appMetadata._id, useBSONObjectId),
    kinveyDate,
    push: push(proxyURL, taskMetadata, proxyTaskEmitter),
    query,
    requestContext: requestContext(requestMetadata),
    tempObjectStore: tempObjectStore(task.request.tempObjectStore)
  };
}

exports.generate = generateModules;
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import {graphql} from 'react-apollo'
import compose from 'util/compose'
import gql from 'graphql-tag'
import BaseLayout from 'client/components/layout/BaseLayout'
import {
    SimpleButton,
    SimpleDialog,
    Typography,
    TextField,
    Divider,
    DeleteIconButton,
    Chip,
    SimpleList,
    Row,
    Col
} from 'ui/admin'
import FileDrop from 'client/components/FileDrop'
import Util from 'client/util'
import config from 'gen/config'

const {BACKUP_URL} = config

class DbDumpContainer extends React.Component {

    constructor(props) {
        super(props)

        this.state = {
            creatingDump: false,
            creatingMediaDump: false,
            importingDbDump: false,
            importingMediaDump: false,
            importMediaDumpDialog: false,
            importDbDumpDialog: false
        }
    }

    createDump() {
        this.setState({creatingDump: true})
        this.props.createDbDump().then(e => {
            console.log(e)
            this.setState({creatingDump: false})
        })

    }

    createMediaDump() {
        this.setState({creatingMediaDump: true})
        this.props.createMediaDump().then(e => {
            console.log(e)
            this.setState({creatingMediaDump: false})
        })

    }

    importMediaDump() {
        this.setState({importMediaDumpDialog: true})
    }

    importDbDump() {
        this.setState({importDbDumpDialog: true})
    }

    handleConfirmMediaDialog() {
        this.setState({importMediaDumpDialog: false})
    }

    handleConfirmDbDialog() {
        this.setState({importDbDumpDialog: false})
    }

    handleMediaDumpUpload(e) {
        console.log(e)
    }

    download(content, filename, contentType)
    {
        if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
    }

    authorizedRequest(url, name){
        const xhr = new XMLHttpRequest

        xhr.open(url)
        xhr.responseType = 'blob'

        xhr.addEventListener("load", () => {
            if( xhr.status === 200) {

                this.download(xhr.response, name, 'application/gzip')
            }else{

                alert(`Invalid status ${xhr.status}`)
            }
        }, false)

        xhr.setRequestHeader('Authorization', Util.getAuthToken())
        // xhr.overrideMimeType( "application/octet-stream; charset=x-user-defined;" )
        xhr.send(null)
    }

    render() {
        const {dbDumps, mediaDumps} = this.props
        const {creatingDump, creatingMediaDump, importingMediaDump, importMediaDumpDialog, importDbDumpDialog, importingDbDump} = this.state
        return (
            <BaseLayout>
                <Typography variant="h3" gutterBottom>Backups</Typography>

                <Row spacing={4}>
                    <Col md={6}>

                        <SimpleButton variant="contained" color="primary"
                                      showProgress={creatingDump}
                                      onClick={this.createDump.bind(this)}>{creatingDump ? 'Dump is beeing created' : 'Create new db dump'}</SimpleButton>

                        <SimpleButton color="secondary"
                                      disabled={importDbDumpDialog}
                                      showProgress={importingDbDump}
                                      onClick={this.importDbDump.bind(this)}>{importingDbDump ? 'Dump is beeing restored' : 'Restore db dump'}</SimpleButton>

                        {dbDumps && dbDumps.results && dbDumps.results.length > 0 &&
                        <SimpleList items={dbDumps.results.reduce((a, i) => {
                            a.push({
                                primary: i.name,
                                onClick: () => {

                                    this.authorizedRequest("GET", BACKUP_URL + '/dbdumps/' + i.name, 'db.backup.gz' )

                                },
                                secondary: Util.formattedDatetime(i.createdAt) + ' - ' + i.size
                            })
                            return a
                        }, [])}/>
                        }
                    </Col>

                    <Col md={6}>

                        <SimpleButton variant="contained" color="primary"
                                      disabled={importMediaDumpDialog}
                                      showProgress={creatingMediaDump}
                                      onClick={this.createMediaDump.bind(this)}>{creatingMediaDump ? 'Dump is beeing created' : 'Create new media dump'}</SimpleButton>

                        <SimpleButton color="secondary"
                                      showProgress={importingMediaDump}
                                      onClick={this.importMediaDump.bind(this)}>{importingMediaDump ? 'Dump is beeing imported' : 'Import media dump'}</SimpleButton>

                        {mediaDumps && mediaDumps.results && mediaDumps.results.length > 0 &&
                        <SimpleList items={mediaDumps.results.reduce((a, i) => {
                            a.push({
                                primary: i.name,
                                onClick: () => {
                                    this.authorizedRequest("GET", BACKUP_URL + '/mediadumbs/' + i.name, 'medias.backup.gz' )
                                },
                                secondary: Util.formattedDatetime(i.createdAt) + ' - ' + i.size
                            })
                            return a
                        }, [])}/>
                        }
                    </Col>
                </Row>

                <SimpleDialog open={importMediaDumpDialog} onClose={this.handleConfirmMediaDialog.bind(this)}
                              actions={[{key: 'close', label: 'Close'}]}
                              title="Select a media dump file">

                    <FileDrop style={{width: '15rem', height: '10rem'}} accept="application/x-gzip"
                              uploadTo="/graphql/upload/mediadump"
                              label="Drop file here"/>

                </SimpleDialog>

                <SimpleDialog open={importDbDumpDialog} onClose={this.handleConfirmDbDialog.bind(this)}
                              actions={[{key: 'close', label: 'Close'}]}
                              title="Select a db dump file">

                    <FileDrop style={{width: '15rem', height: '10rem'}} accept="application/x-gzip"
                              uploadTo="/graphql/upload/dbdump"
                              label="Drop file here"/>

                </SimpleDialog>

            </BaseLayout>
        )
    }
}

DbDumpContainer.propTypes = {
    /* apollo client props */
    dbDumps: PropTypes.object,
    createDbDump: PropTypes.func.isRequired,
    createMediaDump: PropTypes.func.isRequired,
    loading: PropTypes.bool,
    mediaDumps: PropTypes.object
}

const gqlQuery = gql`query{dbDumps{results{name createdAt size}}}`
const gqlUpdate = gql`mutation createDbDump($type:String){createDbDump(type:$type){name createdAt size}}`
const gqlQueryMedia = gql`query{mediaDumps{results{name createdAt size}}}`
const gqlUpdateMedia = gql`mutation createMediaDump($type:String){createMediaDump(type:$type){name createdAt size}}`

const DbDumpContainerWithGql = compose(
    graphql(gqlQuery, {
        options() {
            return {
                fetchPolicy: 'cache-and-network'
            }
        },
        props: ({data: {dbDumps}}) => ({
            dbDumps
        })
    }),
    graphql(gqlUpdate, {
        props: ({mutate}) => ({
            createDbDump: () => {
                return mutate({
                    variables: {type: 'full'},
                    update: (proxy, {data: {createDbDump}}) => {
                        // Read the data from our cache for this query.
                        const data = proxy.readQuery({query: gqlQuery})
                        // Add our note from the mutation to the end.
                        data.dbDumps.results.unshift(createDbDump)
                        // Write our data back to the cache.
                        proxy.writeQuery({query: gqlQuery, data})
                    }

                })
            }
        })
    }),
    graphql(gqlQueryMedia, {
        options() {
            return {
                fetchPolicy: 'cache-and-network'
            }
        },
        props: ({data: {mediaDumps}}) => ({
            mediaDumps
        })
    }),
    graphql(gqlUpdateMedia, {
        props: ({mutate}) => ({
            createMediaDump: () => {
                return mutate({
                    variables: {type: 'full'},
                    update: (proxy, {data: {createMediaDump}}) => {
                        // Read the data from our cache for this query.
                        const data = proxy.readQuery({query: gqlQueryMedia})
                        // Add our note from the mutation to the end.
                        data.mediaDumps.results.unshift(createMediaDump)
                        // Write our data back to the cache.
                        proxy.writeQuery({query: gqlQueryMedia, data})
                    }

                })
            }
        })
    })
)
(DbDumpContainer)

/**
 * Connect the component to
 * the Redux store.
 */
export default DbDumpContainerWithGql
<commit_msg>Small improvments<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import {graphql} from 'react-apollo'
import compose from 'util/compose'
import gql from 'graphql-tag'
import BaseLayout from 'client/components/layout/BaseLayout'
import {
    SimpleButton,
    SimpleDialog,
    Typography,
    TextField,
    Divider,
    DeleteIconButton,
    Chip,
    SimpleList,
    Row,
    Col
} from 'ui/admin'
import FileDrop from 'client/components/FileDrop'
import Util from 'client/util'
import config from 'gen/config'

const {BACKUP_URL} = config

class DbDumpContainer extends React.Component {

    constructor(props) {
        super(props)

        this.state = {
            creatingDump: false,
            creatingMediaDump: false,
            importingDbDump: false,
            importingMediaDump: false,
            importMediaDumpDialog: false,
            importDbDumpDialog: false
        }
    }

    createDump() {
        this.setState({creatingDump: true})
        this.props.createDbDump().then(e => {
            console.log(e)
            this.setState({creatingDump: false})
        })

    }

    createMediaDump() {
        this.setState({creatingMediaDump: true})
        this.props.createMediaDump().then(e => {
            console.log(e)
            this.setState({creatingMediaDump: false})
        })

    }

    importMediaDump() {
        this.setState({importMediaDumpDialog: true})
    }

    importDbDump() {
        this.setState({importDbDumpDialog: true})
    }

    handleConfirmMediaDialog() {
        this.setState({importMediaDumpDialog: false})
    }

    handleConfirmDbDialog() {
        this.setState({importDbDumpDialog: false})
    }

    handleMediaDumpUpload(e) {
        console.log(e)
    }

    download(content, filename, contentType)
    {
        if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
    }

    authorizedRequest(url, name){
        const xhr = new XMLHttpRequest

        xhr.open("GET",url)
        xhr.responseType = 'blob'

        xhr.addEventListener("load", () => {
            if( xhr.status === 200) {

                this.download(xhr.response, name, 'application/gzip')
            }else{

                alert(`Invalid status ${xhr.status}`)
            }
        }, false)

        xhr.setRequestHeader('Authorization', Util.getAuthToken())
        // xhr.overrideMimeType( "application/octet-stream; charset=x-user-defined;" )
        xhr.send(null)
    }

    render() {
        const {dbDumps, mediaDumps} = this.props
        const {creatingDump, creatingMediaDump, importingMediaDump, importMediaDumpDialog, importDbDumpDialog, importingDbDump} = this.state
        return (
            <BaseLayout>
                <Typography variant="h3" gutterBottom>Backups</Typography>

                <Row spacing={4}>
                    <Col md={6}>

                        <SimpleButton variant="contained" color="primary"
                                      showProgress={creatingDump}
                                      onClick={this.createDump.bind(this)}>{creatingDump ? 'Dump is beeing created' : 'Create new db dump'}</SimpleButton>

                        <SimpleButton color="secondary"
                                      disabled={importDbDumpDialog}
                                      showProgress={importingDbDump}
                                      onClick={this.importDbDump.bind(this)}>{importingDbDump ? 'Dump is beeing restored' : 'Restore db dump'}</SimpleButton>

                        {dbDumps && dbDumps.results && dbDumps.results.length > 0 &&
                        <SimpleList items={dbDumps.results.reduce((a, i) => {
                            a.push({
                                primary: i.name,
                                onClick: () => {

                                    this.authorizedRequest(BACKUP_URL + '/dbdumps/' + i.name, 'db.backup.gz' )

                                },
                                secondary: Util.formattedDatetime(i.createdAt) + ' - ' + i.size
                            })
                            return a
                        }, [])}/>
                        }
                    </Col>

                    <Col md={6}>

                        <SimpleButton variant="contained" color="primary"
                                      disabled={importMediaDumpDialog}
                                      showProgress={creatingMediaDump}
                                      onClick={this.createMediaDump.bind(this)}>{creatingMediaDump ? 'Dump is beeing created' : 'Create new media dump'}</SimpleButton>

                        <SimpleButton color="secondary"
                                      showProgress={importingMediaDump}
                                      onClick={this.importMediaDump.bind(this)}>{importingMediaDump ? 'Dump is beeing imported' : 'Import media dump'}</SimpleButton>

                        {mediaDumps && mediaDumps.results && mediaDumps.results.length > 0 &&
                        <SimpleList items={mediaDumps.results.reduce((a, i) => {
                            a.push({
                                primary: i.name,
                                onClick: () => {
                                    this.authorizedRequest(BACKUP_URL + '/mediadumbs/' + i.name, 'medias.backup.gz' )
                                },
                                secondary: Util.formattedDatetime(i.createdAt) + ' - ' + i.size
                            })
                            return a
                        }, [])}/>
                        }
                    </Col>
                </Row>

                <SimpleDialog open={importMediaDumpDialog} onClose={this.handleConfirmMediaDialog.bind(this)}
                              actions={[{key: 'close', label: 'Close'}]}
                              title="Select a media dump file">

                    <FileDrop style={{width: '15rem', height: '10rem'}} accept="application/x-gzip"
                              uploadTo="/graphql/upload/mediadump"
                              label="Drop file here"/>

                </SimpleDialog>

                <SimpleDialog open={importDbDumpDialog} onClose={this.handleConfirmDbDialog.bind(this)}
                              actions={[{key: 'close', label: 'Close'}]}
                              title="Select a db dump file">

                    <FileDrop style={{width: '15rem', height: '10rem'}} accept="application/x-gzip"
                              uploadTo="/graphql/upload/dbdump"
                              label="Drop file here"/>

                </SimpleDialog>

            </BaseLayout>
        )
    }
}

DbDumpContainer.propTypes = {
    /* apollo client props */
    dbDumps: PropTypes.object,
    createDbDump: PropTypes.func.isRequired,
    createMediaDump: PropTypes.func.isRequired,
    loading: PropTypes.bool,
    mediaDumps: PropTypes.object
}

const gqlQuery = gql`query{dbDumps{results{name createdAt size}}}`
const gqlUpdate = gql`mutation createDbDump($type:String){createDbDump(type:$type){name createdAt size}}`
const gqlQueryMedia = gql`query{mediaDumps{results{name createdAt size}}}`
const gqlUpdateMedia = gql`mutation createMediaDump($type:String){createMediaDump(type:$type){name createdAt size}}`

const DbDumpContainerWithGql = compose(
    graphql(gqlQuery, {
        options() {
            return {
                fetchPolicy: 'cache-and-network'
            }
        },
        props: ({data: {dbDumps}}) => ({
            dbDumps
        })
    }),
    graphql(gqlUpdate, {
        props: ({mutate}) => ({
            createDbDump: () => {
                return mutate({
                    variables: {type: 'full'},
                    update: (proxy, {data: {createDbDump}}) => {
                        // Read the data from our cache for this query.
                        const data = proxy.readQuery({query: gqlQuery})
                        // Add our note from the mutation to the end.
                        data.dbDumps.results.unshift(createDbDump)
                        // Write our data back to the cache.
                        proxy.writeQuery({query: gqlQuery, data})
                    }

                })
            }
        })
    }),
    graphql(gqlQueryMedia, {
        options() {
            return {
                fetchPolicy: 'cache-and-network'
            }
        },
        props: ({data: {mediaDumps}}) => ({
            mediaDumps
        })
    }),
    graphql(gqlUpdateMedia, {
        props: ({mutate}) => ({
            createMediaDump: () => {
                return mutate({
                    variables: {type: 'full'},
                    update: (proxy, {data: {createMediaDump}}) => {
                        // Read the data from our cache for this query.
                        const data = proxy.readQuery({query: gqlQueryMedia})
                        // Add our note from the mutation to the end.
                        data.mediaDumps.results.unshift(createMediaDump)
                        // Write our data back to the cache.
                        proxy.writeQuery({query: gqlQueryMedia, data})
                    }

                })
            }
        })
    })
)
(DbDumpContainer)

/**
 * Connect the component to
 * the Redux store.
 */
export default DbDumpContainerWithGql
<|endoftext|>