<commit_before>    /** @const */ var OAUTH_VERSION = '1.0';

    /**
     * OAuth
     *
     * @constructor
     */
    function OAuth(options) {
        if (!(this instanceof OAuth)) {
            return new OAuth(options);
        }

        return this.init(options);
    }

    OAuth.prototype = {
        init: function (options) {
            var oauth = {
                debug: options.debug || false,
                consumerKey: options.consumerKey,
                consumerSecret: options.consumerSecret,
                accessTokenSecret: options.accessTokenSecret || '',
                signatureMethod: options.signatureMethod || 'HMAC-SHA1'
            };

            /**
             * Makes an authenticated http request
             *
             * @param options {object}
             *      method {string} ['GET', 'POST', 'PUT', ...]
             *      url {string} A valid http(s) url
             *      data {object} A key value paired object of data
             *                      example: {'q':'foobar'}
             *                      for GET this will append a query string
             *      headers {object} A key value paired object of additional headers
             *      success {function} callback for a sucessful request
             *      failure {function} callback for a failed request
             */
            this.request = function (options) {
                var method, url, data, headers, success, failure, xhr, i,
                    headerParams, signatureMethod, signatureString, signature,
                    query = [];

                method = options.method || 'GET';
                url = options.url;
                data = options.data || {};
                headers = options.headers || {};
                success = options.success || function (data) {};
                failure = options.failure || function () {};

                if (oauth.debug) {
                    netscape.security.PrivilegeManager
                        .enablePrivilege("UniversalBrowserRead UniversalBrowserWrite");
                }

                /** @todo factory out this */
                xhr = Request(oauth.debug);
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
                        success({text: xhr.responseText, xml: xhr.responseXML});
                    } else if(xhr.readyState == 4 && xhr.status != 200 && xhr.status != 0) {
                        failure({text: xhr.responseText, xml: xhr.responseXML});
                    }
                };

                for(i in data) {
                    query.push(i + '=' + data[i]);
                }

                headerParams = {
                    'oauth_callback': 'oob',
                    'oauth_consumer_key': oauth.consumerKey,
                    'oauth_token': oauth.accessTokenSecret,
                    'oauth_signature_method': oauth.signatureMethod,
                    'oauth_timestamp': getTimestamp(),
                    'oauth_nonce': getNonce(),
                    'oauth_verifier': oauth.verifier || '',
                    'oauth_version': OAUTH_VERSION
                };

                signatureMethod = oauth.signatureMethod;

                signatureString = toSignatureBaseString(method, url, headerParams, query);
                signature = OAuth['signatureMethod'][signatureMethod](oauth.consumerSecret, oauth.accessTokenSecret, signatureString);

                headerParams.oauth_signature = signature;

                query = query.sort().join('&');
                if(method == 'GET') {
                    if (query) {
                        url += '?' + query;
                    }
                    query = null;
                } else {
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                }

                xhr.open(method, url, true);

                xhr.setRequestHeader('Authorization', 'OAuth ' + toHeaderString(headerParams));
                xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                for (i in headers) {
                    xhr.setRequestHeader(i, headers[i]);
                }

                xhr.send(query);
            }

            return this;
        },

        authenticate: function (options) {},
        deauthenticate: function (options) {},

        request: '',

        /**
         * Wrapper for GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        get: function (url, success, failure) {
            this.request({'url': url, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper for POST OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param data {object} A key value paired object of data
         *                      example: {'q':'foobar'}
         *                      for GET this will append a query string
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        post: function (url, data, success, failure) {
            this.request({'method': 'POST', 'url': url, 'data': data, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper to parse a JSON string and pass it to the callback
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getJSON: function (url, success, failure) {
            this.get(url, function (data) {
                success(JSON.parse(data.text));
            } , failure);
        },

        /**
         * Wrapper for JSON pasrsed GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getXML: function (url, success, failure) {
            this.get(url, function (data) {
                success(data.xml);
            } , failure);
        }
    };

    OAuth.signatureMethod = {
        /**
         * Sign the request
         *
         * @param consumer_secret {string} the consumer secret
         * @param token_secret {string}  the token secret
         * @param signature_base {string}  the signature base string
         */
        'HMAC-SHA1': function (consumer_secret, token_secret, signature_base) {
            var passphrase, signature;

            consumer_secret = OAuth.urlEncode(consumer_secret);
            token_secret = OAuth.urlEncode(token_secret || '');

            passphrase = consumer_secret + '&' + token_secret;
            signature = HMAC(SHA1.prototype, passphrase, signature_base);

            return global.btoa(signature);
        }
    };

    /**
     * Get a string of the parameters for the OAuth Authorization header
     *
     * @param params {object} A key value paired object of data
     *                           example: {'q':'foobar'}
     *                           for GET this will append a query string
     */
    function toHeaderString(params) {
        var arr = [], i;

        for (i in params) {
            if (params[i] && params[i] != undefined && params[i] != '') {
                arr.push(i + '="' + OAuth.urlEncode(params[i]+'') + '"');
            }
        }

        return arr.sort().join(', ');
    }

    /**
     * Generate a signature base string for the request
     *
     * @param method {string} ['GET', 'POST', 'PUT', ...]
     * @param url {string} A valid http(s) url
     * @param header_params A key value paired object of additional headers
     * @param query_params {object} A key value paired object of data
     *                               example: {'q':'foobar'}
     *                               for GET this will append a query string
     */
    function toSignatureBaseString(method, url, header_parms, query_params) {
        var arr = [], i;

        for (i in header_parms) {
            if (header_parms[i] && header_parms[i] != undefined && header_parms[i] != '') {
                arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(header_parms[i]+''));
            }
        }

        for (i in query_params) {
            if (query_params[i] && query_params[i] != undefined && query_params[i] != '') {
                if (!oauth_header_params[i]) {
                    arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(query_params[i]+''));
                }
            }
        }

        return [
            method,
            OAuth.urlEncode(url),
            OAuth.urlEncode(arr.sort().join('&'))
        ].join('&');
    }

    /**
     * Generate a timestamp for the request
     */
    function getTimestamp() {
        return parseInt(+new Date / 1000, 10); // use short form of getting a timestamp
    };

    /**
     * Generate a nonce for the request
     *
     * @param key_length {number} Optional nonce length
     */
    function getNonce(key_length) {
        key_length = key_length || 64;

        var key_bytes = key_length / 8, value = '', key_iter = key_bytes / 4,
        key_remainder = key_bytes % 4, i,
        chars = ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
                     '2A', '2B', '2C', '2D', '2E', '2F', '30', '31', '32', '33',
                     '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D',
                     '3E', '3F', '40', '41', '42', '43', '44', '45', '46', '47',
                     '48', '49', '4A', '4B', '4C', '4D', '4E', '4F', '50', '51',
                     '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B',
                     '5C', '5D', '5E', '5F', '60', '61', '62', '63', '64', '65',
                     '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
                     '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
                     '7A', '7B', '7C', '7D', '7E'];

        for (i = 0; i < key_iter; i++) {
            value += chars[rand()] + chars[rand()] + chars[rand()]+ chars[rand()];
        }

        // handle remaing bytes
        for (i = 0; i < key_remainder; i++) {
            value += chars[rand()];
        }

        function rand() {
            return Math.floor(Math.random() * chars.length);
        }

        return value;
    };

    /**
     * Url encode a string
     *
     * @param string {string} string to be url encoded
     */
    OAuth.urlEncode = function (string) {
        if (!string) return '';

        string = string + '';
        var reserved_chars = / |!|\*|"|'|\(|\)|;|:|@|&|=|\+|\$|,|\/|\?|%|#|\[|\]|<|>|{|}|\||\\|`|\^/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    /**
     * Url decode a string
     *
     * @param string {string} string to be url decoded
     */
    OAuth.urlDecode = function (string){
        if (!string) return '';

        return string.replace(/%[a-fA-F0-9]{2}/ig, function (match) {
            return String.fromCharCode(parseInt(match.replace('%', ''), 16));
        });
    };
<commit_msg>Factored out<commit_after>    /** @const */ var OAUTH_VERSION = '1.0';

    /**
     * OAuth
     *
     * @constructor
     */
    function OAuth(options) {
        if (!(this instanceof OAuth)) {
            return new OAuth(options);
        }

        return this.init(options);
    }

    OAuth.prototype = {
        init: function (options) {
            var oauth = {
                debug: options.debug || false,
                consumerKey: options.consumerKey,
                consumerSecret: options.consumerSecret,
                accessTokenSecret: options.accessTokenSecret || '',
                signatureMethod: options.signatureMethod || 'HMAC-SHA1'
            };

            /**
             * Makes an authenticated http request
             *
             * @param options {object}
             *      method {string} ['GET', 'POST', 'PUT', ...]
             *      url {string} A valid http(s) url
             *      data {object} A key value paired object of data
             *                      example: {'q':'foobar'}
             *                      for GET this will append a query string
             *      headers {object} A key value paired object of additional headers
             *      success {function} callback for a sucessful request
             *      failure {function} callback for a failed request
             */
            this.request = function (options) {
                var method, url, data, headers, success, failure, xhr, i,
                    headerParams, signatureMethod, signatureString, signature,
                    query = [];

                method = options.method || 'GET';
                url = options.url;
                data = options.data || {};
                headers = options.headers || {};
                success = options.success || function (data) {};
                failure = options.failure || function () {};

                if (oauth.debug) {
                    netscape.security.PrivilegeManager
                        .enablePrivilege("UniversalBrowserRead UniversalBrowserWrite");
                }

                xhr = Request(oauth.debug);
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
                        success({text: xhr.responseText, xml: xhr.responseXML});
                    } else if(xhr.readyState == 4 && xhr.status != 200 && xhr.status != 0) {
                        failure({text: xhr.responseText, xml: xhr.responseXML});
                    }
                };

                for(i in data) {
                    query.push(i + '=' + data[i]);
                }

                headerParams = {
                    'oauth_callback': 'oob',
                    'oauth_consumer_key': oauth.consumerKey,
                    'oauth_token': oauth.accessTokenSecret,
                    'oauth_signature_method': oauth.signatureMethod,
                    'oauth_timestamp': getTimestamp(),
                    'oauth_nonce': getNonce(),
                    'oauth_verifier': oauth.verifier || '',
                    'oauth_version': OAUTH_VERSION
                };

                signatureMethod = oauth.signatureMethod;

                signatureString = toSignatureBaseString(method, url, headerParams, query);
                signature = OAuth['signatureMethod'][signatureMethod](oauth.consumerSecret, oauth.accessTokenSecret, signatureString);

                headerParams.oauth_signature = signature;

                query = query.sort().join('&');
                if(method == 'GET') {
                    if (query) {
                        url += '?' + query;
                    }
                    query = null;
                } else {
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                }

                xhr.open(method, url, true);

                xhr.setRequestHeader('Authorization', 'OAuth ' + toHeaderString(headerParams));
                xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                for (i in headers) {
                    xhr.setRequestHeader(i, headers[i]);
                }

                xhr.send(query);
            }

            return this;
        },

        authenticate: function (options) {},
        deauthenticate: function (options) {},

        request: '',

        /**
         * Wrapper for GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        get: function (url, success, failure) {
            this.request({'url': url, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper for POST OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param data {object} A key value paired object of data
         *                      example: {'q':'foobar'}
         *                      for GET this will append a query string
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        post: function (url, data, success, failure) {
            this.request({'method': 'POST', 'url': url, 'data': data, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper to parse a JSON string and pass it to the callback
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getJSON: function (url, success, failure) {
            this.get(url, function (data) {
                success(JSON.parse(data.text));
            } , failure);
        },

        /**
         * Wrapper for JSON pasrsed GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getXML: function (url, success, failure) {
            this.get(url, function (data) {
                success(data.xml);
            } , failure);
        }
    };

    OAuth.signatureMethod = {
        /**
         * Sign the request
         *
         * @param consumer_secret {string} the consumer secret
         * @param token_secret {string}  the token secret
         * @param signature_base {string}  the signature base string
         */
        'HMAC-SHA1': function (consumer_secret, token_secret, signature_base) {
            var passphrase, signature;

            consumer_secret = OAuth.urlEncode(consumer_secret);
            token_secret = OAuth.urlEncode(token_secret || '');

            passphrase = consumer_secret + '&' + token_secret;
            signature = HMAC(SHA1.prototype, passphrase, signature_base);

            return global.btoa(signature);
        }
    };

    /**
     * Get a string of the parameters for the OAuth Authorization header
     *
     * @param params {object} A key value paired object of data
     *                           example: {'q':'foobar'}
     *                           for GET this will append a query string
     */
    function toHeaderString(params) {
        var arr = [], i;

        for (i in params) {
            if (params[i] && params[i] != undefined && params[i] != '') {
                arr.push(i + '="' + OAuth.urlEncode(params[i]+'') + '"');
            }
        }

        return arr.sort().join(', ');
    }

    /**
     * Generate a signature base string for the request
     *
     * @param method {string} ['GET', 'POST', 'PUT', ...]
     * @param url {string} A valid http(s) url
     * @param header_params A key value paired object of additional headers
     * @param query_params {object} A key value paired object of data
     *                               example: {'q':'foobar'}
     *                               for GET this will append a query string
     */
    function toSignatureBaseString(method, url, header_parms, query_params) {
        var arr = [], i;

        for (i in header_parms) {
            if (header_parms[i] && header_parms[i] != undefined && header_parms[i] != '') {
                arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(header_parms[i]+''));
            }
        }

        for (i in query_params) {
            if (query_params[i] && query_params[i] != undefined && query_params[i] != '') {
                if (!oauth_header_params[i]) {
                    arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(query_params[i]+''));
                }
            }
        }

        return [
            method,
            OAuth.urlEncode(url),
            OAuth.urlEncode(arr.sort().join('&'))
        ].join('&');
    }

    /**
     * Generate a timestamp for the request
     */
    function getTimestamp() {
        return parseInt(+new Date / 1000, 10); // use short form of getting a timestamp
    };

    /**
     * Generate a nonce for the request
     *
     * @param key_length {number} Optional nonce length
     */
    function getNonce(key_length) {
        key_length = key_length || 64;

        var key_bytes = key_length / 8, value = '', key_iter = key_bytes / 4,
        key_remainder = key_bytes % 4, i,
        chars = ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
                     '2A', '2B', '2C', '2D', '2E', '2F', '30', '31', '32', '33',
                     '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D',
                     '3E', '3F', '40', '41', '42', '43', '44', '45', '46', '47',
                     '48', '49', '4A', '4B', '4C', '4D', '4E', '4F', '50', '51',
                     '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B',
                     '5C', '5D', '5E', '5F', '60', '61', '62', '63', '64', '65',
                     '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
                     '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
                     '7A', '7B', '7C', '7D', '7E'];

        for (i = 0; i < key_iter; i++) {
            value += chars[rand()] + chars[rand()] + chars[rand()]+ chars[rand()];
        }

        // handle remaing bytes
        for (i = 0; i < key_remainder; i++) {
            value += chars[rand()];
        }

        function rand() {
            return Math.floor(Math.random() * chars.length);
        }

        return value;
    };

    /**
     * Url encode a string
     *
     * @param string {string} string to be url encoded
     */
    OAuth.urlEncode = function (string) {
        if (!string) return '';

        string = string + '';
        var reserved_chars = / |!|\*|"|'|\(|\)|;|:|@|&|=|\+|\$|,|\/|\?|%|#|\[|\]|<|>|{|}|\||\\|`|\^/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    /**
     * Url decode a string
     *
     * @param string {string} string to be url decoded
     */
    OAuth.urlDecode = function (string){
        if (!string) return '';

        return string.replace(/%[a-fA-F0-9]{2}/ig, function (match) {
            return String.fromCharCode(parseInt(match.replace('%', ''), 16));
        });
    };
<|endoftext|>


<commit_before>/* eslint-env node */
const Slack = require('node-slack');
const sampleSize = require('lodash.samplesize');

// Look for slack configuration in the environment
const hookURL = process.env.SLACK_HOOK_URL;

// For details on each option run `ember help release`
module.exports = {
  // Notify Slack when a new release is created (channel and username configured in Slack integration)
  afterPush(project, tags) {
    if (hookURL) {
      let slack = new Slack(hookURL);
      let kudos = sampleSize(CELEBRATE, 7).join(' ');

      return slack.send({
        text: `*${project.name()}* ${tags.next} just dropped ${kudos}`
      });
    }
  }
};

const CELEBRATE = [
  ':+1:',
  ':100:',
  ':bangbang:',
  ':bangbang:',
  ':beers:',
  ':bomb:',
  ':boom:',
  ':clap:',
  ':cool:',
  ':dart:',
  ':dollar:',
  ':eyes:',
  ':facepunch:',
  ':fire:',
  ':gift_heart:',
  ':heart_eyes:',
  ':heart:',
  ':mindblown:',
  ':money_with_wings:',
  ':muscle:',
  ':neckbeard:',
  ':ok_hand:',
  ':raised_hands:',
  ':rocket:',
  ':shipit',
  ':star:',
  ':star2:',
  ':stars:',
  ':sunglasses:',
  ':tada:'
];
<commit_msg>Fix :shipit: and add a couple others (#13)<commit_after>/* eslint-env node */
const Slack = require('node-slack');
const sampleSize = require('lodash.samplesize');

// Look for slack configuration in the environment
const hookURL = process.env.SLACK_HOOK_URL;

// For details on each option run `ember help release`
module.exports = {
  // Notify Slack when a new release is created (channel and username configured in Slack integration)
  afterPush(project, tags) {
    if (hookURL) {
      let slack = new Slack(hookURL);
      let kudos = sampleSize(CELEBRATE, 7).join(' ');

      return slack.send({
        text: `*${project.name()}* ${tags.next} just dropped ${kudos}`
      });
    }
  }
};

const CELEBRATE = [
  ':+1:',
  ':100:',
  ':bangbang:',
  ':bangbang:',
  ':beers:',
  ':bomb:',
  ':boom:',
  ':checkered_flag:',
  ':clap:',
  ':cocktail:',
  ':cool:',
  ':dart:',
  ':dollar:',
  ':eyes:',
  ':facepunch:',
  ':fire:',
  ':gift_heart:',
  ':heart_eyes:',
  ':heart:',
  ':mindblown:',
  ':money_with_wings:',
  ':muscle:',
  ':neckbeard:',
  ':new:',
  ':ok_hand:',
  ':raised_hands:',
  ':ribbon:',
  ':rocket:',
  ':shipit:',
  ':smiley_cat:',
  ':star:',
  ':star2:',
  ':stars:',
  ':sunglasses:',
  ':tada:'
];
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {

  grunt.registerTask('release', 'Build & Bump', function releaseTask(target) {
    grunt.task.run('bump-only:' + target);
    grunt.task.run('docs');
    grunt.task.run('gh-pages');
    grunt.task.run('bump-commit');
  });
};
<commit_msg>fixing release task which should be building<commit_after>'use strict';

module.exports = function(grunt) {

  grunt.registerTask('release', 'Build & Bump', function releaseTask(target) {
    grunt.task.run('bump-only:' + target);
    grunt.task.run('build');
    grunt.task.run('docs');
    grunt.task.run('gh-pages');
    grunt.task.run('bump-commit');
  });
};
<|endoftext|>


<commit_before>    /** @const */ var OAUTH_VERSION_1_0 = '1.0';
    /** @const */ var OAUTH_VERSION_2_0 = '2.0';

    /**
     * OAuth
     *
     * @constructor
     */
    function OAuth(options) {
        if (!(this instanceof OAuth)) {
            return new OAuth(options);
        }

        return this.init(options);
    }

    OAuth.prototype = {
        realm: '',
        requestTokenUrl: '',
        authorizationUrl: '',
        accessTokenUrl: '',

        init: function (options) {
            var empty = '';
            var oauth = {
                enablePrivilege: options.enablePrivilege || false,

                consumerKey: options.consumerKey,
                consumerSecret: options.consumerSecret,
                accessTokenKey: options.accessTokenKey || empty,
                accessTokenSecret: options.accessTokenSecret || empty,
                verifier: '',

                signatureMethod: options.signatureMethod || 'HMAC-SHA1'
            };

            this.realm = options.realm || empty;
            this.requestTokenUrl = options.requestTokenUrl || empty;
            this.authorizationUrl = options.authorizationUrl || empty;
            this.accessTokenUrl = options.accessTokenUrl || empty;

            this.getAccessToken = function () {
                return [oauth.accessTokenKey, oauth.accessTokenSecret];
            };

            this.setAccessToken = function (tokenArray) {
                oauth.accessTokenKey = tokenArray[0];
                oauth.accessTokenSecret = tokenArray[1];
            };

            this.getAccessToken = function () {
                return [oauth.accessTokenKey, oauth.accessTokenSecret];
            };

            this.setAccessToken = function (tokenArray) {
                oauth.accessTokenKey = tokenArray[0];
                oauth.accessTokenSecret = tokenArray[1];
            };

            /**
             * Makes an authenticated http request
             *
             * @param options {object}
             *      method {string} ['GET', 'POST', 'PUT', ...]
             *      url {string} A valid http(s) url
             *      data {object} A key value paired object of data
             *                      example: {'q':'foobar'}
             *                      for GET this will append a query string
             *      headers {object} A key value paired object of additional headers
             *      success {function} callback for a sucessful request
             *      failure {function} callback for a failed request
             */
            this.request = function (options) {
                var method, url, data, headers, success, failure, xhr, i,
                    headerParams, signatureMethod, signatureString, signature,
                    query = [];

                method = options.method || 'GET';
                url = options.url;
                data = options.data || {};
                headers = options.headers || {};
                success = options.success || function (data) {};
                failure = options.failure || function () {};

                if (oauth.enablePrivilege) {
                    netscape.security.PrivilegeManager
                        .enablePrivilege("UniversalBrowserRead UniversalBrowserWrite");
                }

                xhr = Request();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status === 0)) {
                        success({text: xhr.responseText});//, xml: xhr.responseXML});
                    } else if(xhr.readyState == 4 && xhr.status != 200 && xhr.status !== 0) {
                        failure({text: xhr.responseText});//, xml: xhr.responseXML});
                    }
                };

                headerParams = {
                    'oauth_callback': 'oob',
                    'oauth_consumer_key': oauth.consumerKey,
                    'oauth_token': oauth.accessTokenSecret,
                    'oauth_signature_method': oauth.signatureMethod,
                    'oauth_timestamp': getTimestamp(),
                    'oauth_nonce': getNonce(),
                    'oauth_verifier': oauth.verifier,
                    'oauth_version': OAUTH_VERSION_1_0
                };

                signatureMethod = oauth.signatureMethod;

                signatureString = toSignatureBaseString(method, url, headerParams, data);
                signature = OAuth.signatureMethod[signatureMethod](oauth.consumerSecret, oauth.accessTokenSecret, signatureString);

                headerParams.oauth_signature = signature;

                for(i in data) {
                    query.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(data[i] + ''));
                }

                query = query.sort().join('&');
                console.info(query);
                if(method == 'GET') {
                    if (query) {
                        url += '?' + query;
                    }
                    query = null;
                } else {
                    if (!!headers['Content-Type']) {
                        headers['Content-Type'] = 'application/x-www-form-urlencoded';
                    }
                }

                xhr.open(method, url, true);

                xhr.setRequestHeader('Authorization', 'OAuth ' + toHeaderString(headerParams));
                xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                for (i in headers) {
                    xhr.setRequestHeader(i, headers[i]);
                }

                xhr.send(query);
            };

            return this;
        },

        authenticate: function (options, success, failure) {
            var self = this;
            var accessToken = this.getAccessToken();
            if (!(accessToken[0] && accessToken[1])) {
                var args = Array.slice.call(arguments);
                var reqSuccess = function () {
                    self.authenticate.apply(self, args);
                };
                this.getRequestToken({}, reqSuccess);
            } else {

                if (this.oauth_verifier) {
                    success(this);
                } else {
                    var url = this.authorizeToken();
                    window.open(url);
                }
            }
        },

        deauthenticate: function (options, success) {},

        request: '',
        getAccessToken: '',
        setAccessToken: '',

        getRequestToken: function (options, success, failure) {
            this.request({
                method: 'POST',
                url: this.requestTokenUrl,
                success: function (data) {
                    console.log(data);
                },
                failure: function (data) {
                    console.log(data);
                }
            });
        },

        authorizeToken: function () {

        },

        /**
         * Wrapper for GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        get: function (url, success, failure) {
            this.request({'url': url, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper for POST OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param data {object} A key value paired object of data
         *                      example: {'q':'foobar'}
         *                      for GET this will append a query string
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        post: function (url, data, success, failure) {
            this.request({'method': 'POST', 'url': url, 'data': data, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper to parse a JSON string and pass it to the callback
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getJSON: function (url, success, failure) {
            this.get(url, function (data) {
                success(JSON.parse(data.text));
            } , failure);
        }

        /**
         * Wrapper for JSON pasrsed GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        /*getXML: function (url, success, failure) {
            this.get(url, function (data) {
                success(data.xml);
            } , failure);
        }*/
    };

    OAuth.signatureMethod = {
        /**
         * Sign the request
         *
         * @param consumer_secret {string} the consumer secret
         * @param token_secret {string}  the token secret
         * @param signature_base {string}  the signature base string
         */
        'HMAC-SHA1': function (consumer_secret, token_secret, signature_base) {
            var passphrase, signature;

            consumer_secret = OAuth.urlEncode(consumer_secret);
            token_secret = OAuth.urlEncode(token_secret || '');

            passphrase = consumer_secret + '&' + token_secret;
            signature = HMAC(SHA1.prototype, passphrase, signature_base);

            return global.btoa(signature);
        }
    };

    /**
     * Get a string of the parameters for the OAuth Authorization header
     *
     * @param params {object} A key value paired object of data
     *                           example: {'q':'foobar'}
     *                           for GET this will append a query string
     */
    function toHeaderString(params) {
        var arr = [], i;

        for (i in params) {
            if (params[i] && params[i] !== undefined && params[i] !== '') {
                arr.push(i + '="' + OAuth.urlEncode(params[i]+'') + '"');
            }
        }

        return arr.sort().join(', ');
    }

    /**
     * Generate a signature base string for the request
     *
     * @param method {string} ['GET', 'POST', 'PUT', ...]
     * @param url {string} A valid http(s) url
     * @param header_params A key value paired object of additional headers
     * @param query_params {object} A key value paired object of data
     *                               example: {'q':'foobar'}
     *                               for GET this will append a query string
     */
    function toSignatureBaseString(method, url, header_params, query_params) {
        var arr = [], i;

        for (i in header_params) {
            if (header_params[i] !== undefined && header_params[i] !== '') {
                arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(header_params[i]+''));
            }
        }

        for (i in query_params) {
            if (query_params[i] !== undefined && query_params[i] !== '') {
                if (!header_params[i]) {
                    arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(query_params[i] + ''));
                }
            }
        }

        return [
            method,
            OAuth.urlEncode(url),
            OAuth.urlEncode(arr.sort().join('&'))
        ].join('&');
    }

    /**
     * Generate a timestamp for the request
     */
    function getTimestamp() {
        return parseInt(+new Date() / 1000, 10); // use short form of getting a timestamp
    }

    /**
     * Generate a nonce for the request
     *
     * @param key_length {number} Optional nonce length
     */
    function getNonce(key_length) {
        function rand() {
            return Math.floor(Math.random() * chars.length);
        }

        key_length = key_length || 64;

        var key_bytes = key_length / 8, value = '', key_iter = key_bytes / 4,
        key_remainder = key_bytes % 4, i,
        chars = ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
                     '2A', '2B', '2C', '2D', '2E', '2F', '30', '31', '32', '33',
                     '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D',
                     '3E', '3F', '40', '41', '42', '43', '44', '45', '46', '47',
                     '48', '49', '4A', '4B', '4C', '4D', '4E', '4F', '50', '51',
                     '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B',
                     '5C', '5D', '5E', '5F', '60', '61', '62', '63', '64', '65',
                     '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
                     '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
                     '7A', '7B', '7C', '7D', '7E'];

        for (i = 0; i < key_iter; i++) {
            value += chars[rand()] + chars[rand()] + chars[rand()]+ chars[rand()];
        }

        // handle remaing bytes
        for (i = 0; i < key_remainder; i++) {
            value += chars[rand()];
        }

        return value;
    }

    /**
     * Url encode a string
     *
     * @param string {string} string to be url encoded
     */
    OAuth.urlEncode = function (string) {
        if (!string) {
            return '';
        }

        string = string + '';
        var reserved_chars = / |!|\*|"|'|\(|\)|;|:|@|&|=|\+|\$|,|\/|\?|%|#|\[|\]|<|>|\{|\}|\||\\|`|\^/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    /**
     * Url decode a string
     *
     * @param string {string} string to be url decoded
     */
    OAuth.urlDecode = function (string){
        if (!string) {
            return '';
        }

        return string.replace(/%[a-fA-F0-9]{2}/ig, function (match) {
            return String.fromCharCode(parseInt(match.replace('%', ''), 16));
        });
    };
<commit_msg>removed logging<commit_after>    /** @const */ var OAUTH_VERSION_1_0 = '1.0';
    /** @const */ var OAUTH_VERSION_2_0 = '2.0';

    /**
     * OAuth
     *
     * @constructor
     */
    function OAuth(options) {
        if (!(this instanceof OAuth)) {
            return new OAuth(options);
        }

        return this.init(options);
    }

    OAuth.prototype = {
        realm: '',
        requestTokenUrl: '',
        authorizationUrl: '',
        accessTokenUrl: '',

        init: function (options) {
            var empty = '';
            var oauth = {
                enablePrivilege: options.enablePrivilege || false,

                consumerKey: options.consumerKey,
                consumerSecret: options.consumerSecret,
                accessTokenKey: options.accessTokenKey || empty,
                accessTokenSecret: options.accessTokenSecret || empty,
                verifier: '',

                signatureMethod: options.signatureMethod || 'HMAC-SHA1'
            };

            this.realm = options.realm || empty;
            this.requestTokenUrl = options.requestTokenUrl || empty;
            this.authorizationUrl = options.authorizationUrl || empty;
            this.accessTokenUrl = options.accessTokenUrl || empty;

            this.getAccessToken = function () {
                return [oauth.accessTokenKey, oauth.accessTokenSecret];
            };

            this.setAccessToken = function (tokenArray) {
                oauth.accessTokenKey = tokenArray[0];
                oauth.accessTokenSecret = tokenArray[1];
            };

            this.getAccessToken = function () {
                return [oauth.accessTokenKey, oauth.accessTokenSecret];
            };

            this.setAccessToken = function (tokenArray) {
                oauth.accessTokenKey = tokenArray[0];
                oauth.accessTokenSecret = tokenArray[1];
            };

            /**
             * Makes an authenticated http request
             *
             * @param options {object}
             *      method {string} ['GET', 'POST', 'PUT', ...]
             *      url {string} A valid http(s) url
             *      data {object} A key value paired object of data
             *                      example: {'q':'foobar'}
             *                      for GET this will append a query string
             *      headers {object} A key value paired object of additional headers
             *      success {function} callback for a sucessful request
             *      failure {function} callback for a failed request
             */
            this.request = function (options) {
                var method, url, data, headers, success, failure, xhr, i,
                    headerParams, signatureMethod, signatureString, signature,
                    query = [];

                method = options.method || 'GET';
                url = options.url;
                data = options.data || {};
                headers = options.headers || {};
                success = options.success || function (data) {};
                failure = options.failure || function () {};

                if (oauth.enablePrivilege) {
                    netscape.security.PrivilegeManager
                        .enablePrivilege("UniversalBrowserRead UniversalBrowserWrite");
                }

                xhr = Request();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status === 0)) {
                        success({text: xhr.responseText});//, xml: xhr.responseXML});
                    } else if(xhr.readyState == 4 && xhr.status != 200 && xhr.status !== 0) {
                        failure({text: xhr.responseText});//, xml: xhr.responseXML});
                    }
                };

                headerParams = {
                    'oauth_callback': 'oob',
                    'oauth_consumer_key': oauth.consumerKey,
                    'oauth_token': oauth.accessTokenSecret,
                    'oauth_signature_method': oauth.signatureMethod,
                    'oauth_timestamp': getTimestamp(),
                    'oauth_nonce': getNonce(),
                    'oauth_verifier': oauth.verifier,
                    'oauth_version': OAUTH_VERSION_1_0
                };

                signatureMethod = oauth.signatureMethod;

                signatureString = toSignatureBaseString(method, url, headerParams, data);
                signature = OAuth.signatureMethod[signatureMethod](oauth.consumerSecret, oauth.accessTokenSecret, signatureString);

                headerParams.oauth_signature = signature;

                for(i in data) {
                    query.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(data[i] + ''));
                }

                query = query.sort().join('&');

                if(method == 'GET') {
                    if (query) {
                        url += '?' + query;
                    }
                    query = null;
                } else {
                    if (!!headers['Content-Type']) {
                        headers['Content-Type'] = 'application/x-www-form-urlencoded';
                    }
                }

                xhr.open(method, url, true);

                xhr.setRequestHeader('Authorization', 'OAuth ' + toHeaderString(headerParams));
                xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                for (i in headers) {
                    xhr.setRequestHeader(i, headers[i]);
                }

                xhr.send(query);
            };

            return this;
        },

        authenticate: function (options, success, failure) {
            var self = this;
            var accessToken = this.getAccessToken();
            if (!(accessToken[0] && accessToken[1])) {
                var args = Array.slice.call(arguments);
                var reqSuccess = function () {
                    self.authenticate.apply(self, args);
                };
                this.getRequestToken({}, reqSuccess);
            } else {

                if (this.oauth_verifier) {
                    success(this);
                } else {
                    var url = this.authorizeToken();
                    window.open(url);
                }
            }
        },

        deauthenticate: function (options, success) {},

        request: '',
        getAccessToken: '',
        setAccessToken: '',

        getRequestToken: function (options, success, failure) {
            this.request({
                method: 'POST',
                url: this.requestTokenUrl,
                success: function (data) {
                    console.log(data);
                },
                failure: function (data) {
                    console.log(data);
                }
            });
        },

        authorizeToken: function () {

        },

        /**
         * Wrapper for GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        get: function (url, success, failure) {
            this.request({'url': url, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper for POST OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param data {object} A key value paired object of data
         *                      example: {'q':'foobar'}
         *                      for GET this will append a query string
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        post: function (url, data, success, failure) {
            this.request({'method': 'POST', 'url': url, 'data': data, 'success': success, 'failure': failure});
        },

        /**
         * Wrapper to parse a JSON string and pass it to the callback
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        getJSON: function (url, success, failure) {
            this.get(url, function (data) {
                success(JSON.parse(data.text));
            } , failure);
        }

        /**
         * Wrapper for JSON pasrsed GET OAuth.request
         *
         * @param url {string} vaild http(s) url
         * @param success {function} callback for a successful request
         * @param failure {function} callback for a failed request
         */
        /*getXML: function (url, success, failure) {
            this.get(url, function (data) {
                success(data.xml);
            } , failure);
        }*/
    };

    OAuth.signatureMethod = {
        /**
         * Sign the request
         *
         * @param consumer_secret {string} the consumer secret
         * @param token_secret {string}  the token secret
         * @param signature_base {string}  the signature base string
         */
        'HMAC-SHA1': function (consumer_secret, token_secret, signature_base) {
            var passphrase, signature;

            consumer_secret = OAuth.urlEncode(consumer_secret);
            token_secret = OAuth.urlEncode(token_secret || '');

            passphrase = consumer_secret + '&' + token_secret;
            signature = HMAC(SHA1.prototype, passphrase, signature_base);

            return global.btoa(signature);
        }
    };

    /**
     * Get a string of the parameters for the OAuth Authorization header
     *
     * @param params {object} A key value paired object of data
     *                           example: {'q':'foobar'}
     *                           for GET this will append a query string
     */
    function toHeaderString(params) {
        var arr = [], i;

        for (i in params) {
            if (params[i] && params[i] !== undefined && params[i] !== '') {
                arr.push(i + '="' + OAuth.urlEncode(params[i]+'') + '"');
            }
        }

        return arr.sort().join(', ');
    }

    /**
     * Generate a signature base string for the request
     *
     * @param method {string} ['GET', 'POST', 'PUT', ...]
     * @param url {string} A valid http(s) url
     * @param header_params A key value paired object of additional headers
     * @param query_params {object} A key value paired object of data
     *                               example: {'q':'foobar'}
     *                               for GET this will append a query string
     */
    function toSignatureBaseString(method, url, header_params, query_params) {
        var arr = [], i;

        for (i in header_params) {
            if (header_params[i] !== undefined && header_params[i] !== '') {
                arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(header_params[i]+''));
            }
        }

        for (i in query_params) {
            if (query_params[i] !== undefined && query_params[i] !== '') {
                if (!header_params[i]) {
                    arr.push(OAuth.urlEncode(i) + '=' + OAuth.urlEncode(query_params[i] + ''));
                }
            }
        }

        return [
            method,
            OAuth.urlEncode(url),
            OAuth.urlEncode(arr.sort().join('&'))
        ].join('&');
    }

    /**
     * Generate a timestamp for the request
     */
    function getTimestamp() {
        return parseInt(+new Date() / 1000, 10); // use short form of getting a timestamp
    }

    /**
     * Generate a nonce for the request
     *
     * @param key_length {number} Optional nonce length
     */
    function getNonce(key_length) {
        function rand() {
            return Math.floor(Math.random() * chars.length);
        }

        key_length = key_length || 64;

        var key_bytes = key_length / 8, value = '', key_iter = key_bytes / 4,
        key_remainder = key_bytes % 4, i,
        chars = ['20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
                     '2A', '2B', '2C', '2D', '2E', '2F', '30', '31', '32', '33',
                     '34', '35', '36', '37', '38', '39', '3A', '3B', '3C', '3D',
                     '3E', '3F', '40', '41', '42', '43', '44', '45', '46', '47',
                     '48', '49', '4A', '4B', '4C', '4D', '4E', '4F', '50', '51',
                     '52', '53', '54', '55', '56', '57', '58', '59', '5A', '5B',
                     '5C', '5D', '5E', '5F', '60', '61', '62', '63', '64', '65',
                     '66', '67', '68', '69', '6A', '6B', '6C', '6D', '6E', '6F',
                     '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
                     '7A', '7B', '7C', '7D', '7E'];

        for (i = 0; i < key_iter; i++) {
            value += chars[rand()] + chars[rand()] + chars[rand()]+ chars[rand()];
        }

        // handle remaing bytes
        for (i = 0; i < key_remainder; i++) {
            value += chars[rand()];
        }

        return value;
    }

    /**
     * Url encode a string
     *
     * @param string {string} string to be url encoded
     */
    OAuth.urlEncode = function (string) {
        if (!string) {
            return '';
        }

        string = string + '';
        var reserved_chars = / |!|\*|"|'|\(|\)|;|:|@|&|=|\+|\$|,|\/|\?|%|#|\[|\]|<|>|\{|\}|\||\\|`|\^/,
            str_len = string.length, i, string_arr = string.split('');

        for (i = 0; i < str_len; i++) {
            if (string_arr[i].match(reserved_chars)) {
                string_arr[i] = '%' + (string_arr[i].charCodeAt(0)).toString(16).toUpperCase();
            }
        }

        return string_arr.join('');
    };

    /**
     * Url decode a string
     *
     * @param string {string} string to be url decoded
     */
    OAuth.urlDecode = function (string){
        if (!string) {
            return '';
        }

        return string.replace(/%[a-fA-F0-9]{2}/ig, function (match) {
            return String.fromCharCode(parseInt(match.replace('%', ''), 16));
        });
    };
<|endoftext|>


<commit_before>'use strict';

const OPTIONS = [
    'tmpl',
    'title',
    'position',
    'clearList',
    'leaveKeys',
    'dontEscape',
    'dontPrevent'
];

module.exports = (event, state, args, next) => {
    let data = event.data;
    args = args || {};

    if (!state.view) {
        return next(new Error('Flow-view.render: Flow-view not initialized'));
    }

    let options = {};
    OPTIONS.forEach(optionName => {
        options[optionName] = args[optionName] || data[optionName]
    });

    data.data = data.data || {};
    state.view.render(options, data.data, err => {

        if (err) {
            return next('Flow-view.render: ' + err.message);
        }

        next();
    });
};<commit_msg>Don't let event data be undefined.<commit_after>'use strict';

const OPTIONS = [
    'tmpl',
    'title',
    'position',
    'clearList',
    'leaveKeys',
    'dontEscape',
    'dontPrevent'
];

module.exports = (event, state, args, next) => {
    let data = event.data || {};
    args = args || {};

    if (!state.view) {
        return next(new Error('Flow-view.render: Flow-view not initialized'));
    }

    let options = {};
    OPTIONS.forEach(optionName => {
        options[optionName] = args[optionName] || data[optionName]
    });

    data.data = data.data || {};
    state.view.render(options, data.data, err => {

        if (err) {
            return next('Flow-view.render: ' + err.message);
        }

        next();
    });
};<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var util = require('util')
  , OAuth2Strategy = require('passport-oauth').OAuth2Strategy
  , InternalOAuthError = require('passport-oauth').InternalOAuthError;

/**
 * `Strategy` constructor.
 *
 * The Google authentication strategy authenticates requests by delegating to
 * Google using the OAuth 2.0 protocol.
 *
 * Applications must supply a `verify` callback which accepts an `accessToken`,
 * `refreshToken` and service-specific `profile`, and then calls the `done`
 * callback supplying a `user`, which should be set to `false` if the
 * credentials are not valid.  If an exception occured, `err` should be set.
 *
 * Options:
 *   - `clientID`      your Google application's client id
 *   - `clientSecret`  your Google application's client secret
 *   - `callbackURL`   URL to which Google will redirect the user after granting authorization
 *
 * Examples:
 *
 *     passport.use(new GoogleStrategy({
 *         clientID: '123-456-789',
 *         clientSecret: 'shhh-its-a-secret'
 *         callbackURL: 'https://www.example.net/auth/google/callback'
 *       },
 *       function(accessToken, refreshToken, profile, done) {
 *         User.findOrCreate(..., function (err, user) {
 *           done(err, user);
 *         });
 *       }
 *     ));
 *
 * @param {Object} options
 * @param {Function} verify
 * @api public
 */
function Strategy(options, verify) {
  options = options || {};
  options.authorizationURL = options.authorizationURL || 'https://accounts.google.com/o/oauth2/auth';
  options.tokenURL = options.tokenURL || 'https://accounts.google.com/o/oauth2/token';

  OAuth2Strategy.call(this, options, verify);
  this.name = 'google';
}

/**
 * Inherit from `OAuth2Strategy`.
 */
util.inherits(Strategy, OAuth2Strategy);

/**
 * Retrieve user profile from Google.
 *
 * This function constructs a normalized profile, with the following properties:
 *
 *   - `provider`         always set to `google`
 *   - `id`
 *   - `username`
 *   - `displayName`
 *
 * @param {String} accessToken
 * @param {Function} done
 * @api protected
 */
Strategy.prototype.userProfile = function(accessToken, done) {
  this._oauth2.get('https://www.googleapis.com/oauth2/v1/userinfo', accessToken, function (err, body, res) {
    if (err) { return done(new InternalOAuthError('failed to fetch user profile', err)); }

    try {
      var json = JSON.parse(body);

      var profile = { provider: 'google' };
      profile.id = json.id;
      profile.displayName = json.name;
      profile.name = { familyName: json.family_name,
                       givenName: json.given_name };
      profile.emails = [{ value: json.email }];

      profile._raw = body;
      profile._json = json;

      done(null, profile);
    } catch(e) {
      done(e);
    }
  });
}

/**
 * Return extra Google-specific parameters to be included in the authorization
 * request.
 *
 * @param {Object} options
 * @return {Object}
 * @api protected
 */
Strategy.prototype.authorizationParams = function(options) {
  var params = {};
  if (options.accessType) {
    params['access_type'] = options.accessType;
  }
  if (options.approvalPrompt) {
    params['approval_prompt'] = options.approvalPrompt;
  }
  if (options.loginHint) {
    params['login_hint'] = options.loginHint;
  }
  return params;
}

/**
 * Expose `Strategy`.
 */
module.exports = Strategy;
<commit_msg>Add hd and prompt parameters /via @jfromaniello<commit_after>/**
 * Module dependencies.
 */
var util = require('util')
  , OAuth2Strategy = require('passport-oauth').OAuth2Strategy
  , InternalOAuthError = require('passport-oauth').InternalOAuthError;

/**
 * `Strategy` constructor.
 *
 * The Google authentication strategy authenticates requests by delegating to
 * Google using the OAuth 2.0 protocol.
 *
 * Applications must supply a `verify` callback which accepts an `accessToken`,
 * `refreshToken` and service-specific `profile`, and then calls the `done`
 * callback supplying a `user`, which should be set to `false` if the
 * credentials are not valid.  If an exception occured, `err` should be set.
 *
 * Options:
 *   - `clientID`      your Google application's client id
 *   - `clientSecret`  your Google application's client secret
 *   - `callbackURL`   URL to which Google will redirect the user after granting authorization
 *
 * Examples:
 *
 *     passport.use(new GoogleStrategy({
 *         clientID: '123-456-789',
 *         clientSecret: 'shhh-its-a-secret'
 *         callbackURL: 'https://www.example.net/auth/google/callback'
 *       },
 *       function(accessToken, refreshToken, profile, done) {
 *         User.findOrCreate(..., function (err, user) {
 *           done(err, user);
 *         });
 *       }
 *     ));
 *
 * @param {Object} options
 * @param {Function} verify
 * @api public
 */
function Strategy(options, verify) {
  options = options || {};
  options.authorizationURL = options.authorizationURL || 'https://accounts.google.com/o/oauth2/auth';
  options.tokenURL = options.tokenURL || 'https://accounts.google.com/o/oauth2/token';

  OAuth2Strategy.call(this, options, verify);
  this.name = 'google';
}

/**
 * Inherit from `OAuth2Strategy`.
 */
util.inherits(Strategy, OAuth2Strategy);

/**
 * Retrieve user profile from Google.
 *
 * This function constructs a normalized profile, with the following properties:
 *
 *   - `provider`         always set to `google`
 *   - `id`
 *   - `username`
 *   - `displayName`
 *
 * @param {String} accessToken
 * @param {Function} done
 * @api protected
 */
Strategy.prototype.userProfile = function(accessToken, done) {
  this._oauth2.get('https://www.googleapis.com/oauth2/v1/userinfo', accessToken, function (err, body, res) {
    if (err) { return done(new InternalOAuthError('failed to fetch user profile', err)); }

    try {
      var json = JSON.parse(body);

      var profile = { provider: 'google' };
      profile.id = json.id;
      profile.displayName = json.name;
      profile.name = { familyName: json.family_name,
                       givenName: json.given_name };
      profile.emails = [{ value: json.email }];

      profile._raw = body;
      profile._json = json;

      done(null, profile);
    } catch(e) {
      done(e);
    }
  });
}

/**
 * Return extra Google-specific parameters to be included in the authorization
 * request.
 *
 * @param {Object} options
 * @return {Object}
 * @api protected
 */
Strategy.prototype.authorizationParams = function(options) {
  var params = {};
  if (options.accessType) {
    params['access_type'] = options.accessType;
  }
  if (options.approvalPrompt) {
    params['approval_prompt'] = options.approvalPrompt;
  }
  if (options.loginHint) {
    params['login_hint'] = options.loginHint;
  }
  if (options.prompt) {
    params['prompt'] = options.prompt;
  }
  if (options.hd) {
    params['hd'] = options.hd;
  }
  return params;
}

/**
 * Expose `Strategy`.
 */
module.exports = Strategy;
<|endoftext|>


<commit_before>// Redirect between plain HTTP and encrypted HTTPS according to
// `general_ssl_mode` global setting.
//
// http_only: Force HTTP everywhere.
// https_only: Force HTTPS everywhere.
// https_for_registered: Force HTTPS for users, and HTTP for guests.

'use strict';

var COOKIE_MAXAGE_LIKE_FOREVER = 0xFFFFFFFF;
var COOKIE_EXPIRES_IN_THE_PAST = new Date('Thu, 01 Jan 1970 00:00:00 GMT');

module.exports = function (N) {

  // Ensure HTTPS if "ssl" cookie is set *before* session load because
  // session id is stored as secure cookie - it's sent only encrypted.
  N.wire.before('server_chain:*', { priority: -85 }, function force_members_https(env) {
    if ('1' !== env.extras.getCookie('ssl')) {
      // No cookie. Continue.
      return;
    }

    if (env.request.isEncrypted) {
      // Already encrypted. Continue.
      return;
    }

    var redirectUrl = env.helpers.url_to(env.method, env.params, { protocol: 'https' });

    if (!redirectUrl) {
      // Can't build URL - usually RPC-only method.
      return {
        code: N.io.BAD_REQUEST
      , message: 'Encrypted connection is required'
      };
    }

    return {
      code: N.io.REDIRECT
    , head: { Location: redirectUrl }
    };
  });

  // Helper to read "general_ssl_mode" setting used by next hooks.
  // If `pageCheck` is true, page-specific encryption status in included.
  function isEncryptionRequired(env, pageCheck, callback) {
    N.settings.get('general_ssl_mode', {}, function (err, policy) {
      if (err) {
        callback(err);
        return;
      }

      switch (policy) {
      case 'https_off':
        callback(null, false);
        return;

      case 'https_always':
        callback(null, true);
        return;

      case 'https_members':
        if (pageCheck && 'users.auth' === env.method.slice(0, 'users.auth'.length)) {
          // force true even for guests at login/register page
          callback(null, true);
        } else {
          callback(null, Boolean(env.session && env.session.user_id));
        }
        return;

      default:
        // Case for broken settings store.
        callback('Value of setting "general_ssl_mode" is unknown: ' +
                 JSON.stringify(policy));
        return;
      }
    });
  }

  // Main guest/user http/https redirector. Just after session load.
  N.wire.before('server_chain:*', { priority: -75 }, function switch_http_and_https(env, callback) {
    isEncryptionRequired(env, true, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      if (env.request.isEncrypted === shouldBeEncrypted) {
        // Redirection is not needed. Continue.
        callback();
        return;
      }

      var redirectUrl = env.helpers.url_to(env.method, env.params, {
        protocol: shouldBeEncrypted ? 'https' : 'http'
      });

      if (!redirectUrl) {
        // Can't build URL - usually RPC-only method.
        callback({
          code: N.io.BAD_REQUEST
        , message: 'Encrypted connection is required'
        });
        return;
      }

      callback({
        code: N.io.REDIRECT
      , head: { Location: redirectUrl }
      });
    });
  });

  // Set cookie to keep secure connection for logged in users.
  N.wire.after('server_chain:*', { priority: 80, ensure: true }, function set_ssl_redirect_cookie(env, callback) {
    isEncryptionRequired(env, false, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      if (shouldBeEncrypted) {
        if ('1' !== env.extras.getCookie('ssl')) {
          // Add cookie for a HUGE amount of time.
          env.extras.setCookie('ssl', '1', { maxAge: COOKIE_MAXAGE_LIKE_FOREVER });
        }
      } else {
        if ('1' === env.extras.getCookie('ssl')) {
          // Delete cookie by setting 'expires' to a past date.
          env.extras.setCookie('ssl', '0', { expires: COOKIE_EXPIRES_IN_THE_PAST });
        }
      }
      callback();
    });
  });

  // Modify 'secure' flag of session id cookie.
  N.wire.after('server_chain:*', { priority: 85, ensure: true }, function set_sid_cookie_mode(env, callback) {
    isEncryptionRequired(env, false, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      env.extras.updateCookie('sid', { secure: shouldBeEncrypted });
      callback();
    });
  });
};
<commit_msg>Revert "Use `env.extras.updateCookie` helper."<commit_after>// Redirect between plain HTTP and encrypted HTTPS according to
// `general_ssl_mode` global setting.
//
// http_only: Force HTTP everywhere.
// https_only: Force HTTPS everywhere.
// https_for_registered: Force HTTPS for users, and HTTP for guests.

'use strict';

var COOKIE_MAXAGE_LIKE_FOREVER = 0xFFFFFFFF;
var COOKIE_EXPIRES_IN_THE_PAST = new Date('Thu, 01 Jan 1970 00:00:00 GMT');

module.exports = function (N) {

  // Ensure HTTPS if "ssl" cookie is set *before* session load because
  // session id is stored as secure cookie - it's sent only encrypted.
  N.wire.before('server_chain:*', { priority: -85 }, function force_members_https(env) {
    if ('1' !== env.extras.getCookie('ssl')) {
      // No cookie. Continue.
      return;
    }

    if (env.request.isEncrypted) {
      // Already encrypted. Continue.
      return;
    }

    var redirectUrl = env.helpers.url_to(env.method, env.params, { protocol: 'https' });

    if (!redirectUrl) {
      // Can't build URL - usually RPC-only method.
      return {
        code: N.io.BAD_REQUEST
      , message: 'Encrypted connection is required'
      };
    }

    return {
      code: N.io.REDIRECT
    , head: { Location: redirectUrl }
    };
  });

  // Helper to read "general_ssl_mode" setting used by next hooks.
  // If `pageCheck` is true, page-specific encryption status in included.
  function isEncryptionRequired(env, pageCheck, callback) {
    N.settings.get('general_ssl_mode', {}, function (err, policy) {
      if (err) {
        callback(err);
        return;
      }

      switch (policy) {
      case 'https_off':
        callback(null, false);
        return;

      case 'https_always':
        callback(null, true);
        return;

      case 'https_members':
        if (pageCheck && 'users.auth' === env.method.slice(0, 'users.auth'.length)) {
          // force true even for guests at login/register page
          callback(null, true);
        } else {
          callback(null, Boolean(env.session && env.session.user_id));
        }
        return;

      default:
        // Case for broken settings store.
        callback('Value of setting "general_ssl_mode" is unknown: ' +
                 JSON.stringify(policy));
        return;
      }
    });
  }

  // Main guest/user http/https redirector. Just after session load.
  N.wire.before('server_chain:*', { priority: -75 }, function switch_http_and_https(env, callback) {
    isEncryptionRequired(env, true, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      if (env.request.isEncrypted === shouldBeEncrypted) {
        // Redirection is not needed. Continue.
        callback();
        return;
      }

      var redirectUrl = env.helpers.url_to(env.method, env.params, {
        protocol: shouldBeEncrypted ? 'https' : 'http'
      });

      if (!redirectUrl) {
        // Can't build URL - usually RPC-only method.
        callback({
          code: N.io.BAD_REQUEST
        , message: 'Encrypted connection is required'
        });
        return;
      }

      callback({
        code: N.io.REDIRECT
      , head: { Location: redirectUrl }
      });
    });
  });

  // Set cookie to keep secure connection for logged in users.
  N.wire.after('server_chain:*', { priority: 80, ensure: true }, function set_ssl_redirect_cookie(env, callback) {
    isEncryptionRequired(env, false, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      if (shouldBeEncrypted) {
        if ('1' !== env.extras.getCookie('ssl')) {
          // Add cookie for a HUGE amount of time.
          env.extras.setCookie('ssl', '1', { maxAge: COOKIE_MAXAGE_LIKE_FOREVER });
        }
      } else {
        if ('1' === env.extras.getCookie('ssl')) {
          // Delete cookie by setting 'expires' to a past date.
          env.extras.setCookie('ssl', '0', { expires: COOKIE_EXPIRES_IN_THE_PAST });
        }
      }
      callback();
    });
  });

  // Modify 'secure' flag of session id cookie.
  N.wire.after('server_chain:*', { priority: 85, ensure: true }, function set_sid_cookie_mode(env, callback) {
    if (!env.extras.setCookie.storage['sid']) {
      // No session id cookie.
      callback();
      return;
    }

    isEncryptionRequired(env, false, function (err, shouldBeEncrypted) {
      if (err) {
        callback(err);
        return;
      }

      env.extras.setCookie.storage['sid'].options.secure = shouldBeEncrypted;
      callback();
    });
  });
};
<|endoftext|>


<commit_before>// comment api

var
    _ = require('lodash'),
    async = require('async'),
    api = require('../api'),
    db = require('../db'),

    utils = require('./_utils'),
    constants = require('../constants');

var
    Comment = db.comment,
    warp = db.warp,
    next_id = db.next_id;

function formatComment(s) {
    return s.replace(/\r/g, '').replace(/\n+/g, '\n').replace(/\&/g, '&').replace(/</g, '<').replace(/\>/g, '>');
}

function createComment(ref_type, ref_id, user, content, tx, callback) {
    if (arguments.length === 5) {
        callback = tx;
        tx = undefined;
    }
    var fc = formatComment(content);
    if (fc.length > 1000) {
        return callback(api.invalidParam('content', 'Content is too long.'));
    }
    Comment.create({
        ref_type: ref_type,
        ref_id: ref_id,
        user_id: user.id,
        user_name: user.name,
        user_image_url: user.image_url,
        content: fc
    }, tx, function (err, entity) {
        if (err) {
            return callback(err);
        }
        return callback(null, entity);
    });
}

function getCommentsByRef(ref_id, from_id, callback) {
    var query, limit = 100;
    if (arguments.length === 2) {
        callback = from_id;
        from_id = null;
    }
    if (from_id) {
        query = {
            where: 'ref_id=? and id<=?',
            params: [ref_id, from_id]
        };
    } else {
        query = {
            where: 'ref_id=?',
            params: [ref_id]
        };
    }
    query.limit = limit + 1;
    query.order = 'id desc';
    Comment.findAll(query, function (err, comments) {
        if (err) {
            return callback(err);
        }
        var lastId = null;
        if (comments.length > limit) {
            lastId = comments.pop().id;
        }
        callback(null, {
            comments: comments,
            nextCommentId: lastId
        });
    });
}

function getComments(ref_id, page, callback) {
    if (arguments.length === 2) {
        callback = page;
        page = ref_id;
        ref_id = undefined;
    }
    var query = {
        select: 'count(id)'
    };
    if (ref_id) {
        query.where = 'ref_id=?';
        query.params = [ref_id];
    }
    Comment.findNumber(query, function (err, num) {
        if (err) {
            return callback(err);
        }
        page.totalItems = num;
        if (page.isEmpty) {
            return callback(null, {
                page: page,
                comments: []
            });
        }
        var query2 = {
            select: '*',
            offset: page.offset,
            limit: page.limit,
            order: 'created_at desc'
        };
        if (ref_id) {
            query2.where = 'ref_id=?';
            query2.params = [ref_id];
        }
        Comment.findAll(query2, function (err, comments) {
            if (err) {
                return callback(err);
            }
            return callback(null, {
                page: page,
                comments: comments
            });
        });
    });
}

function deleteComment(id, tx, callback) {
    if (arguments.length === 2) {
        callback = tx;
        tx = undefined;
    }
    Comment.find(id, tx, function (err, c) {
        if (err) {
            return callback(err);
        }
        c.destroy(tx, function (err, r) {
            if (err) {
                return callback(err);
            }
            callback(null, { id: c.id });
        });
    });
}

function deleteComments(ref_id, tx, callback) {
    if (arguments.length === 2) {
        callback = tx;
        tx = undefined;
    }
    warp.update('', [ref_id], tx, function (err, r) {
        if (err) {
            return callback(err);
        }
        callback(null, true);
    });
}

module.exports = {

    createComment: createComment,

    deleteComments: deleteComments,

    deleteComment: deleteComment,

    getComments: getComments,

    getCommentsByRef: getCommentsByRef,

    'POST /api/comments/:id/delete': function (req, res, next) {
        /**
         * Delete a comment by its id.
         *
         * @name Delete Comment
         * @param {string} id - The id of the comment.
         * @return {object} Results contains deleted id. e.g. {"id": "12345"}
         */
        if (utils.isForbidden(req, constants.ROLE_EDITOR)) {
            return next(api.notAllowed('Permission denied.'));
        }
        async.waterfall([
            function (callback) {
                Comment.find(req.params.id, callback);
            },
            function (comment, callback) {
                if (comment === null) {
                    return callback(api.notFound('Comment'));
                }
                comment.destroy(callback);
            }
        ], function (err, result) {
            if (err) {
                return next(err);
            }
            return res.send({ id: req.params.id });
        });
    }
};
<commit_msg>remove unused function<commit_after>// comment api

var
    _ = require('lodash'),
    async = require('async'),
    api = require('../api'),
    db = require('../db'),

    utils = require('./_utils'),
    constants = require('../constants');

var
    Comment = db.comment,
    warp = db.warp,
    next_id = db.next_id;

function formatComment(s) {
    return s.replace(/\r/g, '').replace(/\n+/g, '\n').replace(/\&/g, '&').replace(/</g, '<').replace(/\>/g, '>');
}

function createComment(ref_type, ref_id, user, content, tx, callback) {
    if (arguments.length === 5) {
        callback = tx;
        tx = undefined;
    }
    var fc = formatComment(content);
    if (fc.length > 1000) {
        return callback(api.invalidParam('content', 'Content is too long.'));
    }
    Comment.create({
        ref_type: ref_type,
        ref_id: ref_id,
        user_id: user.id,
        user_name: user.name,
        user_image_url: user.image_url,
        content: fc
    }, tx, function (err, entity) {
        if (err) {
            return callback(err);
        }
        return callback(null, entity);
    });
}

function getCommentsByRef(ref_id, from_id, callback) {
    var query, limit = 100;
    if (arguments.length === 2) {
        callback = from_id;
        from_id = null;
    }
    if (from_id) {
        query = {
            where: 'ref_id=? and id<=?',
            params: [ref_id, from_id]
        };
    } else {
        query = {
            where: 'ref_id=?',
            params: [ref_id]
        };
    }
    query.limit = limit + 1;
    query.order = 'id desc';
    Comment.findAll(query, function (err, comments) {
        if (err) {
            return callback(err);
        }
        var lastId = null;
        if (comments.length > limit) {
            lastId = comments.pop().id;
        }
        callback(null, {
            comments: comments,
            nextCommentId: lastId
        });
    });
}

function getComments(ref_id, page, callback) {
    if (arguments.length === 2) {
        callback = page;
        page = ref_id;
        ref_id = undefined;
    }
    var query = {
        select: 'count(id)'
    };
    if (ref_id) {
        query.where = 'ref_id=?';
        query.params = [ref_id];
    }
    Comment.findNumber(query, function (err, num) {
        if (err) {
            return callback(err);
        }
        page.totalItems = num;
        if (page.isEmpty) {
            return callback(null, {
                page: page,
                comments: []
            });
        }
        var query2 = {
            select: '*',
            offset: page.offset,
            limit: page.limit,
            order: 'created_at desc'
        };
        if (ref_id) {
            query2.where = 'ref_id=?';
            query2.params = [ref_id];
        }
        Comment.findAll(query2, function (err, comments) {
            if (err) {
                return callback(err);
            }
            return callback(null, {
                page: page,
                comments: comments
            });
        });
    });
}

function deleteComment(id, tx, callback) {
    if (arguments.length === 2) {
        callback = tx;
        tx = undefined;
    }
    Comment.find(id, tx, function (err, c) {
        if (err) {
            return callback(err);
        }
        c.destroy(tx, function (err, r) {
            if (err) {
                return callback(err);
            }
            callback(null, { id: c.id });
        });
    });
}

module.exports = {

    createComment: createComment,

    deleteComment: deleteComment,

    getComments: getComments,

    getCommentsByRef: getCommentsByRef,

    'POST /api/comments/:id/delete': function (req, res, next) {
        /**
         * Delete a comment by its id.
         *
         * @name Delete Comment
         * @param {string} id - The id of the comment.
         * @return {object} Results contains deleted id. e.g. {"id": "12345"}
         */
        if (utils.isForbidden(req, constants.ROLE_EDITOR)) {
            return next(api.notAllowed('Permission denied.'));
        }
        async.waterfall([
            function (callback) {
                Comment.find(req.params.id, callback);
            },
            function (comment, callback) {
                if (comment === null) {
                    return callback(api.notFound('Comment'));
                }
                comment.destroy(callback);
            }
        ], function (err, result) {
            if (err) {
                return next(err);
            }
            return res.send({ id: req.params.id });
        });
    }
};
<|endoftext|>