<commit_before>'use strict';
exports.info = {
  desc: 'Search messages for user/role mentions and posts results via DM.',
  usage: '[number]',
  aliases: [],
};

const moment = require('moment');
const logger = require('winston');
const utils = require('../utilities');

exports.run = (client, msg, params = []) => {
  // Exit if not ran in normal text channel (no DMs)
  if (msg.channel.type !== 'text') {
    msg.reply('Unable to get **mentions** from a DM channel.');
    utils.finish(msg, exports.name);
    return;
  }
  // Set amount of messages to retrieve
  let max = parseInt(params[0]) || 500;
  // Don't allow over 10k messages to be searched
  if (max > 10000) {
    max = 10000;
  }
  const responses = [];
  let count = 0;
  const delay = 1000;
  const roles = msg.member.roles;

  msg.channel.sendMessage(':mailbox_with_mail:');
  msg.author.sendMessage(`Searching for @ mentions in **#${msg.channel.name}**. Estimated time: ` +
    `${Math.floor((delay / 1000) * (max / 100))} seconds.`);

  function next(err, lastMessage) {
    if (err) {
      return;
    }
    count += 100;
    if (count >= max || !lastMessage) {
      utils.time(msg, 'io');
      processLogs();
    } else {
      getLogs(lastMessage);
    }
  }

  utils.time(msg, 'cpu');
  getLogs(msg);

  function getLogs(m) {
    setTimeout(() => {
      msg.channel.fetchMessages({ limit: 100, before: m.id })
        .then((messages) => {
          if (messages.size !== 100) {
            extractMentions(messages);
            next(null, null);
            return;
          }
          extractMentions(messages);
          next(null, messages[messages.length - 1]);
        })
        .catch(e => {
          logger.error('There was an error searching for @ mentions', e);
          next(true);
        });
    }, delay);
  }

  function extractMentions(messages) {
    messages.forEach(m => {
      if (m.mentions.everyone) {
        responses.push(m);
        return;
      }
      if (m.isMentioned(msg.author)) {
        responses.push(m);
        return;
      }
      roles.some(r => {
        if (m.isMentioned(r)) {
          m.content = m.content.replace(/<@&\d+>/g, `@${r.name}`);
          responses.push(m);
          return true;
        }
        return false;
      });
    });
  }

  function processLogs() {
    if (responses.length === 0) {
      msg.author.sendMessage(`\`\`No mentions were found in #${msg.channel.name}.\`\``);
      utils.finish(msg, exports.name);
      return;
    }
    const chunks = [];
    const header = `\`\`\`Mentions from #${msg.channel.name}.\`\`\`\n`;

    function nextChunk(start) {
      if (start) {
        chunk(start);
      } else {
        chunks.forEach(c => {
          msg.author.sendMessage(header + c, { disableEveryone: false });
        });
        utils.finish(msg, exports.name);
      }
    }

    chunk(responses.length - 1);

    function chunk(start) {
      let str = '';
      for (let i = start; i >= 0; i--) {
        const dur = moment(responses[i].timestamp).fromNow();
        const strToAdd = `\`\`${responses[i].author.username} - ${dur}\`\`\n${responses[i].content}\n\n`;
        const combinedLength = str.length + strToAdd.length + header.length;
        if (combinedLength > 2000) {
          chunks.push(str);
          nextChunk(i);
          return;
        } else {
          str += strToAdd;
        }
      }
      chunks.push(str);
      nextChunk(null);
    }
  }
};
<commit_msg>Updated mentions command<commit_after>'use strict';
exports.info = {
  desc: 'Search messages for user/role mentions and posts results via DM.',
  usage: '[number]',
  aliases: [],
};

const moment = require('moment');
const logger = require('winston');
const utils = require('../utilities');

exports.run = (client, msg, params = []) => new Promise(async(resolve, reject) => {
  // Exit if not ran in normal text channel (no DMs)
  if (msg.channel.type === 'dm') {
    utils.dmDenied(msg).then(resolve).catch(reject);
    return;
  }
  // Set amount of messages to retrieve
  let max = parseInt(params[0]) || 500;
  // Don't allow over 10k messages to be searched
  if (max > 10000) {
    max = 10000;
  }

  const delay = 1000;
  msg.channel.sendMessage(':mailbox_with_mail:');
  msg.author.sendMessage(`Searching for @ mentions in **#${msg.channel.name}**. Estimated time: ` +
    `${Math.floor((delay / 1000) * (max / 100))} seconds.`);

  const responses = [];
  let count = 0;
  let id = msg.channel.lastMessageID;
  let messages;

  while (count < max) {
    try {
      messages = await msg.channel.fetchMessages({ limit: 100, before: id });
      id = messages.first().id;
      responses.concat(messages);
    } catch (err) {
      logger.error(err);
    }
    count += 100;
    await dwell(delay);
  }
  const mentions = extractMentions(msg, messages);
  processMentions(msg, mentions).then(resolve).catch(reject);
});

function dwell(d) {
  return new Promise(resolve => setTimeout(resolve, d));
}

function extractMentions(msg, messages) {
  const mentions = [];
  messages.forEach(m => {
    if (m.mentions.everyone) {
      mentions.push(m);
      return;
    }
    if (m.isMentioned(msg.author)) {
      mentions.push(m);
      return;
    }
    msg.member.roles.some(r => {
      if (m.isMentioned(r)) {
        m.content = m.content.replace(/<@&\d+>/g, `@${r.name}`);
        mentions.push(m);
        return true;
      }
      return false;
    });
  });
  return mentions;
}

function processMentions(msg, mentions) {
  return new Promise((resolve, reject) => {
    if (mentions.length === 0) {
      msg.author.sendMessage(`\`\`No mentions were found in #${msg.channel.name}.\`\``)
        .then(resolve).catch(reject);
      return;
    }
    const header = `\`\`\`Mentions from #${msg.channel.name}.\`\`\`\n`;
    const chunks = [];
    let str = '';
    logger.debug('mentions to mention:', mentions.length);
    mentions.reverse().forEach(message => {
      const dur = moment(message.createdAt).fromNow();
      const strToAdd = `\`\`${message.author.username} - ${dur}\`\`\n${message.content}\n\n`;
      const combinedLength = str.length + strToAdd.length + header.length;
      if (combinedLength < 1950) {
        str += strToAdd;
      } else {
        chunks.push(str);
        str = '';
      }
    });
    chunks.push(str);
    chunks.forEach(c => {
      msg.author.sendMessage(header + c);
    });
  });
}
<|endoftext|>


<commit_before>function libPath(libFilePath){
  var pathToLib = '../lib/'
  return(pathToLib + libFilePath);
}

var auth = require(libPath('auth.js'));

var expect = require('chai').expect;

describe('auth', function(){
  var config;
  var configValidationFail;

  var modelStub = function(){
    var _modelData = {};
    return {
      save: function(key, values){
        _modelData[key] = values;
      },
      get:  function(key){
        return _modelData[key];
      },
      all: function(){
        return _modelData;
      }
    };
  }();

  beforeEach(function(){
    config = {
      validator: function(email) { return email }
    };
    configValidationFail = {
      validator: function(email) { return null }
    }
  });

  it('sanity check', function(){
    expect(auth).to.exist;
  });

  it('is a function', function(){
    expect(auth).to.be.a('function');
  });

  // how to clone functions? until then clobbering occurs
//  it('can be configured without clobbering', function(){
//    var a = auth(config);
//    expect(a.config).to.eql(config);
//    expect(a.config).to.not.equal(config);
//  });

  it('is not a singleton', function(){
    var a1 = auth(config);
    var a2 = auth(configValidationFail);
    expect(a1.config).to.not.eql(a2.config);
  });

  describe('.request', function(){
    var req1, opts1;

    beforeEach(function(){
      var email1 = "email1";

      opts1 = {
        challenge: "who goes there?",
        response: "tis me.",
        listener: {}
      };

      req1 = {
        email: email1,
        challenge: opts1.challenge,
        response: opts1.response,
        listener: opts1.listener
      }
    });

    it('is a function', function(){
      expect(auth(config).request).to.be.a('function');
    });

    it('returns error if email is not a string', function(){
      var email = 32;
      expect( auth(config).request(email) ).to.be.instanceof(Error)
        .and.have.property('message', 'Invalid email, not a string');
    });

    describe('reqReceived', function(){

      it('returns email to  callback if request is valid', function(){
        var email = 'my_email';

        req1.listener.reqReceived = function(err, status) {
          expect(status).to.eql(email);
        };

        expect( auth(config).request(email, req1) ).to.not.be.instanceof(Error)
      });

      it('returns error to callback if email is not a string', function(){
        var email = 32;
        var errorMessage = 'Invalid email, not a string';

        req1.listener.reqReceived = function(err, status) {
          expect(err).to.eql({error: errorMessage});
        };

        expect( auth(config).request(email, req1) ).to.be.instanceof(Error)
          .and.have.property('message', 'Invalid email, not a string');

      });

    });

    describe('reqValidated', function() {

      it('calls the validator in the config options', function(){
        var validEmail = 'my_email';
        var spy=false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(validEmail);
            return email
          }
        };

        expect( auth(vConfig).request(validEmail, req1)).to.not.be.instanceof(Error);
        expect( spy).to.be.equal(true);

      });

      it('returns email to  callback if request is valid', function(){
        var validEmail = 'my_valid_email';
        var spy = false;
        var statusChecked = false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(validEmail);
            return email
          }
        };

        req1.listener.reqValidated = function(err, status) {
          statusChecked = true;
          expect(err).to.be.equal(null);
          expect(status).to.eql(validEmail);
        };

        expect( auth(vConfig).request(validEmail, req1) ).to.not.be.instanceof(Error)

        expect(statusChecked).to.equal(true);
      });

      it('returns error to  listener if email does not validate', function(){
        var inValidEmail = 'my_invalid_email';
        var spy = false;
        var statusChecked = false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(inValidEmail);
            return undefined
          }
        };

        req1.listener.reqValidated = function(err, status) {
          statusChecked = true;
          expect(err).to.be.eql({error: 'failed validation'});
          expect(status).to.eql(undefined);
        };

        expect( auth(vConfig).request(inValidEmail, req1) ).to.be.instanceof(Error)
        expect(statusChecked).to.equal(true);
      });
    });

    describe('processing', function() {
      it('consumes request');
    });

    describe('callback', function() {
      it('provides callback (Change to emitter?????)');
    });

    describe('model', function() {

      describe('saving', function(){
        var validEmail;
        var mConfig;
        var authResp;

        beforeEach(function(){
          validEmail = 'email_to_persist'
          mConfig = {
            validator: function(email) {
              return email
            },
            model: modelStub
          };

          //create the request
          authResp = auth(mConfig).request(validEmail, req1)
        });

        it('does not error when requesting', function(){
          expect( authResp ).to.not.be.instanceof(Error);
        });

        it('saves email to the model', function(){
          var record = mConfig.model.get(validEmail);
          expect( record.email ).to.eql(validEmail);
        });
      });
    });

//    var res1 = a1.config.validator('dummy');
//    var res2 = a2.config.validator('dummy');
//    expect(res1).to.not.eql(res2);
  });
});

<commit_msg>tests for auth().request -- WIP basic model save interface working, all fields<commit_after>function libPath(libFilePath){
  var pathToLib = '../lib/'
  return(pathToLib + libFilePath);
}

var auth = require(libPath('auth.js'));

var expect = require('chai').expect;

describe('auth', function(){
  var config;
  var configValidationFail;

  var modelStub = function(){
    var _modelData = {};
    return {
      save: function(key, values){
        _modelData[key] = values;
      },
      get:  function(key){
        return _modelData[key];
      },
      all: function(){
        return _modelData;
      }
    };
  }();

  beforeEach(function(){
    config = {
      validator: function(email) { return email }
    };
    configValidationFail = {
      validator: function(email) { return null }
    }
  });

  it('sanity check', function(){
    expect(auth).to.exist;
  });

  it('is a function', function(){
    expect(auth).to.be.a('function');
  });

  // how to clone functions? until then clobbering occurs
//  it('can be configured without clobbering', function(){
//    var a = auth(config);
//    expect(a.config).to.eql(config);
//    expect(a.config).to.not.equal(config);
//  });

  it('is not a singleton', function(){
    var a1 = auth(config);
    var a2 = auth(configValidationFail);
    expect(a1.config).to.not.eql(a2.config);
  });

  describe('.request', function(){
    var req1, opts1;

    beforeEach(function(){
      var email1 = "email1";

      opts1 = {
        challenge: "who goes there?",
        response: "tis me.",
        listener: {}
      };

      req1 = {
        email: email1,
        challenge: opts1.challenge,
        response: opts1.response,
        listener: opts1.listener
      }
    });

    it('is a function', function(){
      expect(auth(config).request).to.be.a('function');
    });

    it('returns error if email is not a string', function(){
      var email = 32;
      expect( auth(config).request(email) ).to.be.instanceof(Error)
        .and.have.property('message', 'Invalid email, not a string');
    });

    describe('reqReceived', function(){

      it('returns email to  callback if request is valid', function(){
        var email = 'my_email';

        req1.listener.reqReceived = function(err, status) {
          expect(status).to.eql(email);
        };

        expect( auth(config).request(email, req1) ).to.not.be.instanceof(Error)
      });

      it('returns error to callback if email is not a string', function(){
        var email = 32;
        var errorMessage = 'Invalid email, not a string';

        req1.listener.reqReceived = function(err, status) {
          expect(err).to.eql({error: errorMessage});
        };

        expect( auth(config).request(email, req1) ).to.be.instanceof(Error)
          .and.have.property('message', 'Invalid email, not a string');

      });

    });

    describe('reqValidated', function() {

      it('calls the validator in the config options', function(){
        var validEmail = 'my_email';
        var spy=false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(validEmail);
            return email
          }
        };

        expect( auth(vConfig).request(validEmail, req1)).to.not.be.instanceof(Error);
        expect( spy).to.be.equal(true);

      });

      it('returns email to  callback if request is valid', function(){
        var validEmail = 'my_valid_email';
        var spy = false;
        var statusChecked = false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(validEmail);
            return email
          }
        };

        req1.listener.reqValidated = function(err, status) {
          statusChecked = true;
          expect(err).to.be.equal(null);
          expect(status).to.eql(validEmail);
        };

        expect( auth(vConfig).request(validEmail, req1) ).to.not.be.instanceof(Error)

        expect(statusChecked).to.equal(true);
      });

      it('returns error to  listener if email does not validate', function(){
        var inValidEmail = 'my_invalid_email';
        var spy = false;
        var statusChecked = false;

        var vConfig = {
          validator: function(email) {
            spy=true;
            expect(email).to.eql(inValidEmail);
            return undefined
          }
        };

        req1.listener.reqValidated = function(err, status) {
          statusChecked = true;
          expect(err).to.be.eql({error: 'failed validation'});
          expect(status).to.eql(undefined);
        };

        expect( auth(vConfig).request(inValidEmail, req1) ).to.be.instanceof(Error)
        expect(statusChecked).to.equal(true);
      });
    });

    describe('processing', function() {
      it('consumes request');
    });

    describe('callback', function() {
      it('provides callback (Change to emitter?????)');
    });

    describe('model', function() {

      describe('saving', function(){
        var validEmail;
        var mConfig;
        var authResp;

        beforeEach(function(){
          validEmail = 'email_to_persist'
          mConfig = {
            validator: function(email) {
              return email
            },
            model: modelStub
          };

          //create the request
          authResp = auth(mConfig).request(validEmail, req1)
        });

        it('does not error when requesting', function(){
          expect( authResp ).to.not.be.instanceof(Error);
        });

        it('saves email to the model', function(){
          var record = mConfig.model.get(validEmail);
          expect( record.email ).to.eql(validEmail);
        });

        it('saves challenge/response to the model', function(){
          var record = mConfig.model.get(validEmail);
          expect( record.challenge ).to.eql(req1.challenge);
          expect( record.response ).to.eql(req1.response);
        });

        it('saves a randomStr to the model', function(){
          var record = mConfig.model.get(validEmail);
          expect( typeof record.randomStr ).to.equal('string');
          expect( record.randomStr.length).to.equal(64);
        });

        it('saves a staleVerification to the model', function(){
          var record = mConfig.model.get(validEmail);
          console.dir(record);
          expect( record.staleVerification).to.be.within(0, Infinity);
        });

      });
    });

//    var res1 = a1.config.validator('dummy');
//    var res2 = a2.config.validator('dummy');
//    expect(res1).to.not.eql(res2);
  });
});

<|endoftext|>


<commit_before>'use strict';
var   express = require('express') // 'express' is used in bodyParser if needed
    , router = express.Router()
    , ds = require('../lib/datasift')
    ;

/*
 * POST compile - wrapper to DataSift compile
 *
 * @params todo
 */
router.post('/compile', function(req, res) {
    var auth = req.header('Authorization') || '';
    var csdl = req.rawBody || '';

    ds.compile(csdl, auth, function callback(err, response, body) {
        if(err){
            res.status(err.status || 500);
            res.render('500', { error: err });
        }
        // Pass through the statusCode and Content-Type from the DS response object.
        res.writeHead(response.statusCode, { 'Content-Type': response.headers['content-type'] });
        res.write(body);
        res.end();
    });
});

router.get('/test', function(req, res) {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.write(JSON.stringify({insecticons : ["Shrapnel","Bombshell", "Kickback"]}));
    res.end();
});

module.exports = router;
<commit_msg>Compile API route.<commit_after>'use strict';
var   express = require('express') // 'express' is used in bodyParser if needed
    , router = express.Router()
    , ds = require('../lib/datasift')
    ;

/*
 * POST compile - wrapper to DataSift compile
 *
 */
router.post('/compile', function(req, res) {
    var auth = req.header('Authorization') || '';
    var csdl = req.rawBody || '';

    ds.compile(csdl, auth, function callback(err, response, body) {
        if(err){
            res.status(err.status || 500);
            res.render('500', { error: err });
        }
        // Pass through the statusCode and Content-Type from the DS response object.
        res.writeHead(response.statusCode, { 'Content-Type': response.headers['content-type'] });
        res.write(body);
        res.end();
    });
});

/*
 * POST create - historic preview
 *
 */
router.post('/create', function(req, res) {
    var auth = req.header('Authorization') || '';
    var params = req.rawBody || '';

    ds.create(params, auth, function callback(err, response, body) {
        if(err){
            res.status(err.status || 500);
            res.render('500', { error: err });
        }
        // Pass through the statusCode and Content-Type from the DS response object.
        res.writeHead(response.statusCode, { 'Content-Type': response.headers['content-type'] });
        res.write(body);
        res.end();
    });
});

router.get('/test', function(req, res) {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.write(JSON.stringify({insecticons : ["Shrapnel","Bombshell", "Kickback"]}));
    res.end();
});

module.exports = router;
<|endoftext|>


<commit_before> 'use strict';

var build       = exports;
var fs          = require('fs');
var fse         = require('fs-extra');
var expand      = require('fs-expand');
var node_path   = require('path');
var semver      = require('semver');
var stable      = require('semver-stable');
var async       = require('async');
var cortex_json   = require('read-cortex-json');
var semver_helper = require('../util/semver');
var lang        = require('../util/lang');
var spawns      = require('spawns');
var builder     = require('neuron-builder');
var nconfig     = require('neuron-config');

// @param {Object} options
//      see ./lib/option/build.js for details
build.run = function(options, callback) {
  this.MESSAGE = this.locale.require('command-build');

  var self = this;
  async.eachSeries([
    'read_package_json',
    // run custom build script
    'run_preinstall_script',
    'run_prebuild_script',
    // real building
    'build',
    'server_link'
  ], function (task, done) {
    self[task](options, done);
  }, callback);
};

build.read_package_json = function(options, callback) {
  cortex_json.read(options.cwd, function(err, pkg) {
    options.pkg = pkg;
    callback(err);
  });
};

// Creates a symlink from `from` to `to`.
// If `from` exists, it will remove it.
build.link = function (from, to, callback) {
  function link () {
    fs.symlink(to, from, callback);
    link = null;
  }

  fs.lstat(from, function (err, stat) {
    // not found
    if (err && err.code === 'ENOENT') {
      return link();
    }
    fse.remove(from, function (err) {
      link();
    });
  });
};

// Run custom build scripts, such as 'grunt'
build.run_preinstall_script = function(options, callback) {
  if (!options.preinstall) {
    return callback(null);
  }
  this.run_script('preinstall', options, callback);
};

// Run custom build scripts, such as 'grunt'
build.run_prebuild_script = function(options, callback) {
  if (!options.prebuild) {
    return callback(null);
  }
  this.run_script('prebuild', options, callback);
};

build.run_script = function(script, options, callback) {
  var pkg = options.pkg;
  var scripts = lang.makeArray(pkg.scripts && pkg.scripts[script])
  // skip empty scripts
  .filter(Boolean);

  if (!scripts.length) {
    return callback(null);
  }

  var self = this;

  this.logger.info('{{cyan run}} "scripts.' + script + '" ...');

  spawns(scripts, {
    cwd: options.cwd,
    stdio: 'inherit'

  }).on('spawn', function(command) {
    self.logger.info(' - {{cyan exec}} "' + command + '" ...');

  }).on('close', function(code, signal) {
    if (code) {
      callback({
        code: 'EBUILDSCRIPT',
        message: 'build step "scripts.' + script + '" executes as a failure. exit code: ' + code,
        data: {
          code: code,
          signal: signal,
          script: script
        }
      });
    } else {
      callback(null);
    }

  }).on('error', function(err) {
    self.logger.warn('"scripts.' + script + '" let out an error: ' + err);
  });
};

build.build = function(options, callback) {
  var pkg = options.pkg;
  // distribution directory
  var dist = lang.object_member_by_namespaces(options.pkg, 'directories.dist');
  var to = node_path.join(options.dest, pkg.name, pkg.version);
  options.to = to;

  if (dist) {
    return this.dist(dist, options, callback);
  }

  var self = this;
  this.check_entry(options, function(err) {
    if (err) {
      return callback(err);
    }

    async.parallel([
      function (done) {
        // Build JavaScript modules
        self.build_modules(to, options, done);
      },
      function (done) {
        self.copy(options.cwd, to, 'cortex-shrinkwrap.json', done);
      },
      function (done) {
        // Copy css
        self.copy_csses(to, options, done);
      },
      function (done) {
        // Copy directories
        self.copy_directories(to, options, done);
      },
      function (done) {
        self.generate_config(options, done);
      }
    ], callback);
  });
};

build.server_link = function (options, callback) {
  if (!options.link) {
    return callback(null);
  }

  var built_root = this.profile.get('built_root');
  if (built_root === options.dest) {
    return callback(null);
  }

  var pkg_dir = node_path.join(options.pkg.name, options.pkg.version);
  var to = node_path.join(built_root, pkg_dir);
  var from = node_path.join(options.dest, pkg_dir);
  var logger = this.logger;
  this.link(from, to, function (err) {
    if (err) {
      return callback(err);
    }

    logger.info(' {{cyan link}} ' + from + ' -> ' + to);
    callback(null);
  });
};

build.dist = function (dist, options, callback) {
  var rel_dist = dist;
  var dist = node_path.join(options.cwd, dist);
  // if `dist` dir exists, skip building and just copy it
  fs.exists(dist, function(exists) {
    if (!exists) {
      // if `cortex.directories.dist` is declared, the dir must be existed.
      return callback({
        code: 'DIST_NOT_FOUND',
        message: 'dist dir "' + dist + '" does not exist.',
        data: {
          dist: dist
        }
      });
    }

    this.logger.info('dist dir "' + dist + '" found, {{cyan skip}} building ...');
    this.copy_dist(rel_dist, options, callback);
  }.bind(this));
};

// copy dist dir to the destination dirs
build.copy_dist = function(dist, options, callback) {
  var self = this;
  var tasks = options.tasks;
  var dist_dir = node_path.join(options.cwd, dist);
  self.copy(dist_dir, options.to, null, callback);
};

build.check_entry = function (options, callback) {
  var self = this;
  this.main_exists(options, function (exists) {
    if (exists) {
      var cwd = options.cwd;
      var pkg = options.pkg;
      // the module '<name>.js'
      var main_by_name = node_path.join(cwd, pkg.name) + '.js';
      var main_path = node_path.join(cwd, options.main_entry);

      fs.exists(main_by_name, function(exists) {
        if (exists && main_by_name !== main_path) {
          return callback({
            code: 'MAIN_CONFLICT',
            message: 'if "' + pkg.name + '.js" exists, it must be `package.main`, or you should rename it.',
            data: {
              name: pkg.name,
              main: pkg.main
            }
          });
        }
        self.get_entries(options, callback);
      });
      return;
    }

    if (!options.pkg.css) {
      return callback({
        code: 'NO_ENTRY_FOUND',
        message: 'Both `cortex.main` and `cortex.css` are not found in "'
          + options.pkg.name + '@' + options.pkg.version + '". '
          + 'it needs to define at least one.'
      });
    }
    callback(null);
  });
};

build.main_exists = function (options, callback) {
  var main_entry = options.pkg.main || 'index.js';

  // Standardize main entry
  // './index' -> './index.js'
  main_entry = this.ensure_ext(main_entry, 'js');
  // './index.js' -> 'index.js'
  main_entry = node_path.join('.', main_entry);
  var main_file = node_path.join(options.cwd, main_entry);

  fs.exists(main_file, function (exists) {
    if (exists) {
      options.main_entry = main_entry;
    }
    callback(exists);
  });
};

// Gets all entries, including
// - pkg.main
// - pkg.entries
build.get_entries = function(options, callback) {
  var pkg_entries = options.pkg.entries;
  if (!pkg_entries) {
    options.entries = [options.main_entry];
    return callback(null);
  }

  expand(pkg_entries, {
    cwd: options.cwd
  }, function (err, entries) {
    if (err) {
      return callback(err);
    }
    options.entries = entries;
    // prevent duplication
    if (!~entries.indexOf(options.main_entry)) {
      entries.push(options.main_entry);
    }

    callback(null);
  });
};

build.ensure_ext = function(path, ext) {
  var regex = new RegExp('\\.' + ext + '$', 'i');
  if (!regex.test(path)) {
    path += '.' + ext;
  }
  return path;
};

// Builds JavaScript modules
build.build_modules = function(to, options, callback) {
  // Pure css package.
  if (!options.main_entry) {
    return callback(null);
  }

  var self = this;
  var cwd = options.cwd;
  var pkg = options.pkg;
  async.each(options.entries, function (entry, done) {
    // Standardize entries
    // './index.js' -> 'index.js'
    entry = node_path.join('.', entry);
    var from = node_path.join(cwd, entry);

    builder(from, {
      cwd: cwd,
      targetVersion: pkg.version,
      pkg: options.pkg

    }, function (err, content) {
      if (err) {
        return done(err);
      }

      var file_to = entry === options.main_entry
        // main entry will
        ? pkg.name + '.js'
        : entry;

      var path_to = node_path.join(to, file_to);
      fse.outputFile(path_to, content, function (err) {
        if (err) {
          return done(err);
        }
        self.logger.info('{{cyan write}} ' + path_to);
        done(null);
      });
    });
  }, callback);
};

build.copy_csses = function (to, options, callback) {
  var css = options.pkg.css;
  if (!css) {
    return callback(null);
  }

  async.each(css, function (path, done) {
    this.copy(options.cwd, to, path, function (err) {
      if (err && err.code === 'SRC_NOT_FOUND') {
        err = {
          code: 'CSS_NOT_FOUND',
          message: '`pkg.css`, "' + path + '" is declared but not found.',
          data: {
            path: path
          }
        };
      }
      done(err);
    }, true);
  }.bind(this), callback);
};

build.copy_directories = function(to, options, callback) {
  var pkg = options.pkg;
  var directories = pkg.directories || {};

  var tasks = [
    // We only support `directories.src` for now.
    'src'
  ].filter(function (dir) {
    return directories[dir];
  });

  async.each(tasks, function (name, done) {
    var dir = directories[name];
    this.copy(options.cwd, to, dir, function (err) {
      if (err && err.code === 'SRC_NOT_FOUND') {
        err = {
          code: 'DIR_NOT_FOUND',
          message: '`directories.' + name + '` is defined in cortex.json, but not found.',
          data: {
            name: name,
            dir: dir
          }
        };
      }
      done(err);
    }, true);

  }.bind(this), callback);
};

// Copy item from `from` to `to`
// @param {String=} item If is undefined, will copy `from` to `to`
// @param {Boolean} strict
build.copy = function(from, to, item, callback, strict) {
  var self = this;
  if (from === to) {
    callback(null);
    return;
  }

  if (item) {
    from = node_path.join(from, item);
    to = node_path.join(to, item);
  }

  fs.exists(from, function (exists) {
    if (!exists) {
      // if strict and the source is not found, an error will throw.
      if (strict) {
        return callback({
          code: 'SRC_NOT_FOUND'
        });
      } else {
        return callback(null);
      }
    }

    self.logger.info(' {{cyan copy}} ' + from + ' -> ' + to);
    fse.copy(from, to, callback);
  });
};

build.generate_config = function (options, callback) {
  if (!options._config) {
    return callback(null);
  }

  var pkg = options.pkg;
  nconfig({
    cwd: options.cwd,
    built_root: options.dest,
    cache_root: this.profile.get('cache_root'),
    pkg: pkg

  }, function (err, config) {
    if (err) {
      return callback(err);
    }

    var tree = config.tree;
    var tasks = ['_', pkg.name, '*'];
    tasks.reduce(function (prev, key, index) {
      if (index === tasks.length - 1) {
        prev[key] = pkg.version;
        return;
      }

      return prev[key] || (prev[key] = {});
    }, tree);

    var config_file = node_path.join(options.dest, 'config.js');
    fse.outputFile(config_file, 'neuron.config(' + JSON.stringify(config, null, 2) + ');', callback);
  });
};
<commit_msg>command/build: try to fix EEXIST error when cortex build; #407<commit_after> 'use strict';

var build       = exports;
var fs          = require('fs');
var fse         = require('fs-extra');
var expand      = require('fs-expand');
var node_path   = require('path');
var semver      = require('semver');
var stable      = require('semver-stable');
var async       = require('async');
var cortex_json   = require('read-cortex-json');
var semver_helper = require('../util/semver');
var lang        = require('../util/lang');
var spawns      = require('spawns');
var builder     = require('neuron-builder');
var nconfig     = require('neuron-config');

// @param {Object} options
//      see ./lib/option/build.js for details
build.run = function(options, callback) {
  this.MESSAGE = this.locale.require('command-build');

  var self = this;
  async.eachSeries([
    'read_package_json',
    // run custom build script
    'run_preinstall_script',
    'run_prebuild_script',
    // real building
    'build',
    'server_link'
  ], function (task, done) {
    self[task](options, done);
  }, callback);
};

build.read_package_json = function(options, callback) {
  cortex_json.read(options.cwd, function(err, pkg) {
    options.pkg = pkg;
    callback(err);
  });
};

// Creates a symlink from `from` to `to`.
// If `from` exists, it will remove it.
build.link = function (from, to, callback) {
  function link () {
    fs.symlink(to, from, callback);
    link = null;
  }

  fs.lstat(from, function (err, stat) {
    // not found
    if (err && err.code === 'ENOENT') {
      return link();
    }
    fse.remove(from, function (err) {
      link();
    });
  });
};

// Run custom build scripts, such as 'grunt'
build.run_preinstall_script = function(options, callback) {
  if (!options.preinstall) {
    return callback(null);
  }
  this.run_script('preinstall', options, callback);
};

// Run custom build scripts, such as 'grunt'
build.run_prebuild_script = function(options, callback) {
  if (!options.prebuild) {
    return callback(null);
  }
  this.run_script('prebuild', options, callback);
};

build.run_script = function(script, options, callback) {
  var pkg = options.pkg;
  var scripts = lang.makeArray(pkg.scripts && pkg.scripts[script])
  // skip empty scripts
  .filter(Boolean);

  if (!scripts.length) {
    return callback(null);
  }

  var self = this;

  this.logger.info('{{cyan run}} "scripts.' + script + '" ...');

  spawns(scripts, {
    cwd: options.cwd,
    stdio: 'inherit'

  }).on('spawn', function(command) {
    self.logger.info(' - {{cyan exec}} "' + command + '" ...');

  }).on('close', function(code, signal) {
    if (code) {
      callback({
        code: 'EBUILDSCRIPT',
        message: 'build step "scripts.' + script + '" executes as a failure. exit code: ' + code,
        data: {
          code: code,
          signal: signal,
          script: script
        }
      });
    } else {
      callback(null);
    }

  }).on('error', function(err) {
    self.logger.warn('"scripts.' + script + '" let out an error: ' + err);
  });
};

build.build = function(options, callback) {
  var pkg = options.pkg;
  // distribution directory
  var dist = lang.object_member_by_namespaces(options.pkg, 'directories.dist');
  var to = node_path.join(options.dest, pkg.name, pkg.version);
  options.to = to;

  if (dist) {
    return this.dist(dist, options, callback);
  }

  var self = this;
  this.check_entry(options, function(err) {
    if (err) {
      return callback(err);
    }

    async.parallel([
      function (done) {
        // Build JavaScript modules
        self.build_modules(to, options, done);
      },
      function (done) {
        self.copy(options.cwd, to, 'cortex-shrinkwrap.json', done);
      },
      function (done) {
        // Copy css
        self.copy_csses(to, options, done);
      },
      function (done) {
        // Copy directories
        self.copy_directories(to, options, done);
      },
      function (done) {
        self.generate_config(options, done);
      }
    ], callback);
  });
};

build.server_link = function (options, callback) {
  if (!options.link) {
    return callback(null);
  }

  var built_root = this.profile.get('built_root');
  if (built_root === options.dest) {
    return callback(null);
  }

  var pkg_dir = node_path.join(options.pkg.name, options.pkg.version);
  var to = node_path.join(built_root, pkg_dir);
  var from = node_path.join(options.dest, pkg_dir);
  var logger = this.logger;
  this.link(from, to, function (err) {
    if (err) {
      return callback(err);
    }

    logger.info(' {{cyan link}} ' + from + ' -> ' + to);
    callback(null);
  });
};

build.dist = function (dist, options, callback) {
  var rel_dist = dist;
  var dist = node_path.join(options.cwd, dist);
  // if `dist` dir exists, skip building and just copy it
  fs.exists(dist, function(exists) {
    if (!exists) {
      // if `cortex.directories.dist` is declared, the dir must be existed.
      return callback({
        code: 'DIST_NOT_FOUND',
        message: 'dist dir "' + dist + '" does not exist.',
        data: {
          dist: dist
        }
      });
    }

    this.logger.info('dist dir "' + dist + '" found, {{cyan skip}} building ...');
    this.copy_dist(rel_dist, options, callback);
  }.bind(this));
};

// copy dist dir to the destination dirs
build.copy_dist = function(dist, options, callback) {
  var self = this;
  var tasks = options.tasks;
  var dist_dir = node_path.join(options.cwd, dist);
  self.copy(dist_dir, options.to, null, callback);
};

build.check_entry = function (options, callback) {
  var self = this;
  this.main_exists(options, function (exists) {
    if (exists) {
      var cwd = options.cwd;
      var pkg = options.pkg;
      // the module '<name>.js'
      var main_by_name = node_path.join(cwd, pkg.name) + '.js';
      var main_path = node_path.join(cwd, options.main_entry);

      fs.exists(main_by_name, function(exists) {
        if (exists && main_by_name !== main_path) {
          return callback({
            code: 'MAIN_CONFLICT',
            message: 'if "' + pkg.name + '.js" exists, it must be `package.main`, or you should rename it.',
            data: {
              name: pkg.name,
              main: pkg.main
            }
          });
        }
        self.get_entries(options, callback);
      });
      return;
    }

    if (!options.pkg.css) {
      return callback({
        code: 'NO_ENTRY_FOUND',
        message: 'Both `cortex.main` and `cortex.css` are not found in "'
          + options.pkg.name + '@' + options.pkg.version + '". '
          + 'it needs to define at least one.'
      });
    }
    callback(null);
  });
};

build.main_exists = function (options, callback) {
  var main_entry = options.pkg.main || 'index.js';

  // Standardize main entry
  // './index' -> './index.js'
  main_entry = this.ensure_ext(main_entry, 'js');
  // './index.js' -> 'index.js'
  main_entry = node_path.join('.', main_entry);
  var main_file = node_path.join(options.cwd, main_entry);

  fs.exists(main_file, function (exists) {
    if (exists) {
      options.main_entry = main_entry;
    }
    callback(exists);
  });
};

// Gets all entries, including
// - pkg.main
// - pkg.entries
build.get_entries = function(options, callback) {
  var pkg_entries = options.pkg.entries;
  if (!pkg_entries) {
    options.entries = [options.main_entry];
    return callback(null);
  }

  expand(pkg_entries, {
    cwd: options.cwd
  }, function (err, entries) {
    if (err) {
      return callback(err);
    }
    options.entries = entries;
    // prevent duplication
    if (!~entries.indexOf(options.main_entry)) {
      entries.push(options.main_entry);
    }

    callback(null);
  });
};

build.ensure_ext = function(path, ext) {
  var regex = new RegExp('\\.' + ext + '$', 'i');
  if (!regex.test(path)) {
    path += '.' + ext;
  }
  return path;
};

// Builds JavaScript modules
build.build_modules = function(to, options, callback) {
  // Pure css package.
  if (!options.main_entry) {
    return callback(null);
  }

  var self = this;
  var cwd = options.cwd;
  var pkg = options.pkg;
  async.each(options.entries, function (entry, done) {
    // Standardize entries
    // './index.js' -> 'index.js'
    entry = node_path.join('.', entry);
    var from = node_path.join(cwd, entry);

    builder(from, {
      cwd: cwd,
      targetVersion: pkg.version,
      pkg: options.pkg

    }, function (err, content) {
      if (err) {
        return done(err);
      }

      var file_to = entry === options.main_entry
        // main entry will
        ? pkg.name + '.js'
        : entry;

      var path_to = node_path.join(to, file_to);
      fse.mkdirs( node_path.dirname(path_to), function (err) {
        // #407
        // There might be a bug of `fs-extra` that it will throw an `EEXIST` error
        // if the dir already exists.
        if (err && err.code !== 'EEXIST') {
          return done(err);
        }
        fs.writeFile(path_to, content, function (err) {
          if (err) {
            return done(err);
          }
          self.logger.info('{{cyan write}} ' + path_to);
          done(null);
        });
      });
    });

  }, callback);
};

build.copy_csses = function (to, options, callback) {
  var css = options.pkg.css;
  if (!css) {
    return callback(null);
  }

  async.each(css, function (path, done) {
    this.copy(options.cwd, to, path, function (err) {
      if (err && err.code === 'SRC_NOT_FOUND') {
        err = {
          code: 'CSS_NOT_FOUND',
          message: '`pkg.css`, "' + path + '" is declared but not found.',
          data: {
            path: path
          }
        };
      }
      done(err);
    }, true);
  }.bind(this), callback);
};

build.copy_directories = function(to, options, callback) {
  var pkg = options.pkg;
  var directories = pkg.directories || {};

  var tasks = [
    // We only support `directories.src` for now.
    'src'
  ].filter(function (dir) {
    return directories[dir];
  });

  async.each(tasks, function (name, done) {
    var dir = directories[name];
    this.copy(options.cwd, to, dir, function (err) {
      if (err && err.code === 'SRC_NOT_FOUND') {
        err = {
          code: 'DIR_NOT_FOUND',
          message: '`directories.' + name + '` is defined in cortex.json, but not found.',
          data: {
            name: name,
            dir: dir
          }
        };
      }
      done(err);
    }, true);

  }.bind(this), callback);
};

// Copy item from `from` to `to`
// @param {String=} item If is undefined, will copy `from` to `to`
// @param {Boolean} strict
build.copy = function(from, to, item, callback, strict) {
  var self = this;
  if (from === to) {
    callback(null);
    return;
  }

  if (item) {
    from = node_path.join(from, item);
    to = node_path.join(to, item);
  }

  fs.exists(from, function (exists) {
    if (!exists) {
      // if strict and the source is not found, an error will throw.
      if (strict) {
        return callback({
          code: 'SRC_NOT_FOUND'
        });
      } else {
        return callback(null);
      }
    }

    self.logger.info(' {{cyan copy}} ' + from + ' -> ' + to);
    fse.copy(from, to, callback);
  });
};

build.generate_config = function (options, callback) {
  if (!options._config) {
    return callback(null);
  }

  var pkg = options.pkg;
  nconfig({
    cwd: options.cwd,
    built_root: options.dest,
    cache_root: this.profile.get('cache_root'),
    pkg: pkg

  }, function (err, config) {
    if (err) {
      return callback(err);
    }

    var tree = config.tree;
    var tasks = ['_', pkg.name, '*'];
    tasks.reduce(function (prev, key, index) {
      if (index === tasks.length - 1) {
        prev[key] = pkg.version;
        return;
      }

      return prev[key] || (prev[key] = {});
    }, tree);

    var config_file = node_path.join(options.dest, 'config.js');
    fse.outputFile(config_file, 'neuron.config(' + JSON.stringify(config, null, 2) + ');', callback);
  });
};
<|endoftext|>


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

var router = express.Router();
var passport = require('passport');
var mongoose = require('mongoose');
mongoose.connect(config.mongooseURL);

var WeatherServerModels = require('../models/WeatherDataModels');
var WeatherMeasurement = WeatherServerModels.WeatherMeasurement;
var SupportedMeasurements = WeatherServerModels.SupportedMeasurements;

var SensorNode = WeatherServerModels.SensorNode;

var querySelect = "sensorNodeId measurementType value timestamp"

var ensureApiKey = passport.authenticate('headerapikey', {session: false, failureRedirect: '/api/unauthorized'});

router.get('/measurement', ensureApiKey, function(req, res){
	WeatherMeasurement.find(
		{},
        querySelect,
		function(err, query_result){
		if(err){
			console.error(err);
			res.status(500).send(err);
		}
		else{
			res.send(query_result);
		}
	})
});

router.get('/measurement/sensorNode/:sensorNodeID', ensureApiKey, function(req, res){
	WeatherMeasurement.find({
		sensorNodeID: req.params.sensorNodeID
	},
	querySelect,
	function(err, query_result){
		if(err){
			console.error(err);
			res.status(500).send(err);
		}
		else{
			res.send(query_result)
		}
	})
});

router.get('/measurement/measurementType/:measurementType', ensureApiKey, function(req, res){
	if(req.params.measurementType in SupportedMeasurements){
        WeatherMeasurement.find({
            measurementType: req.params.measurementType
        },
		querySelect,
		function(err, query_result){
        	if(err){
        		console.error(err);
				res.status(500).send(err);
			}
			else{
        		res.send(query_result);
			}

		});

    }
    else{
		res.status(400).send({
			error: "Measurement type '" + req.params.measurementType + "' not supported."
		});
	}
});

router.post('/measurement', ensureApiKey, function(req, res, next){

	var measurement = new WeatherMeasurement(req.body);

	measurement.save(function(err){
		if(err){
			console.log(err);
			res.status(400).send(err);
		}
		else{
			res.status(200).send();
		}
	});
});

router.post('/sensorNode', ensureApiKey, function(req, res, next){
	var sensorNode = new SensorNode(req.body);
	sensorNode.save(function(err){
		if(err){
			console.log(err);
			res.status(400).send(err);
		}
		else{
			res.status(200).send();
		}
	});
});

router.get('/unauthorized', function (req, res) {
	res.status(403).send({error: "unauthorized"});
});

module.exports = router;
<commit_msg>disabled api key requirement for sensornode GET<commit_after>var config = require('../config.json');
var express = require('express');

var router = express.Router();
var passport = require('passport');
var mongoose = require('mongoose');
mongoose.connect(config.mongooseURL);

var WeatherServerModels = require('../models/WeatherDataModels');
var WeatherMeasurement = WeatherServerModels.WeatherMeasurement;
var SupportedMeasurements = WeatherServerModels.SupportedMeasurements;

var SensorNode = WeatherServerModels.SensorNode;

var querySelect = "sensorNodeId measurementType value timestamp"

var ensureApiKey = passport.authenticate('headerapikey', {session: false, failureRedirect: '/api/unauthorized'});

router.get('/measurement', function(req, res){
	WeatherMeasurement.find(
		{},
        querySelect,
		function(err, query_result){
		if(err){
			console.error(err);
			res.status(500).send(err);
		}
		else{
			res.send(query_result);
		}
	})
});

router.get('/measurement/sensorNode/:sensorNodeID', function(req, res){
	WeatherMeasurement.find({
		sensorNodeID: req.params.sensorNodeID
	},
	querySelect,
	function(err, query_result){
		if(err){
			console.error(err);
			res.status(500).send(err);
		}
		else{
			res.send(query_result)
		}
	})
});

router.get('/measurement/measurementType/:measurementType', ensureApiKey, function(req, res){
	if(req.params.measurementType in SupportedMeasurements){
        WeatherMeasurement.find({
            measurementType: req.params.measurementType
        },
		querySelect,
		function(err, query_result){
        	if(err){
        		console.error(err);
				res.status(500).send(err);
			}
			else{
        		res.send(query_result);
			}

		});

    }
    else{
		res.status(400).send({
			error: "Measurement type '" + req.params.measurementType + "' not supported."
		});
	}
});

router.post('/measurement', ensureApiKey, function(req, res, next){

	var measurement = new WeatherMeasurement(req.body);

	measurement.save(function(err){
		if(err){
			console.log(err);
			res.status(400).send(err);
		}
		else{
			res.status(200).send();
		}
	});
});

router.post('/sensorNode', ensureApiKey, function(req, res, next){
	var sensorNode = new SensorNode(req.body);
	sensorNode.save(function(err){
		if(err){
			console.log(err);
			res.status(400).send(err);
		}
		else{
			res.status(200).send();
		}
	});
});

router.get('/unauthorized', function (req, res) {
	res.status(403).send({error: "unauthorized"});
});

module.exports = router;
<|endoftext|>


<commit_before>
var should = require("should");
var sinon = require("sinon");
var NR_TEST_UTILS = require("nr-test-utils");
var diagnostics = NR_TEST_UTILS.require("@node-red/runtime/lib/api/diagnostics")

var mockLog = () => ({
    log: sinon.stub(),
    debug: sinon.stub(),
    trace: sinon.stub(),
    warn: sinon.stub(),
    info: sinon.stub(),
    metric: sinon.stub(),
    audit: sinon.stub(),
    _: function() { return "abc"}
})

describe("runtime-api/diagnostics", function() {

    describe("get", function() {
        before(function() {
            diagnostics.init({
                isStarted: () => true,
                nodes: {
                    getNodeList: () => [{module:"node-red", version:"9.9.9"},{module:"node-red-node-inject", version:"8.8.8"}]
                },
                settings: {
                    version: "7.7.7",
                    available: () => true,
                    //apiMaxLength: xxx, deliberately left blank. Should arrive in report as "UNSET"
                    debugMaxLength: 1111,
                    disableEditor: false,
                    flowFile: "flows.json",
                    mqttReconnectTime: 321,
                    serialReconnectTime: 432,
                    adminAuth: {},//should be sanitised to "SET"
                    httpAdminRoot: "/admin/root/",
                    httpAdminCors: {},//should be sanitised to "SET"
                    httpNodeAuth: {},//should be sanitised to "SET"
                    httpNodeRoot: "/node/root/",
                    httpNodeCors: {},//should be sanitised to "SET"
                    httpStatic: "/var/static/",//should be sanitised to "SET"
                    httpStaticRoot: "/static/root/",
                    httpStaticCors: {},//should be sanitised to "SET"
                    uiHost: "something.secret.com",//should be sanitised to "SET"
                    uiPort: 1337,//should be sanitised to "SET"
                    userDir: "/var/super/secret/",//should be sanitised to "SET",
                    contextStorage: {
                        default    : { module: "memory" },
                        file: { module: "localfilesystem" },
                        secured: { module: "secure_store", user: "fred", pass: "super-duper-secret" },
                    },
                    editorTheme: {}
                },
                log: mockLog()
            });
        })
        it("returns basic user settings", function() {
            return diagnostics.get({scope:"fake_scope"}).then(result => {
                should(result).be.type("object");

                //result.xxxxx
                Object.keys(result)
                const reportPropCount = Object.keys(result).length;
                reportPropCount.should.eql(7);//ensure no more than 7 keys are present in the report (avoid leakage of extra info)
                result.should.have.property("report","diagnostics");
                result.should.have.property("scope","fake_scope");
                result.should.have.property("time").type("object");
                result.should.have.property("intl").type("object");
                result.should.have.property("nodejs").type("object");
                result.should.have.property("os").type("object");
                result.should.have.property("runtime").type("object");

                //result.runtime.xxxxx
                const runtimeCount = Object.keys(result.runtime).length;
                runtimeCount.should.eql(4);//ensure no more than 4 keys are present in runtime
                result.runtime.should.have.property('isStarted',true)
                result.runtime.should.have.property('modules').type("object");
                result.runtime.should.have.property('settings').type("object");
                result.runtime.should.have.property('version','7.7.7');

                //result.runtime.modules.xxxxx
                const moduleCount = Object.keys(result.runtime.modules).length;
                moduleCount.should.eql(2);//ensure no more than the 2 modules specified are present
                result.runtime.modules.should.have.property('node-red','9.9.9');
                result.runtime.modules.should.have.property('node-red-node-inject','8.8.8');

                //result.runtime.settings.xxxxx
                const settingsCount = Object.keys(result.runtime.settings).length;
                settingsCount.should.eql(21);//ensure no more than the 21 settings listed below are present in the settings object
                result.runtime.settings.should.have.property('available',true);
                result.runtime.settings.should.have.property('apiMaxLength', "UNSET");//deliberately disabled to ensure UNSET is returned
                result.runtime.settings.should.have.property('debugMaxLength', 1111);
                result.runtime.settings.should.have.property('disableEditor', false);
                result.runtime.settings.should.have.property('editorTheme', {});
                result.runtime.settings.should.have.property('flowFile', "flows.json");
                result.runtime.settings.should.have.property('mqttReconnectTime', 321);
                result.runtime.settings.should.have.property('serialReconnectTime', 432);
                result.runtime.settings.should.have.property("adminAuth", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("httpAdminCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpAdminRoot', "/admin/root/");
                result.runtime.settings.should.have.property("httpNodeAuth", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("httpNodeCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpNodeRoot', "/node/root/");
                result.runtime.settings.should.have.property("httpStatic", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpStaticRoot', "/static/root/");
                result.runtime.settings.should.have.property("httpStaticCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("uiHost", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("uiPort", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("userDir", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('contextStorage').type("object");

                //result.runtime.settings.contextStorage.xxxxx
                const contextCount = Object.keys(result.runtime.settings.contextStorage).length;
                contextCount.should.eql(3);//ensure no more than the 3 settings listed below are present in the contextStorage object
                result.runtime.settings.contextStorage.should.have.property('default', {module:"memory"});
                result.runtime.settings.contextStorage.should.have.property('file', {module:"localfilesystem"});
                result.runtime.settings.contextStorage.should.have.property('secured', {module:"secure_store"}); //only module should be present, other fields are dropped for security

            })
        })

    });

});
<commit_msg>update tests for sys info diagnostics ammendments<commit_after>
var should = require("should");
var sinon = require("sinon");
var NR_TEST_UTILS = require("nr-test-utils");
var diagnostics = NR_TEST_UTILS.require("@node-red/runtime/lib/api/diagnostics")

var mockLog = () => ({
    log: sinon.stub(),
    debug: sinon.stub(),
    trace: sinon.stub(),
    warn: sinon.stub(),
    info: sinon.stub(),
    metric: sinon.stub(),
    audit: sinon.stub(),
    _: function() { return "abc"}
})

describe("runtime-api/diagnostics", function() {

    describe("get", function() {
        before(function() {
            diagnostics.init({
                isStarted: () => true,
                nodes: {
                    getNodeList: () => [{module:"node-red", version:"9.9.9"},{module:"node-red-node-inject", version:"8.8.8"}]
                },
                settings: {
                    version: "7.7.7",
                    available: () => true,
                    //apiMaxLength: xxx, deliberately left blank. Should arrive in report as "UNSET"
                    debugMaxLength: 1111,
                    disableEditor: false,
                    flowFile: "flows.json",
                    mqttReconnectTime: 321,
                    serialReconnectTime: 432,
                    socketReconnectTime: 2222,
                    socketTimeout: 3333,
                    tcpMsgQueueSize: 4444,
                    inboundWebSocketTimeout: 5555,
                    runtimeState: {enabled: true, ui: false},
                    adminAuth: {},//should be sanitised to "SET"
                    httpAdminRoot: "/admin/root/",
                    httpAdminCors: {},//should be sanitised to "SET"
                    httpNodeAuth: {},//should be sanitised to "SET"
                    httpNodeRoot: "/node/root/",
                    httpNodeCors: {},//should be sanitised to "SET"
                    httpStatic: "/var/static/",//should be sanitised to "SET"
                    httpStaticRoot: "/static/root/",
                    httpStaticCors: {},//should be sanitised to "SET"
                    uiHost: "something.secret.com",//should be sanitised to "SET"
                    uiPort: 1337,//should be sanitised to "SET"
                    userDir: "/var/super/secret/",//should be sanitised to "SET",
                    nodesDir: "/var/super/secret/",//should be sanitised to "SET",
                    contextStorage: {
                        default    : { module: "memory" },
                        file: { module: "localfilesystem" },
                        secured: { module: "secure_store", user: "fred", pass: "super-duper-secret" },
                    },
                    editorTheme: {}
                },
                log: mockLog()
            });
        })
        it("returns basic user settings", function() {
            return diagnostics.get({scope:"fake_scope"}).then(result => {
                should(result).be.type("object");

                //result.xxxxx
                Object.keys(result)
                const reportPropCount = Object.keys(result).length;
                reportPropCount.should.eql(7);//ensure no more than 7 keys are present in the report (avoid leakage of extra info)
                result.should.have.property("report","diagnostics");
                result.should.have.property("scope","fake_scope");
                result.should.have.property("time").type("object");
                result.should.have.property("intl").type("object");
                result.should.have.property("nodejs").type("object");
                result.should.have.property("os").type("object");
                result.should.have.property("runtime").type("object");

                //result.runtime.xxxxx
                const runtimeCount = Object.keys(result.runtime).length;
                runtimeCount.should.eql(5);//ensure 5 keys are present in runtime
                result.runtime.should.have.property('isStarted',true)
                result.runtime.should.have.property('flows')
                result.runtime.should.have.property('modules').type("object");
                result.runtime.should.have.property('settings').type("object");
                result.runtime.should.have.property('version','7.7.7');

                //result.runtime.modules.xxxxx
                const moduleCount = Object.keys(result.runtime.modules).length;
                moduleCount.should.eql(2);//ensure no more than the 2 modules specified are present
                result.runtime.modules.should.have.property('node-red','9.9.9');
                result.runtime.modules.should.have.property('node-red-node-inject','8.8.8');

                //result.runtime.settings.xxxxx
                const settingsCount = Object.keys(result.runtime.settings).length;
                settingsCount.should.eql(27);//ensure no more than the 21 settings listed below are present in the settings object
                result.runtime.settings.should.have.property('available',true);
                result.runtime.settings.should.have.property('apiMaxLength', "UNSET");//deliberately disabled to ensure UNSET is returned
                result.runtime.settings.should.have.property('debugMaxLength', 1111);
                result.runtime.settings.should.have.property('disableEditor', false);
                result.runtime.settings.should.have.property('editorTheme', {});
                result.runtime.settings.should.have.property('flowFile', "flows.json");
                result.runtime.settings.should.have.property('mqttReconnectTime', 321);
                result.runtime.settings.should.have.property('serialReconnectTime', 432);
                result.runtime.settings.should.have.property('socketReconnectTime', 2222);
                result.runtime.settings.should.have.property('socketTimeout', 3333);
                result.runtime.settings.should.have.property('tcpMsgQueueSize', 4444);
                result.runtime.settings.should.have.property('inboundWebSocketTimeout', 5555);
                result.runtime.settings.should.have.property('runtimeState', {enabled: true, ui: false});
                result.runtime.settings.should.have.property("adminAuth", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("httpAdminCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpAdminRoot', "/admin/root/");
                result.runtime.settings.should.have.property("httpNodeAuth", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("httpNodeCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpNodeRoot', "/node/root/");
                result.runtime.settings.should.have.property("httpStatic", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('httpStaticRoot', "/static/root/");
                result.runtime.settings.should.have.property("httpStaticCors", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("uiHost", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("uiPort", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property("userDir", "SET"); //should be sanitised to "SET"
                result.runtime.settings.should.have.property('contextStorage').type("object");
                result.runtime.settings.should.have.property('nodesDir', "SET")

                //result.runtime.settings.contextStorage.xxxxx
                const contextCount = Object.keys(result.runtime.settings.contextStorage).length;
                contextCount.should.eql(3);//ensure no more than the 3 settings listed below are present in the contextStorage object
                result.runtime.settings.contextStorage.should.have.property('default', {module:"memory"});
                result.runtime.settings.contextStorage.should.have.property('file', {module:"localfilesystem"});
                result.runtime.settings.contextStorage.should.have.property('secured', {module:"secure_store"}); //only module should be present, other fields are dropped for security

            })
        })

    });

});
<|endoftext|>


<commit_before>define(['require', 'exports', './commandParser', './events', './pipeSeq', './command'], function(require, exports, commandParser, events, pipeSeq, command) {
	var Command = command.Command;
	var CommandParser = commandParser.CommandParser;
	var EventEmitter = events.EventEmitter;
	var PipeSequence = pipeSeq.PipeSequence;

	var inherits = function(ctor, superCtor) {
	  ctor.super_ = superCtor;
	  ctor.prototype = Object.create(superCtor.prototype, {
		constructor: {
		  value: ctor,
		  enumerable: false,
		  writable: true,
		  configurable: true
		}
	  });
	};

	var merge = function merge(dest, source) {
		for(key in source) {
			dest[key] = source[key];
		}

		return dest;
	};

	var CommandRunner = exports.CommandRunner = (function() {
		function CommandRunner(terminal) {
			this.terminal = terminal;
			this.env = this.terminal.env;
			this.commandParser = new CommandParser(this.env);
			this.fs = this.terminal.fs;

			EventEmitter.call(this);
		}

		inherits(CommandRunner, EventEmitter);

		CommandRunner.prototype.run = function run(cmd, curDir, cb, /* internal */ sendMessage) {
			var cmdFiles, cmds, runContext, curPipeSeq, startSeq, allowRun, /*runCmd, pipes, tmpPipes, nextPipes, pipeList, toPipes,*/ rtnCode, self;

			self = this;
			cmds = this.commandParser.parse(cmd, function(cmdLine, env, execCmd) {
				var output = '';
				self.run(cmdLine, curDir, function(context) {
					context.data.on('data', function(d) {
						output += d;
					});
				}, false);

				return output;
			});
			/*cmdFiles = cmds.map(function(cmd) {
				return merge(cmd, { file: self.terminal.findCMD(cmd.args[0], curDir), args: cmd.args.slice(1), name: cmd.args[0] });
			});*/
			runContext = this.terminal.createRunContext(cmds, ( sendMessage === false ? true : false ));

			for(i = 0; i < cmds.length; i++) {
				curFile = cmds[i];

				if(curFile.joiner == '|') {
					if(!curPipeSeq) {
						curPipeSeq = new PipeSequence();
						curPipeSeq.push(cmds[i - 1]);
						startSeq = i - 1;
					}

					curPipeSeq.push(cmds[i]);
				} else if(curPipeSeq) {
					cmds.splice(startSeq, i - startSeq, curPipeSeq);
					curPipeSeq = undefined;
					startSeq = undefined;
				}

				if(!curPipeSeq) cmds[i] = new Command(curFile, this.terminal, runContext).find();
			}

			if(curPipeSeq) {
				cmds.splice(startSeq, cmds.length, curPipeSeq);
				curPipeSeq = undefined;
				startSeq = undefined;
			}

			//for(i = 0; i < cmdFiles.length; i++) {

			i = -1;

			function commandCallback(exitCode) {
				if(i + 1 < cmds.length) {
					allowRun = true;

					if(cmds[++i].joiner == '&&') allowRun = exitCode == 0;
					else if(cmds[i].joiner == '||') allowRun = exitCode != 0;

					if(allowRun) {
						//self.exec(cmds[i], undefined, undefined, runContext, commandCallback);
						/*(new Command(cmds[i], self.terminal, runContext)).find()*/cmds[i].exec(commandCallback, self.terminal, runContext);
					}
				} else {
					// Done
				}
			}

			commandCallback(0);

			/*	allowRun = true;

				if(cmdFiles[i].joiner == '&&') allowRun = rtnCode == 0;
				else if(cmdFiles[i].joiner == '||') allowRun = rtnCode != 0;

				if(allowRun) {
					rtnCode = this.exec(cmdFiles[i], undefined, undefined, runContext);

					this.env.vars['?'] = rtnCode; // Fixed #1
				}
			//}*/

//			return rtnCode;
		};

		CommandRunner.prototype.exec = function exec(obj, args, context, runContext, cb) {
			if(obj) {
				if(obj.file && this.fs.isExec(obj.file)) return this.execFile(obj.file, obj.args || args, context || runContext.createCMDContext(obj, {
					filePipes: obj.pipes || {}
				}), cb);
				else if(obj instanceof PipeSequence || typeof(obj.run) == 'function') return obj.run(this, runContext, args, context, cb);
			}
		};

		CommandRunner.prototype.execFile = function execFile(file, args, context, cmdCb) {
			var exitCode = 0;

			function cb(exitCode) {
				exitCode = exitCode || 0;
				context.setExitCode(exitCode);
				if(typeof(cmdCb) == 'function') cmdCb(exitCode);
			}

			if(!this.fs.isExec(file)) return new Error("Not executable");

			try {
				if(file.command && typeof(file.command.exec) == 'function') {
					exitCode = file.command.exec(args, context, cb);

					// New code
					var source = new Function().toString.call(file.command.exec);

					var called = false;

					var argMatch, callMatch;

					if(argMatch = /^\s*function\s*(?:[\w\$_][\w\d]*)?\s*\([\w\$\_][\w\d]*\,\s*[\w\$\_][\w\d]*\,\s*([\w\$\_][\w\d]*)\)\s*{/.exec(source)) {
						// Basic search for it being called
						called = !!(callMatch = new RegExp(RegExp.escape(argMatch[1]) + '\\s*\\(').exec(source));
					}

					if(!called) {
						// Call the callback if the command does not call it
						cb(exitCode);
					}
					// End new code
				} else if(file.contents && file.contents.length && file.contents.length > 0) {
					console.log('shell:', this.fs.pathTo(file), this.run(file.contents));
					cb(exitCode = 0);
				}
			} catch(e) {
				console.error('shell:', this.fs.pathTo(file), e, e.message, e.stack);
				cb(exitCode = 1);
			}

			context.setExitCode(exitCode || 0);

			return exitCode || 0;
		};

		return CommandRunner;
	})();
});
<commit_msg>Fix bug with adding to i by making it local<commit_after>define(['require', 'exports', './commandParser', './events', './pipeSeq', './command'], function(require, exports, commandParser, events, pipeSeq, command) {
	var Command = command.Command;
	var CommandParser = commandParser.CommandParser;
	var EventEmitter = events.EventEmitter;
	var PipeSequence = pipeSeq.PipeSequence;

	var inherits = function(ctor, superCtor) {
	  ctor.super_ = superCtor;
	  ctor.prototype = Object.create(superCtor.prototype, {
		constructor: {
		  value: ctor,
		  enumerable: false,
		  writable: true,
		  configurable: true
		}
	  });
	};

	var merge = function merge(dest, source) {
		for(key in source) {
			dest[key] = source[key];
		}

		return dest;
	};

	var CommandRunner = exports.CommandRunner = (function() {
		function CommandRunner(terminal) {
			this.terminal = terminal;
			this.env = this.terminal.env;
			this.commandParser = new CommandParser(this.env);
			this.fs = this.terminal.fs;

			EventEmitter.call(this);
		}

		inherits(CommandRunner, EventEmitter);

		CommandRunner.prototype.run = function run(cmd, curDir, cb, /* internal */ sendMessage) {
			var cmdFiles, cmds, runContext, curPipeSeq, startSeq, allowRun, /*runCmd, pipes, tmpPipes, nextPipes, pipeList, toPipes,*/ rtnCode, self, i;

			self = this;
			cmds = this.commandParser.parse(cmd, function(cmdLine, env, execCmd) {
				var output = '';
				self.run(cmdLine, curDir, function(context) {
					context.data.on('data', function(d) {
						output += d;
					});
				}, false);

				return output;
			});
			/*cmdFiles = cmds.map(function(cmd) {
				return merge(cmd, { file: self.terminal.findCMD(cmd.args[0], curDir), args: cmd.args.slice(1), name: cmd.args[0] });
			});*/
			runContext = this.terminal.createRunContext(cmds, ( sendMessage === false ? true : false ));

			for(i = 0; i < cmds.length; i++) {
				curFile = cmds[i];

				if(curFile.joiner == '|') {
					if(!curPipeSeq) {
						curPipeSeq = new PipeSequence();
						curPipeSeq.push(cmds[i - 1]);
						startSeq = i - 1;
					}

					curPipeSeq.push(cmds[i]);
				} else if(curPipeSeq) {
					cmds.splice(startSeq, i - startSeq, curPipeSeq);
					curPipeSeq = undefined;
					startSeq = undefined;
				}

				if(!curPipeSeq) {
					cmds[i] = new Command(curFile, this.terminal, runContext).find();
				}
			}

			if(curPipeSeq) {
				cmds.splice(startSeq, cmds.length, curPipeSeq);
				curPipeSeq = undefined;
				startSeq = undefined;
			}

			//for(i = 0; i < cmdFiles.length; i++) {

			i = -1;

			function commandCallback(exitCode) {
				if(i + 1 < cmds.length) {
					allowRun = true;

					if(cmds[++i].joiner == '&&') allowRun = exitCode == 0;
					else if(cmds[i].joiner == '||') allowRun = exitCode != 0;

					if(allowRun) {
						//self.exec(cmds[i], undefined, undefined, runContext, commandCallback);
						/*(new Command(cmds[i], self.terminal, runContext)).find()*/cmds[i].exec(commandCallback, self.terminal, runContext);
					}
				} else {
					// Done
				}
			}

			commandCallback(0);

			/*	allowRun = true;

				if(cmdFiles[i].joiner == '&&') allowRun = rtnCode == 0;
				else if(cmdFiles[i].joiner == '||') allowRun = rtnCode != 0;

				if(allowRun) {
					rtnCode = this.exec(cmdFiles[i], undefined, undefined, runContext);

					this.env.vars['?'] = rtnCode; // Fixed #1
				}
			//}*/

//			return rtnCode;
		};

		CommandRunner.prototype.exec = function exec(obj, args, context, runContext, cb) {
			if(obj) {
				if(obj.file && this.fs.isExec(obj.file)) return this.execFile(obj.file, obj.args || args, context || runContext.createCMDContext(obj, {
					filePipes: obj.pipes || {}
				}), cb);
				else if(obj instanceof PipeSequence || typeof(obj.run) == 'function') return obj.run(this, runContext, args, context, cb);
			}
		};

		CommandRunner.prototype.execFile = function execFile(file, args, context, cmdCb) {
			var exitCode = 0;

			function cb(exitCode) {
				exitCode = exitCode || 0;
				context.setExitCode(exitCode);
				if(typeof(cmdCb) == 'function') cmdCb(exitCode);
			}

			if(!this.fs.isExec(file)) return new Error("Not executable");

			try {
				if(file.command && typeof(file.command.exec) == 'function') {
					exitCode = file.command.exec(args, context, cb);

					// New code
					var source = new Function().toString.call(file.command.exec);

					var called = false;

					var argMatch, callMatch;

					if(argMatch = /^\s*function\s*(?:[\w\$_][\w\d]*)?\s*\([\w\$\_][\w\d]*\,\s*[\w\$\_][\w\d]*\,\s*([\w\$\_][\w\d]*)\)\s*{/.exec(source)) {
						// Basic search for it being called
						called = !!(callMatch = new RegExp(RegExp.escape(argMatch[1]) + '\\s*\\(').exec(source));
					}

					if(!called) {
						// Call the callback if the command does not call it
						cb(exitCode);
					}
					// End new code
				} else if(file.contents && file.contents.length && file.contents.length > 0) {
					console.log('shell:', this.fs.pathTo(file), this.run(file.contents));
					cb(exitCode = 0);
				}
			} catch(e) {
				console.error('shell:', this.fs.pathTo(file), e, e.message, e.stack);
				cb(exitCode = 1);
			}

			context.setExitCode(exitCode || 0);

			return exitCode || 0;
		};

		return CommandRunner;
	})();
});
<|endoftext|>


<commit_before><commit_msg>basic router config<commit_after>/**
 * Copyright (c) 2016-present, Alejandro Mantilla <@AlejoJamC>.
 * All rights reserved.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree or translated in the assets folder.
 */

/**
 * SetupRouter
 *
 * @description  Configure all routes on express router
 *
 * @param {express}      app      The application server
 */

function SetupRouter(app) {
    // Initialize all routes
    var indexRoutes = require('./login');

    app.use('/', indexRoutes);

}

// Export setup function
module.exports.SetupRouter = SetupRouter;<|endoftext|>


<commit_before>/**
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * 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.
 */
'use strict';

(function() {

var thisScript = document.querySelector("script[src$='bootstrap.js']");

function loadScript(src) {
  document.write('');
}

function loadCSS(src) {
  document.write('<link rel="stylesheet" type="text/css" href="' + src + '">');
}

loadScript('../testharness/testharness.js');
loadCSS('../testharness/testharness.css');

loadScript('../testharness_extensions.js');

loadScript('../testharness_timing.js');
loadCSS('../testharness_timing.css');

loadScript(location.pathname.replace('.html', '-checks.js'));

document.write('

');
loadScript('../testharness/testharnessreport.js');

if (thisScript && thisScript.getAttribute('nopolyfill') === null) {
  loadScript('../../web-animations.js');
}

window.__coverage__ = parent.window.__coverage__;

})();
<commit_msg>Reimplement nochecks flag to toggle loading of '-checks.js' files<commit_after>/**
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * 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.
 */
'use strict';

(function() {

var thisScript = document.querySelector("script[src$='bootstrap.js']");

function loadScript(src) {
  document.write('');
}

function loadCSS(src) {
  document.write('<link rel="stylesheet" type="text/css" href="' + src + '">');
}

function hasFlag(flag) {
  return thisScript && thisScript.getAttribute(flag) !== null;
}

function isUnitTest() {
  return /unit-test[^\\\/]*\.html$/.exec(location.pathname);
}

loadScript('../testharness/testharness.js');
loadCSS('../testharness/testharness.css');

loadScript('../testharness_extensions.js');

loadScript('../testharness_timing.js');
loadCSS('../testharness_timing.css');

if (!isUnitTest() && !hasFlag('nochecks')) {
  loadScript(location.pathname.replace('.html', '-checks.js'));
}

document.write('

');
loadScript('../testharness/testharnessreport.js');

if (!hasFlag('nopolyfill')) {
  loadScript('../../web-animations.js');
}

window.__coverage__ = parent.window.__coverage__;

})();
<|endoftext|>


<commit_before>/* @flow */

/**
 * Cross-platform code generation for component v-model
 */
export function genComponentModel (
  el: ASTElement,
  value: string,
  modifiers: ?ASTModifiers
): ?boolean {
  const { number, trim } = modifiers || {}

  const baseValueExpression = '$$v'
  let valueExpression = baseValueExpression
  if (trim) {
    valueExpression =
      `(typeof ${baseValueExpression} === 'string'` +
        `? ${baseValueExpression}.trim()` +
        `: ${baseValueExpression})`
  }
  if (number) {
    valueExpression = `_n(${valueExpression})`
  }
  const assignment = genAssignmentCode(value, valueExpression)

  el.model = {
    value: `(${value})`,
    expression: `"${value}"`,
    callback: `function (${baseValueExpression}) {${assignment}}`
  }
}

/**
 * Cross-platform codegen helper for generating v-model value assignment code.
 */
export function genAssignmentCode (
  value: string,
  assignment: string
): string {
  const modelRs = parseModel(value)
  if (modelRs.idx === null) {
    return `${value}=${assignment}`
  } else {
    return `var $$exp = ${modelRs.exp}, $$idx = ${modelRs.idx};` +
      `if (!Array.isArray($$exp)){` +
        `${value}=${assignment}}` +
      `else{$$exp.splice($$idx, 1, ${assignment})}`
  }
}

/**
 * parse directive model to do the array update transform. a[idx] = val => $$a.splice($$idx, 1, val)
 *
 * for loop possible cases:
 *
 * - test
 * - test[idx]
 * - test[test1[idx]]
 * - test["a"][idx]
 * - xxx.test[a[a].test1[idx]]
 * - test.xxx.a["asa"][test1[idx]]
 *
 */

let len, str, chr, index, expressionPos, expressionEndPos

export function parseModel (val: string): Object {
  str = val
  len = str.length
  index = expressionPos = expressionEndPos = 0

  if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
    return {
      exp: val,
      idx: null
    }
  }

  while (!eof()) {
    chr = next()
    /* istanbul ignore if */
    if (isStringStart(chr)) {
      parseString(chr)
    } else if (chr === 0x5B) {
      parseBracket(chr)
    }
  }

  return {
    exp: val.substring(0, expressionPos),
    idx: val.substring(expressionPos + 1, expressionEndPos)
  }
}

function next (): number {
  return str.charCodeAt(++index)
}

function eof (): boolean {
  return index >= len
}

function isStringStart (chr: number): boolean {
  return chr === 0x22 || chr === 0x27
}

function parseBracket (chr: number): void {
  let inBracket = 1
  expressionPos = index
  while (!eof()) {
    chr = next()
    if (isStringStart(chr)) {
      parseString(chr)
      continue
    }
    if (chr === 0x5B) inBracket++
    if (chr === 0x5D) inBracket--
    if (inBracket === 0) {
      expressionEndPos = index
      break
    }
  }
}

function parseString (chr: number): void {
  const stringQuote = chr
  while (!eof()) {
    chr = next()
    if (chr === stringQuote) {
      break
    }
  }
}
<commit_msg>simplify v-model assignment gen + support adding reactive field when using dynamic segments<commit_after>/* @flow */

/**
 * Cross-platform code generation for component v-model
 */
export function genComponentModel (
  el: ASTElement,
  value: string,
  modifiers: ?ASTModifiers
): ?boolean {
  const { number, trim } = modifiers || {}

  const baseValueExpression = '$$v'
  let valueExpression = baseValueExpression
  if (trim) {
    valueExpression =
      `(typeof ${baseValueExpression} === 'string'` +
        `? ${baseValueExpression}.trim()` +
        `: ${baseValueExpression})`
  }
  if (number) {
    valueExpression = `_n(${valueExpression})`
  }
  const assignment = genAssignmentCode(value, valueExpression)

  el.model = {
    value: `(${value})`,
    expression: `"${value}"`,
    callback: `function (${baseValueExpression}) {${assignment}}`
  }
}

/**
 * Cross-platform codegen helper for generating v-model value assignment code.
 */
export function genAssignmentCode (
  value: string,
  assignment: string
): string {
  const modelRs = parseModel(value)
  if (modelRs.idx === null) {
    return `${value}=${assignment}`
  } else {
    return `$set(${modelRs.exp}, ${modelRs.idx}, ${assignment})`
  }
}

/**
 * parse directive model to do the array update transform. a[idx] = val => $$a.splice($$idx, 1, val)
 *
 * for loop possible cases:
 *
 * - test
 * - test[idx]
 * - test[test1[idx]]
 * - test["a"][idx]
 * - xxx.test[a[a].test1[idx]]
 * - test.xxx.a["asa"][test1[idx]]
 *
 */

let len, str, chr, index, expressionPos, expressionEndPos

export function parseModel (val: string): Object {
  str = val
  len = str.length
  index = expressionPos = expressionEndPos = 0

  if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
    return {
      exp: val,
      idx: null
    }
  }

  while (!eof()) {
    chr = next()
    /* istanbul ignore if */
    if (isStringStart(chr)) {
      parseString(chr)
    } else if (chr === 0x5B) {
      parseBracket(chr)
    }
  }

  return {
    exp: val.substring(0, expressionPos),
    idx: val.substring(expressionPos + 1, expressionEndPos)
  }
}

function next (): number {
  return str.charCodeAt(++index)
}

function eof (): boolean {
  return index >= len
}

function isStringStart (chr: number): boolean {
  return chr === 0x22 || chr === 0x27
}

function parseBracket (chr: number): void {
  let inBracket = 1
  expressionPos = index
  while (!eof()) {
    chr = next()
    if (isStringStart(chr)) {
      parseString(chr)
      continue
    }
    if (chr === 0x5B) inBracket++
    if (chr === 0x5D) inBracket--
    if (inBracket === 0) {
      expressionEndPos = index
      break
    }
  }
}

function parseString (chr: number): void {
  const stringQuote = chr
  while (!eof()) {
    chr = next()
    if (chr === stringQuote) {
      break
    }
  }
}
<|endoftext|>


<commit_before>var colors = require('colors');
var readline = require('readline');
var OAuth2Client = require('googleapis').auth.OAuth2;

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

var defaults = require('../defaults');

var GOOGLE_AUTH_SCOPE = [
  'https://www.googleapis.com/auth/drive',
  'https://www.googleapis.com/auth/drive.scripts'
];

module.exports = function auth(clientSecretPath, withWebserver) {
  return fs.lstatAsync(defaults.STORAGE_FILE)
    .then(function() {
      console.log(defaults.STORAGE_FILE + ' already exists. Remove it to re-authenticate node-google-apps-script');
      return Promise.resolve();
    })
    .catch(function(err) {
      if (!clientSecretPath) {
        throw defaults.STORAGE_FILE + ' does not exist yet. Specify a credential file with `--auth ~/Downloads/client_secret_abcd.json`';
      }
      return performAuthenticationFlow(clientSecretPath, withWebserver);
    });
};

function performAuthenticationFlow(clientSecretPath, withWebserver) {
  return getCredentialsFromFile(clientSecretPath)
      .then(function(credentials) {
        return authenticateWithGoogle(credentials, withWebserver);
      })
      .then(saveAuthenticationConfig)
      .then(cleanUp)
      .then(function() {
        console.log('Successfully Authenticated with Google Drive!'.green);
      })
      .catch(function(err) {
        console.log('Error running auth command'.underline.red);
        throw err;
      });
}

function getCredentialsFromFile(clientSecretPath) {
  return fs.readFileAsync(clientSecretPath)
    .then(JSON.parse)
    .then(function(credentials) {
      if (!credentials.installed) {
        throw 'Path did not include "OAuth 2.0 client ID" credentials. Please check that you downloaded the right JSON credentials.';
      }

      // Add important auth information to persist
      // return credentials
      return {
        client_id: credentials.installed.client_id,
        client_secret: credentials.installed.client_secret,
        redirect_uri: credentials.installed.redirect_uris[0]
      };
    })
    .catch(SyntaxError, function(err) {
      console.log('Invalid file contents'.red);
    })
    .error(function(err) {
      console.log('Unable to read file'.red);
      throw err;
    });
}

function authenticateWithGoogle(credentials, withWebserver) {
  return new Promise(function(resolve, reject) {

    var redirect_uri = credentials.redirect_uri;
    if (withWebserver) {
      redirect_uri = 'http://localhost:' + defaults.WEBSERVER_PORT;
    }

    var oauth2Client = new OAuth2Client(credentials.client_id, credentials.client_secret, redirect_uri);
    var url = oauth2Client.generateAuthUrl({
      access_type: 'offline', // Required to receive a refresh token
      approval_prompt: 'force',
      scope: GOOGLE_AUTH_SCOPE
    });

    var getToken = function(code) {
      oauth2Client.getToken(code, function(err, tokens) {
        if (err) { reject(err); }
        credentials.refresh_token = tokens.refresh_token;
        resolve(credentials);
      });
    };

    console.log('\nPlease visit the following url in your browser (you\'ll only have to do this once):'.cyan, url.green);

    if (withWebserver) {

      require('../miniOAuthServer')(defaults.WEBSERVER_PORT)
        .then(getToken)
        .catch(function(err) {
          console.log('Something went wrong with the webserver'.red);
          throw err;
        });

    } else {

      var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
      });

      rl.question('Copy the provided code and paste it here: ', function(code) {
        rl.close();

        getToken(code);

      });
    }
  });
}

function saveAuthenticationConfig(credentials) {
  return fs.writeFileAsync(defaults.STORAGE_FILE, JSON.stringify(credentials, "", 2));
}

function cleanUp() {
  process.stdin.destroy();
}
<commit_msg>Issue 57: return after resolving get token failure<commit_after>var colors = require('colors');
var readline = require('readline');
var OAuth2Client = require('googleapis').auth.OAuth2;

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

var defaults = require('../defaults');

var GOOGLE_AUTH_SCOPE = [
  'https://www.googleapis.com/auth/drive',
  'https://www.googleapis.com/auth/drive.scripts'
];

module.exports = function auth(clientSecretPath, withWebserver) {
  return fs.lstatAsync(defaults.STORAGE_FILE)
    .then(function() {
      console.log(defaults.STORAGE_FILE + ' already exists. Remove it to re-authenticate node-google-apps-script');
      return Promise.resolve();
    })
    .catch(function(err) {
      if (!clientSecretPath) {
        throw defaults.STORAGE_FILE + ' does not exist yet. Specify a credential file with `--auth ~/Downloads/client_secret_abcd.json`';
      }
      return performAuthenticationFlow(clientSecretPath, withWebserver);
    });
};

function performAuthenticationFlow(clientSecretPath, withWebserver) {
  return getCredentialsFromFile(clientSecretPath)
      .then(function(credentials) {
        return authenticateWithGoogle(credentials, withWebserver);
      })
      .then(saveAuthenticationConfig)
      .then(cleanUp)
      .then(function() {
        console.log('Successfully Authenticated with Google Drive!'.green);
      })
      .catch(function(err) {
        console.log('Error running auth command'.underline.red);
        throw err;
      });
}

function getCredentialsFromFile(clientSecretPath) {
  return fs.readFileAsync(clientSecretPath)
    .then(JSON.parse)
    .then(function(credentials) {
      if (!credentials.installed) {
        throw 'Path did not include "OAuth 2.0 client ID" credentials. Please check that you downloaded the right JSON credentials.';
      }

      // Add important auth information to persist
      // return credentials
      return {
        client_id: credentials.installed.client_id,
        client_secret: credentials.installed.client_secret,
        redirect_uri: credentials.installed.redirect_uris[0]
      };
    })
    .catch(SyntaxError, function(err) {
      console.log('Invalid file contents'.red);
    })
    .error(function(err) {
      console.log('Unable to read file'.red);
      throw err;
    });
}

function authenticateWithGoogle(credentials, withWebserver) {
  return new Promise(function(resolve, reject) {

    var redirect_uri = credentials.redirect_uri;
    if (withWebserver) {
      redirect_uri = 'http://localhost:' + defaults.WEBSERVER_PORT;
    }

    var oauth2Client = new OAuth2Client(credentials.client_id, credentials.client_secret, redirect_uri);
    var url = oauth2Client.generateAuthUrl({
      access_type: 'offline', // Required to receive a refresh token
      approval_prompt: 'force',
      scope: GOOGLE_AUTH_SCOPE
    });

    var getToken = function(code) {
      oauth2Client.getToken(code, function(err, tokens) {
        if (err) { reject(err); return; }
        credentials.refresh_token = tokens.refresh_token;
        resolve(credentials);
      });
    };

    console.log('\nPlease visit the following url in your browser (you\'ll only have to do this once):'.cyan, url.green);

    if (withWebserver) {

      require('../miniOAuthServer')(defaults.WEBSERVER_PORT)
        .then(getToken)
        .catch(function(err) {
          console.log('Something went wrong with the webserver'.red);
          throw err;
        });

    } else {

      var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
      });

      rl.question('Copy the provided code and paste it here: ', function(code) {
        rl.close();

        getToken(code);

      });
    }
  });
}

function saveAuthenticationConfig(credentials) {
  return fs.writeFileAsync(defaults.STORAGE_FILE, JSON.stringify(credentials, "", 2));
}

function cleanUp() {
  process.stdin.destroy();
}
<|endoftext|>