<commit_before>'use strict';

let request = require('request');
let _ = require('lodash');
let util = require('util');
let async = require('async');
let log = null;
var arinuri = '';

function startup(logger) {
    log = logger;
}

function doLookup(entities, options, cb) {

    let blacklist = options.blacklist;

    let checkv6 = options.lookupIPv6;

    let lookupResults = [];

    async.each(entities, function (entityObj, next) {
        if (_.includes(blacklist, entityObj.value)) {
            next(null);
        } else if ((entityObj.isIPv4 && !entityObj.isPrivateIP) || (entityObj.isIPv6 && checkv6 == true)
            || entityObj.types.indexOf('custom.IPv4CIDR') >= 0) {
            _lookupEntity(entityObj, options, function (err, result) {
                if (err) {
                    next(err);
                } else {
                    lookupResults.push(result);
                    log.debug({result: result}, "Result Values:");
                    next(null);
                }
            });
        } else {
            next(null);
        }
    }, function (err) {
        cb(err, lookupResults);
    });
}

function _lookupEntity(entityObj, options, cb) {
    log.debug({entity: entityObj.value}, "What is the entity");

    if (entityObj.value) {

        if (entityObj.types.indexOf('custom.IPv4CIDR') >= 0) {
            arinuri = 'cidr';
        } else {
            arinuri = 'ip';
        }

        //Debug check for API endpoint URI  assignment

        log.trace({arinuri: arinuri}, "What is the ARIN API enpoint");

        request({
            uri: 'http://whois.arin.net/rest/' + arinuri + '/' + entityObj.value,
            method: 'GET',
            json: true,
            headers: {
                'Accept': 'application/json'
            }
        }, function (err, response, body) {
            if (err) {
                log.error({err: err}, "Request Error");
                cb(err);
                return;
            }

            if (response.statusCode === 500) {
                cb(_createJsonErrorPayload("ARIN server was unable to process your request", null, '500', '2A', 'Unable to Process Request', {
                    err: err
                }));
                return;
            }

            if (response.statusCode === 404) {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                return;
            }

            if (response.statusCode === 400) {
                cb(_createJsonErrorPayload("Bad Request", null, '400', '2A', 'Bad Request', {
                    err: err
                }));
                return;
            }

            if (response.statusCode !== 200) {
                cb({
                    statusCode: response.statusCode,
                    body: body,
                    entity: entityObj
                });
                return;
            }
            log.trace({netblock: _.isArray(body.net.netBlocks)}, "Checking to see if the value is true or false");
            log.trace({body: body}, "Printing out the results of Body ");

            if (_.isNil(body) || _.isNil(body.net) || _.isNil(body.net.parentNetRef) || _.isNil(body.net.orgRef)) {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                return;
            }

            log.debug({body: body}, "Printing out the results of Body 22");

            // If ARIN returns malformed JSON then the `body` object will be a string.  If it's
            // valid JSON that we are expecting then it will be an object.  See why body will be a
            // string on JSON parse error in this issue: https://github.com/request/request/issues/440
            if (response && typeof body === 'string') {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                log.trace({error: e}, "Result is not JSON"); // ARIN response not JSON
                return;
            }

            log.debug({body: body}, "Printing out the results of Body ");

            if (_.isArray(body.net.netBlocks.netBlock) == true) {
                // The lookup results returned is an array of lookup objects with the following format
                cb(null, {
                    // Required: This is the entity object passed into the integration doLookup method
                    entity: entityObj,
                    // Required: An object containing everything you want passed to the template
                    data: {
                        // Required: this is the string value that is displayed in the template
                        entity_name: entityObj.value,
                        // Required: These are the tags that are displayed in your template
                        summary: [body.net.orgRef['@name']],
                        // Data that you want to pass back to the notification window details block
                        details: {
                            allData: body,
                            //Organization
                            orgHandle: body.net.orgRef['@handle'],
                            orgName: body.net.orgRef['@name'],
                            orgRef: body.net.orgRef['$'],
                            //Network Details
                            netBlockHandle: body.net.handle['$'],
                            netBlockName: body.net.name['$'],
                            netBlockCIDR: body.net.startAddress['$'] + '/' + body.net.netBlocks.netBlock[0].cidrLength['$'],
                            startAddr: body.net.startAddress['$'],
                            endAddr: body.net.endAddress['$'],
                            netBlockRef: body.net.ref['$'],
                            regDate: body.net.registrationDate['$'],
                            upDate: body.net.updateDate['$'],
                            //Parent Network
                            parentHandle: body.net.parentNetRef['@handle'],
                            parentName: body.net.parentNetRef['@name'],
                            parentRef: body.net.parentNetRef['$']
                        }
                    }
                });
            } else {
                cb(null, {
                    // Required: This is the entity object passed into the integration doLookup method
                    entity: entityObj,
                    // Required: An object containing everything you want passed to the template
                    data: {
                        // Required: this is the string value that is displayed in the template
                        entity_name: entityObj.value,
                        // Required: These are the tags that are displayed in your template
                        summary: [body.net.orgRef['@name']],
                        // Data that you want to pass back to the notification window details block
                        details: {
                            allData: body,
                            //Organization
                            orgHandle: body.net.orgRef['@handle'],
                            orgName: body.net.orgRef['@name'],
                            orgRef: body.net.orgRef['$'],
                            //Network Details
                            netBlockHandle: body.net.handle['$'],
                            netBlockName: body.net.name['$'],
                            netBlockCIDR: body.net.startAddress['$'] + '/' + body.net.netBlocks.netBlock.cidrLength['$'],
                            startAddr: body.net.startAddress['$'],
                            endAddr: body.net.endAddress['$'],
                            netBlockRef: body.net.ref['$'],
                            regDate: body.net.registrationDate['$'],
                            upDate: body.net.updateDate['$'],
                            //Parent Network
                            parentHandle: body.net.parentNetRef['@handle'],
                            parentName: body.net.parentNetRef['@name'],
                            parentRef: body.net.parentNetRef['$']
                        }
                    }
                });
            }
        });

    }
}

function validateOptions(userOptions, cb) {
    let errors = [];
    //nothig to validate; leaving function for future expantion of integration.
    cb(null, errors);
}

// function that takes the ErrorObject and passes the error message to the notification window
var _createJsonErrorPayload = function (msg, pointer, httpCode, code, title, meta) {
    return {
        errors: [
            _createJsonErrorObject(msg, pointer, httpCode, code, title, meta)
        ]
    }
};

// function that creates the Json object to be passed to the payload
var _createJsonErrorObject = function (msg, pointer, httpCode, code, title, meta) {
    let error = {
        detail: msg,
        status: httpCode.toString(),
        title: title,
        code: 'ARIN_' + code.toString()
    };

    if (pointer) {
        error.source = {
            pointer: pointer
        };
    }

    if (meta) {
        error.meta = meta;
    }

    return error;
};

module.exports = {
    doLookup: doLookup,
    startup: startup,
    validateOptions: validateOptions
};<commit_msg>Remove large duplicate code block<commit_after>'use strict';

let request = require('request');
let _ = require('lodash');
let async = require('async');
let log = null;
let arinuri = '';

function startup(logger) {
    log = logger;
}

function doLookup(entities, options, cb) {
    let blacklist = options.blacklist;
    let checkv6 = options.lookupIPv6;
    let lookupResults = [];

    async.each(entities, function (entityObj, next) {
        if (_.includes(blacklist, entityObj.value)) {
            next(null);
        } else if ((entityObj.isIPv4 && !entityObj.isPrivateIP) || (entityObj.isIPv6 && checkv6 == true)
            || entityObj.types.indexOf('custom.IPv4CIDR') >= 0) {
            _lookupEntity(entityObj, options, function (err, result) {
                if (err) {
                    next(err);
                } else {
                    lookupResults.push(result);
                    log.debug({result: result}, "Result Values:");
                    next(null);
                }
            });
        } else {
            next(null);
        }
    }, function (err) {
        cb(err, lookupResults);
    });
}

function _lookupEntity(entityObj, options, cb) {
    log.debug({entity: entityObj.value}, "What is the entity");

    if (entityObj.value) {

        if (entityObj.types.indexOf('custom.IPv4CIDR') >= 0) {
            arinuri = 'cidr';
        } else {
            arinuri = 'ip';
        }

        //Debug check for API endpoint URI  assignment
        log.trace({arinuri: arinuri}, "What is the ARIN API endpoint");

        request({
            uri: 'http://whois.arin.net/rest/' + arinuri + '/' + entityObj.value,
            method: 'GET',
            json: true,
            headers: {
                'Accept': 'application/json'
            }
        }, function (err, response, body) {
            if (err) {
                log.error({err: err}, "Request Error");
                cb(err);
                return;
            }

            if (response.statusCode === 500) {
                cb(_createJsonErrorPayload("ARIN server was unable to process your request", null, '500', '2A', 'Unable to Process Request', {
                    err: err
                }));
                return;
            }

            if (response.statusCode === 404) {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                return;
            }

            if (response.statusCode === 400) {
                cb(_createJsonErrorPayload("Bad Request", null, '400', '2A', 'Bad Request', {
                    err: err
                }));
                return;
            }

            if (response.statusCode !== 200) {
                cb({
                    statusCode: response.statusCode,
                    body: body,
                    entity: entityObj
                });
                return;
            }

            log.trace({body: body}, "Printing out the results of Body ");

            if (_.isNil(body) || _.isNil(body.net) || _.isNil(body.net.parentNetRef) || _.isNil(body.net.orgRef)) {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                return;
            }

            log.debug({body: body}, "Printing out the results of Body 22");

            // If ARIN returns malformed JSON then the `body` object will be a string.  If it's
            // valid JSON that we are expecting then it will be an object.  See why body will be a
            // string on JSON parse error in this issue: https://github.com/request/request/issues/440
            if (response && typeof body === 'string') {
                cb(null, {entity: entityObj, data: null}); //Cache the missed results
                log.trace({error: e}, "Result is not JSON"); // ARIN response not JSON
                return;
            }

            log.debug({body: body}, "Printing out the results of Body ");

            let cidrLength;
            if(Array.isArray(body.net.netBlocks.netBlock)){
                cidrLength = body.net.netBlocks.netBlock[0].cidrLength;
            }else{
                cidrLength = body.net.netBlocks.netBlock.cidrLength;
            }

            // The lookup results returned is an array of lookup objects with the following format
            cb(null, {
                // Required: This is the entity object passed into the integration doLookup method
                entity: entityObj,
                // Required: An object containing everything you want passed to the template
                data: {
                    // Required: this is the string value that is displayed in the template
                    entity_name: entityObj.value,
                    // Required: These are the tags that are displayed in your template
                    summary: [body.net.orgRef['@name']],
                    // Data that you want to pass back to the notification window details block
                    details: {
                        allData: body,
                        //Organization
                        orgHandle: body.net.orgRef['@handle'],
                        orgName: body.net.orgRef['@name'],
                        orgRef: body.net.orgRef['$'],
                        //Network Details
                        netBlockHandle: body.net.handle['$'],
                        netBlockName: body.net.name['$'],
                        netBlockCIDR: body.net.startAddress['$'] + '/' + cidrLength['$'],
                        startAddr: body.net.startAddress['$'],
                        endAddr: body.net.endAddress['$'],
                        netBlockRef: body.net.ref['$'],
                        regDate: body.net.registrationDate['$'],
                        upDate: body.net.updateDate['$'],
                        //Parent Network
                        parentHandle: body.net.parentNetRef['@handle'],
                        parentName: body.net.parentNetRef['@name'],
                        parentRef: body.net.parentNetRef['$']
                    }
                }
            });
        });

    }
}

function validateOptions(userOptions, cb) {
    let errors = [];
    //nothing to validate; leaving function for future expansion of integration.
    cb(null, errors);
}

// function that takes the ErrorObject and passes the error message to the notification window
var _createJsonErrorPayload = function (msg, pointer, httpCode, code, title, meta) {
    return {
        errors: [
            _createJsonErrorObject(msg, pointer, httpCode, code, title, meta)
        ]
    }
};

// function that creates the Json object to be passed to the payload
var _createJsonErrorObject = function (msg, pointer, httpCode, code, title, meta) {
    let error = {
        detail: msg,
        status: httpCode.toString(),
        title: title,
        code: 'ARIN_' + code.toString()
    };

    if (pointer) {
        error.source = {
            pointer: pointer
        };
    }

    if (meta) {
        error.meta = meta;
    }

    return error;
};

module.exports = {
    doLookup: doLookup,
    startup: startup,
    validateOptions: validateOptions
};<|endoftext|>


<commit_before>angular.module('loginService', [])
.provider('loginService', function () {
  var userToken = localStorage.getItem('userToken'),
      errorState = 'app.error',
      logoutState = 'app.home';

  this.$get = function ($rootScope, $http, $q, $state) {
    /**
     * Low-level, private functions.
     */

    var setHeaders = function (token) {
      if (!token) {
        delete $http.defaults.headers.common['X-Token'];
        return;
      }
      $http.defaults.headers.common['X-Token'] = token.toString();
    };

    var setToken = function (token) {
      if (!token) {
        localStorage.removeItem('userToken');
      } else {
        localStorage.setItem('userToken', token);
      }
      setHeaders(token);
    };

    var getLoginData = function () {
      if (userToken) {
        setHeaders(userToken);
      } else {
        wrappedService.userRole = userRoles.public;
        wrappedService.isLogged = false;
      }
    };

    var managePermissions = function () {
      // Register routing function.
      $rootScope.$on('$stateChangeStart', function (event, to, toParams, from, fromParams) {

        /**
         * $stateChangeStart is a synchronous check to the accessLevels property
         * if it's not set, it will setup a pendingStateChange and will let
         * the grandfather resolve do his job.
         *
         * In short:
         * If accessLevels is still undefined, it let the user change the state.
         * Grandfather.resolve will either let the user in or reject the promise later!
         */
        if (wrappedService.userRole === null) {
          wrappedService.pendingStateChange = {
            to: to,
            toParams: toParams
          };
          return;
        }

        // if the state has undefined accessLevel, anyone can access it.
        // NOTE: if `wrappedService.userRole === undefined` means the service still doesn't know the user role,
        // we need to rely on grandfather resolve, so we let the stateChange success, for now.
        if (to.accessLevel === undefined || to.accessLevel.bitMask & wrappedService.userRole.bitMask) {
          console.log('you are allowed on this page:', to.name);
        } else {
          event.preventDefault();
          // test this
          $state.go(errorState, { error: 'unauthorized' }, { location: false, inherit: false });
        }
      });

      // Gets triggered when a resolve isn't fulfilled
      // da aggiungere un caso in cui il resolve da informazioni solo ad un admin e non ad un user
      // quindi un url ad esempio /resource/admin
      // anche un url /resource/user
      // in questo modo si potrà vedere l'error redirect!
      // anche un caso in cui sono io che faccio fallire una $q cosi si vede l'errore stringa!
      $rootScope.$on('$stateChangeError', function (event, to, toParams, from, fromParams, error) {
        /**
         * This is a very clever way to implement failure redirection.
         * You can use the value of redirectMap, based on the value of the rejection
         * So you can setup DIFFERENT redirections based on different promise errors.
         */
        var errorObj;
        // in case the promise given to resolve function is an $http request
        // the error is a object containing the error and additional informations
        error = (typeof error === 'object') ? error.status.toString() : error;
        // there must be a tokenexpired error.
        if (error === 'tokenexpired') {
          $state.go(errorState, { error: error }, { location: false, inherit: false });
          return wrappedService.logoutUser();
        }
        /**
         * Generic redirect handling.
         * If a state transition has been prevented and it's not one of the 2 above errors, means it's a
         * custom error in your application.
         *
         * redirectMap should be defined in the $state(s) that can generate transition errors.
         */
        if (angular.isDefined(to.redirectMap) && angular.isDefined(to.redirectMap[error])) {
          return $state.go(to.redirectMap[error], { error: error });
        }
        return $state.go(errorState, { error: error }, { location: false, inherit: false });
      });
    };

    /**
     * High level, public methods
     */

    var wrappedService = {
      loginHandler: function (user, status, headers, config) {
        /**
         * Custom logic to manually set userRole goes here
         *
         * Commented example shows an userObj coming with a 'completed'
         * property defining if the user has completed his registration process,
         * validating his/her email or not.
         *
         * EXAMPLE:
         * if (user.hasValidatedEmail) {
         *   wrappedService.userRole = userRoles.registered;
         * } else {
         *   wrappedService.userRole = userRoles.invalidEmail;
         *   $state.go('app.nagscreen');
         * }
         */
        // setup token
        setToken(user.token);
        // update user
        angular.extend(wrappedService.user, user);
        // flag true on isLogged
        wrappedService.isLogged = true;
        // update userRole
        wrappedService.userRole = user.userRole;
        return user;
      },
      loginUser: function (httpPromise) {
        httpPromise.success(wrappedService.loginHandler);
      },
      logoutUser: function (httpPromise) {
        /**
         * De-registers the userToken remotely
         * then clears the loginService as it was on startup
         */
        setToken(null);
        wrappedService.userRole = userRoles.public;
        wrappedService.user = {};
        wrappedService.isLogged = false;
        $state.go(logoutState);
      },
      resolvePendingState: function (httpPromise) {
        var checkUser = $q.defer(),
            finalPromise,
            pendingState = wrappedService.pendingStateChange;

        // When the $http is done, we register the http result into loginHandler, `data` parameter goes into loginService.loginHandler
        httpPromise.success(wrappedService.loginHandler);
        httpPromise.error(function () {
          checkUser.reject('tokenexpired');
        });

        /**
         * Define another check after the $http is done, this will *Actually* check if current user can access the requested $state
         */
        finalPromise = $q.all([httpPromise, checkUser.promise]);

        httpPromise.then(function (result) {
          wrappedService.isLogged = true;
          // duplicated logic from loginService $stateChangeStart, slightly different, now we *MUST* have the userRole informations.
          if (pendingState.to.accessLevel === undefined || pendingState.to.accessLevel.bitMask & wrappedService.userRole.bitMask) {
            checkUser.resolve();
          } else {
            checkUser.reject('unauthorized');
          }
        });
        wrappedService.pendingStateChange = null;
        return finalPromise;
      },
      /**
       * Public properties
       */
      userRole: null,
      user: {},
      isLogged: null,
      pendingStateChange: null
    };

    getLoginData();
    managePermissions();

    return wrappedService;
  };
});
<commit_msg>Using loginService on a true server, makes the server generate some 5xx Responses, that wasn't handled very well before!<commit_after>angular.module('loginService', [])
.provider('loginService', function () {
  var userToken = localStorage.getItem('userToken'),
      errorState = 'app.error',
      logoutState = 'app.home';

  this.$get = function ($rootScope, $http, $q, $state) {
    /**
     * Low-level, private functions.
     */

    var setHeaders = function (token) {
      if (!token) {
        delete $http.defaults.headers.common['X-Token'];
        return;
      }
      $http.defaults.headers.common['X-Token'] = token.toString();
    };

    var setToken = function (token) {
      if (!token) {
        localStorage.removeItem('userToken');
      } else {
        localStorage.setItem('userToken', token);
      }
      setHeaders(token);
    };

    var getLoginData = function () {
      if (userToken) {
        setHeaders(userToken);
      } else {
        wrappedService.userRole = userRoles.public;
        wrappedService.isLogged = false;
      }
    };

    var managePermissions = function () {
      // Register routing function.
      $rootScope.$on('$stateChangeStart', function (event, to, toParams, from, fromParams) {

        /**
         * $stateChangeStart is a synchronous check to the accessLevels property
         * if it's not set, it will setup a pendingStateChange and will let
         * the grandfather resolve do his job.
         *
         * In short:
         * If accessLevels is still undefined, it let the user change the state.
         * Grandfather.resolve will either let the user in or reject the promise later!
         */
        if (wrappedService.userRole === null) {
          wrappedService.pendingStateChange = {
            to: to,
            toParams: toParams
          };
          return;
        }

        // if the state has undefined accessLevel, anyone can access it.
        // NOTE: if `wrappedService.userRole === undefined` means the service still doesn't know the user role,
        // we need to rely on grandfather resolve, so we let the stateChange success, for now.
        if (to.accessLevel === undefined || to.accessLevel.bitMask & wrappedService.userRole.bitMask) {
          console.log('you are allowed on this page:', to.name);
        } else {
          event.preventDefault();
          // test this
          $state.go(errorState, { error: 'unauthorized' }, { location: false, inherit: false });
        }
      });

      // Gets triggered when a resolve isn't fulfilled
      // da aggiungere un caso in cui il resolve da informazioni solo ad un admin e non ad un user
      // quindi un url ad esempio /resource/admin
      // anche un url /resource/user
      // in questo modo si potrà vedere l'error redirect!
      // anche un caso in cui sono io che faccio fallire una $q cosi si vede l'errore stringa!
      $rootScope.$on('$stateChangeError', function (event, to, toParams, from, fromParams, error) {
        /**
         * This is a very clever way to implement failure redirection.
         * You can use the value of redirectMap, based on the value of the rejection
         * So you can setup DIFFERENT redirections based on different promise errors.
         */
        var errorObj;
        // in case the promise given to resolve function is an $http request
        // the error is a object containing the error and additional informations
        error = (typeof error === 'object') ? error.status.toString() : error;
        // in case of a 'tokenexpired', or a random 5xx status code from server, user gets loggedout
        if (error === 'tokenexpired' || /5\d{2}/.test(error)) {
          wrappedService.logoutUser();
          return $state.go(errorState, { error: error }, { location: false, inherit: false });
        }
        /**
         * Generic redirect handling.
         * If a state transition has been prevented and it's not one of the 2 above errors, means it's a
         * custom error in your application.
         *
         * redirectMap should be defined in the $state(s) that can generate transition errors.
         */
        if (angular.isDefined(to.redirectMap) && angular.isDefined(to.redirectMap[error])) {
          return $state.go(to.redirectMap[error], { error: error });
        }
        return $state.go(errorState, { error: error }, { location: false, inherit: false });
      });
    };

    /**
     * High level, public methods
     */

    var wrappedService = {
      loginHandler: function (user, status, headers, config) {
        /**
         * Custom logic to manually set userRole goes here
         *
         * Commented example shows an userObj coming with a 'completed'
         * property defining if the user has completed his registration process,
         * validating his/her email or not.
         *
         * EXAMPLE:
         * if (user.hasValidatedEmail) {
         *   wrappedService.userRole = userRoles.registered;
         * } else {
         *   wrappedService.userRole = userRoles.invalidEmail;
         *   $state.go('app.nagscreen');
         * }
         */
        // setup token
        setToken(user.token);
        // update user
        angular.extend(wrappedService.user, user);
        // flag true on isLogged
        wrappedService.isLogged = true;
        // update userRole
        wrappedService.userRole = user.userRole;
        return user;
      },
      loginUser: function (httpPromise) {
        httpPromise.success(wrappedService.loginHandler);
      },
      logoutUser: function (httpPromise) {
        /**
         * De-registers the userToken remotely
         * then clears the loginService as it was on startup
         */
        setToken(null);
        wrappedService.userRole = userRoles.public;
        wrappedService.user = {};
        wrappedService.isLogged = false;
        $state.go(logoutState);
      },
      resolvePendingState: function (httpPromise) {
        var checkUser = $q.defer(),
            finalPromise,
            pendingState = wrappedService.pendingStateChange;

        // When the $http is done, we register the http result into loginHandler, `data` parameter goes into loginService.loginHandler
        httpPromise.success(wrappedService.loginHandler);
        httpPromise.error(function () {
          checkUser.reject('tokenexpired');
        });

        /**
         * Define another check after the $http is done, this will *Actually* check if current user can access the requested $state
         */
        finalPromise = $q.all([httpPromise, checkUser.promise]);

        httpPromise.then(function (result) {
          wrappedService.isLogged = true;
          // duplicated logic from loginService $stateChangeStart, slightly different, now we *MUST* have the userRole informations.
          if (pendingState.to.accessLevel === undefined || pendingState.to.accessLevel.bitMask & wrappedService.userRole.bitMask) {
            checkUser.resolve();
          } else {
            checkUser.reject('unauthorized');
          }
        });
        wrappedService.pendingStateChange = null;
        return finalPromise;
      },
      /**
       * Public properties
       */
      userRole: null,
      user: {},
      isLogged: null,
      pendingStateChange: null
    };

    getLoginData();
    managePermissions();

    return wrappedService;
  };
});
<|endoftext|>


<commit_before>import {
  omit,
  decodeBase64Url
} from './utils'

const reservedUserProperties = [
  '_id',
  '_rev',
  'name',
  'password',
  'roles',
  'type',
  'salt',
  'derived_key',
  'password_scheme',
  'iterations'
]

class LoginService {
  constructor (
    $http,
    $window,
    $rootRouter,
    config,
    sessionService,
    toastService,
    mainService
  ) {
    this.$http = $http
    this.$window = $window
    this.$rootRouter = $rootRouter
    this.config = config
    this.sessionService = sessionService
    this.toastService = toastService
    this.mainService = mainService
  }

  createUser (username, token) {
    const data = {
      username,
      token
    }
    const opts = {
      headers: {
        'x-api-key': this.config.middleware.key
      }
    }
    return this.$http.post(this.config.middleware.url + '/users', data, opts)
  }

  handleLoginError (error) {
    let message = 'Could not log you in'
    if (error && error.data && error.data.message) {
      message += `. The response was "${error.data.message}".`
    }
    return this.toastService.error('login-failed', message)
  }

  setSession (session) {
    const doc = Object.assign({}, session, {
      _id: '_local/session'
    })
    const opts = {
      forceUpdate: true
    }
    return this.sessionService.save(doc, opts)
  }

  init (session) {
    this.mainService.init(session)
    this.$rootRouter.navigate(['/Nav'])
    return session
  }

  navLogin () {
    this.$window.location.href = this.config.nav + '/SignIn.aspx'
  }

  navLogout () {
    this.$window.location.href = this.config.nav + '/SignOut.aspx'
  }

  loginOrCreateUser (username, token) {
    const retry = () => {
      return this.createUser(username, token)
        .then(() => this.sessionService.login(username, token))
    }
    return this.sessionService.login(username, token)
      .catch(retry)
  }

  getSession () {
    return this.sessionService.get('_local/session')
  }

  canActivate () {
    const isValidSession = (local, remote) => {
      if (!remote.ok) {
        return Promise.reject('session invalid')
      }
      if (!remote.userCtx) {
        return Promise.reject('missing user context in session')
      }
      if (remote.userCtx.name !== local.userName) {
        return Promise.reject(`session mismatch for user ${local.userName}`)
      }
    }

    const checkSession = localSession => {
      return this.sessionService.getSession()
        .then(remoteSession => isValidSession(localSession, remoteSession))
        .then(() => this.init(localSession))
        .catch(err => {
          if (angular.isObject(err) && err.status === 0) {
            // User looks to be offline, grant login
            return this.init(localSession)
          }
          throw err
        })
    }

    return this.getSession()
      .then(localSession => checkSession(localSession))
      .catch(err => this.navLogin(err))
  }

  updateSession (username, session) {
    const omitted = omit(session, reservedUserProperties)
    const metadata = Object.assign(omitted, {
      lastLogin: new Date().toISOString()
    })

    const updateIdRev = res => {
      if (!res.ok) {
        return session
      }
      return Object.assign(metadata, omit(res, ['ok']))
    }

    const opts = {
      metadata
    }
    return this.sessionService.putUser(username, opts)
      .then(updateIdRev)
  }

  login (instruction) {
    if (!(instruction.params.username && instruction.params.token)) {
      return this.canActivate()
    }

    const username = this.$window.decodeURI(instruction.params.username)
      .toLowerCase()
    const token = decodeBase64Url(instruction.params.token)

    return this.loginOrCreateUser(username, token)
      .then(() => this.sessionService.getUser(username))
      .then(session => this.updateSession(username, session))
      .then(session => this.setSession(session))
      .then(session => this.init(session))
      .catch(err => this.handleLoginError(err))
  }

  logout () {
    return this.getSession()
      .then(session => this.sessionService.remove(session))
  }
}

LoginService.$inject = [
  '$http',
  '$window',
  '$rootRouter',
  'config',
  'sessionService',
  'toastService',
  'mainService'
]

export default LoginService
<commit_msg>fix: case-insensitive user name condition<commit_after>import {
  omit,
  decodeBase64Url
} from './utils'

const reservedUserProperties = [
  '_id',
  '_rev',
  'name',
  'password',
  'roles',
  'type',
  'salt',
  'derived_key',
  'password_scheme',
  'iterations'
]

class LoginService {
  constructor (
    $http,
    $window,
    $rootRouter,
    config,
    sessionService,
    toastService,
    mainService
  ) {
    this.$http = $http
    this.$window = $window
    this.$rootRouter = $rootRouter
    this.config = config
    this.sessionService = sessionService
    this.toastService = toastService
    this.mainService = mainService
  }

  createUser (username, token) {
    const data = {
      username,
      token
    }
    const opts = {
      headers: {
        'x-api-key': this.config.middleware.key
      }
    }
    return this.$http.post(this.config.middleware.url + '/users', data, opts)
  }

  handleLoginError (error) {
    let message = 'Could not log you in'
    if (error && error.data && error.data.message) {
      message += `. The response was "${error.data.message}".`
    }
    return this.toastService.error('login-failed', message)
  }

  setSession (session) {
    const doc = Object.assign({}, session, {
      _id: '_local/session'
    })
    const opts = {
      forceUpdate: true
    }
    return this.sessionService.save(doc, opts)
  }

  init (session) {
    this.mainService.init(session)
    this.$rootRouter.navigate(['/Nav'])
    return session
  }

  navLogin () {
    this.$window.location.href = this.config.nav + '/SignIn.aspx'
  }

  navLogout () {
    this.$window.location.href = this.config.nav + '/SignOut.aspx'
  }

  loginOrCreateUser (username, token) {
    const retry = () => {
      return this.createUser(username, token)
        .then(() => this.sessionService.login(username, token))
    }
    return this.sessionService.login(username, token)
      .catch(retry)
  }

  getSession () {
    return this.sessionService.get('_local/session')
  }

  canActivate () {
    const isValidSession = (local, remote) => {
      if (!remote.ok) {
        return Promise.reject('session invalid')
      }
      if (!(remote.userCtx && remote.userCtx.name)) {
        return Promise.reject('missing user context in remote session')
      }
      if (!local.userName) {
        return Promise.reject('missing user name in local session')
      }
      if (remote.userCtx.name.toLowerCase() !== local.userName.toLowerCase()) {
        return Promise.reject(`session mismatch for user ${local.userName}`)
      }
    }

    const checkSession = localSession => {
      return this.sessionService.getSession()
        .then(remoteSession => isValidSession(localSession, remoteSession))
        .then(() => this.init(localSession))
        .catch(err => {
          if (angular.isObject(err) && err.status === 0) {
            // User looks to be offline, grant login
            return this.init(localSession)
          }
          throw err
        })
    }

    return this.getSession()
      .then(localSession => checkSession(localSession))
      .catch(err => this.navLogin(err))
  }

  updateSession (username, session) {
    const omitted = omit(session, reservedUserProperties)
    const metadata = Object.assign(omitted, {
      lastLogin: new Date().toISOString()
    })

    const updateIdRev = res => {
      if (!res.ok) {
        return session
      }
      return Object.assign(metadata, omit(res, ['ok']))
    }

    const opts = {
      metadata
    }
    return this.sessionService.putUser(username, opts)
      .then(updateIdRev)
  }

  login (instruction) {
    if (!(instruction.params.username && instruction.params.token)) {
      return this.canActivate()
    }

    const username = this.$window.decodeURI(instruction.params.username)
      .toLowerCase()
    const token = decodeBase64Url(instruction.params.token)

    return this.loginOrCreateUser(username, token)
      .then(() => this.sessionService.getUser(username))
      .then(session => this.updateSession(username, session))
      .then(session => this.setSession(session))
      .then(session => this.init(session))
      .catch(err => this.handleLoginError(err))
  }

  logout () {
    return this.getSession()
      .then(session => this.sessionService.remove(session))
  }
}

LoginService.$inject = [
  '$http',
  '$window',
  '$rootRouter',
  'config',
  'sessionService',
  'toastService',
  'mainService'
]

export default LoginService
<|endoftext|>


<commit_before>var Maki = require('maki');
var config = require('./config');
var decentral = new Maki( config );

var mongoose = decentral.mongoose;
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;

var Passport = require('maki-passport-local');
var passport = new Passport({ resource: 'Person' });

var Torrent = require('node-torrent-stream');
var readTorrent = require('read-torrent');
var magnet = require('magnet-uri');

var crypto = require('crypto');
var stream = require('stream');

decentral.use( passport );

var Credit = decentral.define('Credit', {
  internal: true,
  attributes: {
    _person: { type: ObjectId , ref: 'Person', required: true },
    role: { type: String , enum: ['host', 'producer', 'guest'] }
  }
});

var Show = decentral.define('Show', {
  attributes: {
    name:    { type: String , max: 35 , required: true , slug: true },
    created: { type: Date , default: Date.now , required: true },
    description: { type: String },
    hosts:     [ Credit.Schema ],
    producers: [ Credit.Schema ],
    donations: {
      type: { type: String , enum: ['bitcoin'] },
      destination: { type: String , max: 35 }
    }
  },
  icon: 'unmute'
});

var Recording = decentral.define('Recording', {
  attributes: {
    _show:    { type: ObjectId , ref: 'Show', required: false , alias: 'show' },
    title:    { type: String , max: 35 , required: true , slug: true },
    media:    { type: 'File', required: true },
    torrent:  { type: ObjectId , render: { create: false } },
    magnet:   { type: String , max: 24 , render: { create: false } },
    type:     { type: String , max: 5 , render: { create: false } },
    filename: { type: String , max: 255 , render: { create: false } },
    size:   { type: Number , render: { create: false } },
    recorded: { type: Date },
    released: { type: Date , default: Date.now , required: true },
    description: { type: String , format: 'markdown' },
    hash: { type: String , max: 32 , render: { create: false } },
    credits:  [ Credit.Schema ],
    // TODO: remove this in favor of a "Sources" object
    youtube: { type: String }
  },
  icon: 'sound'
});

var Checksum = decentral.define('Checksum', {
  attributes: {
    filename: { type: String },
    _file: { type: ObjectId },
    _recording: { type: ObjectId },
    hash: { type: String , max: 35 },
    type: { type: String , enum: ['md5'] },
    created: { type: Date , default: Date.now }
  },
  icon: 'lock'
});

Recording.post('query', function(next, done) {
  var recordings = this;
  Show.Model.populate( recordings , {
    path: '_show'
  }, function(err, populatedRecordings) {
    if (err) return done(err);
    return next( null , populatedRecordings );
  });
});

Recording.on('file:media', function(media) {
  console.log('received media:', media);

  var torrent = new Torrent({
    name: media.filename,
    trackers: config.torrents.trackers,
    webseeds: config.service.seeds.map(function(x) {
      return x + '/files/' + media._id
    })
  });
  var file = decentral.datastore.gfs.createReadStream({
    _id: media._id
  });
  var torrentstore = decentral.datastore.gfs.createWriteStream({
    mode: 'w',
    filename: media.filename + '.torrent',
    content_type: 'application/x-bittorrent'
  });
  torrentstore.on('error', function(data) {
    console.log('error!' , data );
  });
  torrentstore.on('close', function( torrentFile ) {
    readTorrent('http://localhost:15005/files/' + torrentFile._id , function(err, parsed) {
      if (err) console.error( err );
      var magnetURI = magnet.encode( parsed );

      Recording.patch({
        _id: media.metadata.document
      }, [
        { op: 'add', path: '/torrent' , value: torrentFile._id },
        { op: 'add', path: '/magnet' , value: magnetURI },
        { op: 'add', path: '/type' , value: media.contentType },
        { op: 'add', path: '/filename' , value: media.filename },
        { op: 'add', path: '/size' , value: media.length }
      ], function(err, num) {
        if (err) console.error( err );
        console.log('all done,', num , 'affected');
      });

    });
  });

  torrent.pipe( torrentstore );
  file.pipe( torrent );

});

Recording.pre('create', function(next, done) {
  var recording = this;
  if (!recording.media) return next();

  var db = decentral.datastore.mongoose.connections[0].db;
  var files = db.collection('fs.files');
  files.findOne({ _id: recording.media }, function(err, thing) {
    return Checksum.create({
      filename: thing.filename,
      _file: thing._id,
      hash: thing.md5,
      type: 'md5'
    }, function() {
      recording.hash = thing.md5;
      return next();
    });
  });
});

var Person = decentral.define('Person', {
  attributes: {
    name: {
      given: { type: String , max: 30 },
      family: { type: String , max: 70 }
    },
    username: { type: String , max: 35 , slug: true },
    password: { type: String , max: 70 , masked: true }
  },
  virtuals: {
    'name.full': function() {
      return [ this.name.given , this.name.family ].join(' ');
    }
  },
  icon: 'user'
});

decentral.serve(['http']).start(function() {

  decentral.app.get('/about', function(req, res, next) {
    return res.render('about');
  });

  // TODO: internalize to maki, provide sane defaults
  decentral.app.get('/recordings/:recordingSlug/edit', function(req, res, next) {
    Recording.get({ slug: req.param('recordingSlug') }, function(err, recording) {
      return res.render('recording-edit', {
        item: recording
      });
    });
  });

  decentral.app.post('/recordings/:recordingSlug', function(req, res, next) {
    Recording.update({ slug: req.param('recordingSlug') }, req.body , function(err, recording) {
      req.flash('success', 'Content edited successfully!');
      return res.redirect('/recordings/' + req.param('recordingSlug'));
    });
  });

  decentral.app.get('/search', function(req, res, next) {
    Show.query({}, function(err, shows) {
      return res.send({
        results: shows.map(function(x) {
          return {
            title: x.name
          }
        })
      });
    });
  });
});
<commit_msg>Condense show credits into a single field.<commit_after>var Maki = require('maki');
var config = require('./config');
var decentral = new Maki( config );

var mongoose = decentral.mongoose;
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;

var Passport = require('maki-passport-local');
var passport = new Passport({ resource: 'Person' });

var Torrent = require('node-torrent-stream');
var readTorrent = require('read-torrent');
var magnet = require('magnet-uri');

var crypto = require('crypto');
var stream = require('stream');

decentral.use( passport );

var Credit = decentral.define('Credit', {
  internal: true,
  attributes: {
    _person: { type: ObjectId , ref: 'Person', required: true },
    role: { type: String , enum: ['host', 'producer', 'guest'] }
  }
});

var Show = decentral.define('Show', {
  attributes: {
    name:    { type: String , max: 35 , required: true , slug: true },
    created: { type: Date , default: Date.now , required: true },
    description: { type: String },
    credits:     [ Credit.Schema ],
    donations: {
      type: { type: String , enum: ['bitcoin'] },
      destination: { type: String , max: 35 }
    }
  },
  icon: 'unmute'
});

var Recording = decentral.define('Recording', {
  attributes: {
    _show:    { type: ObjectId , ref: 'Show', required: false , alias: 'show' },
    title:    { type: String , max: 35 , required: true , slug: true },
    media:    { type: 'File', required: true },
    torrent:  { type: ObjectId , render: { create: false } },
    magnet:   { type: String , max: 24 , render: { create: false } },
    type:     { type: String , max: 5 , render: { create: false } },
    filename: { type: String , max: 255 , render: { create: false } },
    size:   { type: Number , render: { create: false } },
    recorded: { type: Date },
    released: { type: Date , default: Date.now , required: true },
    description: { type: String , format: 'markdown' },
    hash: { type: String , max: 32 , render: { create: false } },
    credits:  [ Credit.Schema ],
    // TODO: remove this in favor of a "Sources" object
    youtube: { type: String }
  },
  icon: 'sound'
});

var Checksum = decentral.define('Checksum', {
  attributes: {
    filename: { type: String },
    _file: { type: ObjectId },
    _recording: { type: ObjectId },
    hash: { type: String , max: 35 },
    type: { type: String , enum: ['md5'] },
    created: { type: Date , default: Date.now }
  },
  icon: 'lock'
});

Recording.post('query', function(next, done) {
  var recordings = this;
  Show.Model.populate( recordings , {
    path: '_show'
  }, function(err, populatedRecordings) {
    if (err) return done(err);
    return next( null , populatedRecordings );
  });
});

Recording.on('file:media', function(media) {
  console.log('received media:', media);

  var torrent = new Torrent({
    name: media.filename,
    trackers: config.torrents.trackers,
    webseeds: config.service.seeds.map(function(x) {
      return x + '/files/' + media._id
    })
  });
  var file = decentral.datastore.gfs.createReadStream({
    _id: media._id
  });
  var torrentstore = decentral.datastore.gfs.createWriteStream({
    mode: 'w',
    filename: media.filename + '.torrent',
    content_type: 'application/x-bittorrent'
  });
  torrentstore.on('error', function(data) {
    console.log('error!' , data );
  });
  torrentstore.on('close', function( torrentFile ) {
    readTorrent('http://localhost:15005/files/' + torrentFile._id , function(err, parsed) {
      if (err) console.error( err );
      var magnetURI = magnet.encode( parsed );

      Recording.patch({
        _id: media.metadata.document
      }, [
        { op: 'add', path: '/torrent' , value: torrentFile._id },
        { op: 'add', path: '/magnet' , value: magnetURI },
        { op: 'add', path: '/type' , value: media.contentType },
        { op: 'add', path: '/filename' , value: media.filename },
        { op: 'add', path: '/size' , value: media.length }
      ], function(err, num) {
        if (err) console.error( err );
        console.log('all done,', num , 'affected');
      });

    });
  });

  torrent.pipe( torrentstore );
  file.pipe( torrent );

});

Recording.pre('create', function(next, done) {
  var recording = this;
  if (!recording.media) return next();

  var db = decentral.datastore.mongoose.connections[0].db;
  var files = db.collection('fs.files');
  files.findOne({ _id: recording.media }, function(err, thing) {
    return Checksum.create({
      filename: thing.filename,
      _file: thing._id,
      hash: thing.md5,
      type: 'md5'
    }, function() {
      recording.hash = thing.md5;
      return next();
    });
  });
});

var Person = decentral.define('Person', {
  attributes: {
    name: {
      given: { type: String , max: 30 },
      family: { type: String , max: 70 }
    },
    username: { type: String , max: 35 , slug: true },
    password: { type: String , max: 70 , masked: true }
  },
  virtuals: {
    'name.full': function() {
      return [ this.name.given , this.name.family ].join(' ');
    }
  },
  icon: 'user'
});

decentral.serve(['http']).start(function() {

  decentral.app.get('/about', function(req, res, next) {
    return res.render('about');
  });

  // TODO: internalize to maki, provide sane defaults
  decentral.app.get('/recordings/:recordingSlug/edit', function(req, res, next) {
    Recording.get({ slug: req.param('recordingSlug') }, function(err, recording) {
      return res.render('recording-edit', {
        item: recording
      });
    });
  });

  decentral.app.post('/recordings/:recordingSlug', function(req, res, next) {
    Recording.update({ slug: req.param('recordingSlug') }, req.body , function(err, recording) {
      req.flash('success', 'Content edited successfully!');
      return res.redirect('/recordings/' + req.param('recordingSlug'));
    });
  });

  decentral.app.get('/search', function(req, res, next) {
    Show.query({}, function(err, shows) {
      return res.send({
        results: shows.map(function(x) {
          return {
            title: x.name
          }
        })
      });
    });
  });
});
<|endoftext|>


<commit_before>var Ξ=[],//stack
		//I/O functions
		ï,
		ô=i=>document.getElementById('o').value+=i!=[]._?i:Ξ.join`\n`,//output
		ℹ=i=>[i=i!=[]._?document.getElementById("c").value[i]:document.getElementById("c").value,Ξ.push(i)][0],//source

		//stack functions
		ᵖ=(i=0,...r)=>{Ξ.push(i,...r)},
		ᵍ=i=>i!=[]._?Ξ[i<0?Ξ.length+i:i]:Ξ[Ξ.length-1],
		ʳ=(i=Ξ.length-1)=>Ξ.splice(i,1),
		ᶜ=i=>Ξ=[],

		//aliasing
		ȉ=Infinity,
		ߎ=[]._,
		ℇ=math.e,
		ε=Number.EPSILON,
		ȋ=math.sqrt(-1),
		ɸ=(1+math.sqrt(5))/2,
		π=math.pi,
		τ=math.pi*2,
		М=math,
		Ϛ=String,
		Ѧ=Array,
		Ѩ=_,
		П=Number,
		Ø=Object,
		ʝ=JSON,
		ɼ=RegExp,
		Ḍ=Date,
		ש=window,
		ß='toString',
		ξ=s,
		ɘ=i=>LZString.decompress(i),
		ᴙ=i=>[...i].reverse().join``,
		ë=eval,
		nchars=`ḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙaʾẛẜẝẞẟẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹỺỻỼỽỾỿ`;
[Ϛ,Ѧ,П,Ø,ɼ,Ḍ,ξ,Ѩ].map(v=>Object.getOwnPropertyNames(v).map((x,y)=>v.prototype[String.fromCharCode(y+248)]=v.prototype[x]));
[М,Ϛ,Ѧ,П,Ø,ʝ,ɼ,Ḍ,Ѩ,ξ,ש].map(v=>Object.getOwnPropertyNames(v).map((x,y)=>v[String.fromCharCode(y+248)]=v[x]));
var Σ=(c,asdf=0)=>{
	//syntax from esmin to es6
	c=c
		.replace(/ɘ(.+)#/g,(x,y)=>ɘ(y))
		.replace(/ℍ/g,'00')
		.replace(/𝕜/g,'000')
		.replace(/𝕄/g,'000000')
		.replace(/𝔾/g,'000000000')
		.replace(/𝕋/g,'000000000000')
		.replace(/ℙ/g,'000000000000000')
		.replace(/𝔼/g,'000000000000000000')
		.replace(/ℤ/g,'000000000000000000000')
		.replace(/𝕐/g,'000000000000000000000000')
		.replace(/⬮/g,'()')
		.replace(/⬯/g,'(``)')
		.replace(/⇝/g,'((a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/⇀/g,'(($,_,ã)=>')
		.replace(/§/g,'($1)')
		.replace(/([ᵖᵍʳᶜôℹΣɘϚѦПØѨɼḌᴙξëß\u00f8-\u01ef])([A-Za-z$_ãïȉℇεȋɸπτ\u1e00-\u1eff]+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'$1($2)')
		.replace(/([ᵖᵍʳᶜôℹΣɘϚѦПØɼѨḌᴙξëß\u00f8-\u01ef])([^(\u00f8-\u01ef])/g,'$1($2')
		.replace(/ï(\d+)/g,'ï[$1]')
		.replace(/⇏/g,'(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/↛/g,'=(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/↪/g,'($,_,ã)=>')
		.replace(/⤤/g,'=($,_,ã)=>')
		.replace(/→/g,'=>')
		.replace(/”/g,'`)')
		.replace(/‘/g,'\\`')
		.replace(/’/g,'\\`)')
		.replace(/⸩/g,'))')
		.replace(/⎞/g,'/)')
		.replace(/⦃/g,'${')
		.replace(/…/g,'...')
		.replace(/⟦/g,'[...')
		.replace(/˖/g,'+=')
		.replace(/⧺/g,'++')
		.replace(/˗/g,'-=')
		.replace(/‡/g,'--')
		.replace(/×/g,'*=')
		.replace(/÷/g,'/=')
		.replace(/٪/g,'%=')
		.replace(/¡/g,'!!')
		.replace(/≔/g,'==')
		.replace(/≠/g,'!=')
		.replace(/≤/g,'<=')
		.replace(/≥/g,'>=')
		.replace(/⅋/g,'&&')
		.replace(/⋎/g,'||')
		.replace(/↺/g,'for(')
		.replace(/ᶉ/g,'return ')
		.replace(/ŋ/g,'new ')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)²/g,'Math.pow($1,2)')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)³/g,'Math.pow($1,3)')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)ⁿ(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.pow($1,$2)')
		.replace(/√(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.sqrt($1)')
		.replace(/∛(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.cbrt($1)')
		.replace(/½/g,'0.5')
		.replace(/¼/g,'0.25')
		.replace(/¾/g,'0.75')
		.replace(/⅐/g,'(1/7)')
		.replace(/⅑/g,'(1/9)')
		.replace(/⅒/g,'0.1')
		.replace(/⅓/g,'(1/3)')
		.replace(/⅔/g,'(2/3)')
		.replace(/⅕/g,'0.2')
		.replace(/⅖/g,'0.4')
		.replace(/⅗/g,'0.6')
		.replace(/⅘/g,'0.8')
		.replace(/⅙/g,'(1/6)')
		.replace(/⅚/g,'(5/6)')
		.replace(/⅛/g,'(1/8)')
		.replace(/⅜/g,'(3/8)')
		.replace(/⅝/g,'(5/8)')
		.replace(/⅞/g,'(7/8)')
		.replace(/ᶀ/g,'0b')
		.replace(/ᶍ/g,'0x')
		.replace(/Ⅹ/g,'10')
		.replace(/([\u00f8-\u01ef])/g,'["$1"]')
		.replace(/ß/g,'[ß]')
		.replace(/⌿/g,'/g')
		.replace(/⍀/g,'/ig')
		.replace(/⊨/g,'true')
		.replace(/⊭/g,'false')
		.replace(/«/g,'<<')
		.replace(/»/g,'>>')
		.replace(/⫸/g,'>>>')
		.replace(/˜/g,'~~')
	;
	if(asdf==1e4&&!c.match(/ô/g))c+=';ô()';console.log(c);eval(c)
}
<commit_msg>more digit support!<commit_after>var Ξ=[],//stack
		//I/O functions
		ï,
		ô=i=>document.getElementById('o').value+=i!=[]._?i:Ξ.join`\n`,//output
		ℹ=i=>[i=i!=[]._?document.getElementById("c").value[i]:document.getElementById("c").value,Ξ.push(i)][0],//source

		//stack functions
		ᵖ=(i=0,...r)=>{Ξ.push(i,...r)},
		ᵍ=i=>i!=[]._?Ξ[i<0?Ξ.length+i:i]:Ξ[Ξ.length-1],
		ʳ=(i=Ξ.length-1)=>Ξ.splice(i,1),
		ᶜ=i=>Ξ=[],

		//aliasing
		ȉ=Infinity,
		ߎ=[]._,
		ℇ=math.e,
		ε=Number.EPSILON,
		ȋ=math.sqrt(-1),
		ɸ=(1+math.sqrt(5))/2,
		π=math.pi,
		τ=math.pi*2,
		М=math,
		Ϛ=String,
		Ѧ=Array,
		Ѩ=_,
		П=Number,
		Ø=Object,
		ʝ=JSON,
		ɼ=RegExp,
		Ḍ=Date,
		ש=window,
		ß='toString',
		ξ=s,
		ɘ=i=>LZString.decompress(i),
		ᴙ=i=>[...i].reverse().join``,
		ë=eval,
		nchars=`ḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙaʾẛẜẝẞẟẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾếỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹỺỻỼỽỾỿ`;
[Ϛ,Ѧ,П,Ø,ɼ,Ḍ,ξ,Ѩ].map(v=>Object.getOwnPropertyNames(v).map((x,y)=>v.prototype[String.fromCharCode(y+248)]=v.prototype[x]));
[М,Ϛ,Ѧ,П,Ø,ʝ,ɼ,Ḍ,Ѩ,ξ,ש].map(v=>Object.getOwnPropertyNames(v).map((x,y)=>v[String.fromCharCode(y+248)]=v[x]));
var Σ=(c,asdf=0)=>{
	//syntax from esmin to es6
	c=c
		.replace(/ɘ(.+)#/g,(x,y)=>ɘ(y))
		.replace(/ℍ/g,'00')
		.replace(/𝕜/g,'000')
		.replace(/𝕄/g,'000000')
		.replace(/𝔾/g,'000000000')
		.replace(/𝕋/g,'000000000000')
		.replace(/ℙ/g,'000000000000000')
		.replace(/𝔼/g,'000000000000000000')
		.replace(/ℤ/g,'000000000000000000000')
		.replace(/𝕐/g,'000000000000000000000000')
		.replace(/⬮/g,'()')
		.replace(/⬯/g,'(``)')
		.replace(/⇝/g,'((a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/⇀/g,'(($,_,ã)=>')
		.replace(/§/g,'($1)')
		.replace(/([ᵖᵍʳᶜôℹΣɘϚѦПØѨɼḌᴙξëß\u00f8-\u01ef])([A-Za-z$_ãïȉℇεȋɸπτ²³ⁿ√∛¼½¾⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞ᶀᶍ\u1e00-\u1eff]+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'$1($2)')
		.replace(/([ᵖᵍʳᶜôℹΣɘϚѦПØɼѨḌᴙξëß\u00f8-\u01ef])([^(\u00f8-\u01ef])/g,'$1($2')
		.replace(/ï(\d+)/g,'ï[$1]')
		.replace(/⇏/g,'(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/↛/g,'=(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)=>')
		.replace(/↪/g,'($,_,ã)=>')
		.replace(/⤤/g,'=($,_,ã)=>')
		.replace(/→/g,'=>')
		.replace(/”/g,'`)')
		.replace(/‘/g,'\\`')
		.replace(/’/g,'\\`)')
		.replace(/⸩/g,'))')
		.replace(/⎞/g,'/)')
		.replace(/⦃/g,'${')
		.replace(/…/g,'...')
		.replace(/⟦/g,'[...')
		.replace(/˖/g,'+=')
		.replace(/⧺/g,'++')
		.replace(/˗/g,'-=')
		.replace(/‡/g,'--')
		.replace(/×/g,'*=')
		.replace(/÷/g,'/=')
		.replace(/٪/g,'%=')
		.replace(/¡/g,'!!')
		.replace(/≔/g,'==')
		.replace(/≠/g,'!=')
		.replace(/≤/g,'<=')
		.replace(/≥/g,'>=')
		.replace(/⅋/g,'&&')
		.replace(/⋎/g,'||')
		.replace(/↺/g,'for(')
		.replace(/ᶉ/g,'return ')
		.replace(/ŋ/g,'new ')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)²/g,'Math.pow($1,2)')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)³/g,'Math.pow($1,3)')
		.replace(/(⦅.+|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)ⁿ(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.pow($1,$2)')
		.replace(/√(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.sqrt($1)')
		.replace(/∛(.+⦆|-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?)/g,'Math.cbrt($1)')
		.replace(/½/g,'0.5')
		.replace(/¼/g,'0.25')
		.replace(/¾/g,'0.75')
		.replace(/⅐/g,'(1/7)')
		.replace(/⅑/g,'(1/9)')
		.replace(/⅒/g,'0.1')
		.replace(/⅓/g,'(1/3)')
		.replace(/⅔/g,'(2/3)')
		.replace(/⅕/g,'0.2')
		.replace(/⅖/g,'0.4')
		.replace(/⅗/g,'0.6')
		.replace(/⅘/g,'0.8')
		.replace(/⅙/g,'(1/6)')
		.replace(/⅚/g,'(5/6)')
		.replace(/⅛/g,'(1/8)')
		.replace(/⅜/g,'(3/8)')
		.replace(/⅝/g,'(5/8)')
		.replace(/⅞/g,'(7/8)')
		.replace(/ᶀ/g,'0b')
		.replace(/ᶍ/g,'0x')
		.replace(/Ⅹ/g,'10')
		.replace(/([\u00f8-\u01ef])/g,'["$1"]')
		.replace(/ß/g,'[ß]')
		.replace(/⌿/g,'/g')
		.replace(/⍀/g,'/ig')
		.replace(/⊨/g,'true')
		.replace(/⊭/g,'false')
		.replace(/«/g,'<<')
		.replace(/»/g,'>>')
		.replace(/⫸/g,'>>>')
		.replace(/˜/g,'~~')
	;
	if(asdf==1e4&&!c.match(/ô/g))c+=';ô()';console.log(c);eval(c)
}
<|endoftext|>


<commit_before>//
// Created by davimacedo on 22/10/15.
//

'use strict';

var chai = require('chai');
var expect = chai.expect;
var AssertionError = chai.AssertionError;
var Promise = require('bluebird');
var mongodb = require('mongodb');
var MongoError = mongodb.MongoError;
var Db = mongodb.Db;
var Collection = mongodb.Collection;
var entity = require('@back4app/back4app-entity');
var settings = entity.settings;
var classes = entity.utils.classes;
var Adapter = entity.adapters.Adapter;
var MongoAdapter = require('../../../').MongoAdapter;

require('../settings');

var defaultAdapter = settings.ADAPTERS.default;

describe('MongoAdapter', function () {
  var mongoAdapter = null;

  it('expect to be instantiable', function () {
    mongoAdapter = new MongoAdapter('');
    mongoAdapter = new MongoAdapter('', {});
  });

  it('expect to not work with wrong arguments', function () {
    expect(function () {
      mongoAdapter = new MongoAdapter();
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter({});
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter('', function () {});
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter('', {}, null);
    }).to.throw(AssertionError);
  });

  it('expect to be an instance of Adapter', function () {
    expect(classes.isGeneral(Adapter, MongoAdapter));

    expect(mongoAdapter).to.be.an.instanceOf(Adapter);
  });

  describe('#openConnection', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.openConnection(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve with right connection', function (done) {
      var promise =  defaultAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise
        .then(function (result) {
          expect(result).to.be.an('undefined');
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to reject with invalid parameters', function (done) {
      mongoAdapter = new MongoAdapter(
        '', {}
      );
      var promise = mongoAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(Error);
        done();
      });
    });

    it('expect to reject with wrong connection', function (done) {
      this.timeout(2000);
      mongoAdapter = new MongoAdapter(
        'mongodb://127.0.0.1:6969?connectTimeoutMS=1000'
      );
      var promise = mongoAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(MongoError);
        done();
      });
    });

    it('expect to work if already opened', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.openConnection();
        })
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if asked to open many times', function (done) {
      var total = 10;
      var counter = 0;

      for (var i = 0; i < total; i++) {
        open();
      }

      function open() {
        defaultAdapter
          .openConnection()
          .then(function () {
            return defaultAdapter.closeConnection();
          })
          .then(function () {
            counter++;
            if (counter === total) {
              done();
            }
          });
      }
    });
  });

  describe('#closeConnection', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.closeConnection(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve', function (done) {
      defaultAdapter.openConnection().then(function () {
        var promise = defaultAdapter.closeConnection();
        expect(promise).to.be.an.instanceOf(Promise);
        promise.then(function (result) {
          expect(result).to.be.an('undefined');
          done();
        });
      });
    });

    it('expect to work if still opening', function (done) {
      defaultAdapter
        .openConnection();

      defaultAdapter
        .closeConnection()
        .then(done);
    });

    it('expect to work if already closed', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if asked to close many times', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          var total = 10;
          var counter = 0;

          for (var i = 0; i < total; i++) {
            close();
          }

          function close() {
            defaultAdapter
              .closeConnection()
              .then(function () {
                counter++;
                if (counter === total) {
                  done();
                }
              });
          }
        });
    });
  });

  describe('#getDatabase', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.getDatabase(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve with right arguments', function (done) {
      var promise = defaultAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to reject with invalid parameters', function (done) {
      mongoAdapter = new MongoAdapter(
        '', {}
      );
      var promise = mongoAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(Error);
        done();
      });
    });

    it('expect to reject with wrong connection', function (done) {
      this.timeout(2000);
      mongoAdapter = new MongoAdapter(
        'mongodb://127.0.0.1:6969?connectTimeoutMS=1000'
      );
      var promise = mongoAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(MongoError);
        done();
      });
    });

    it('expect to work if already opened', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.getDatabase();
        })
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if still opening', function (done) {
      defaultAdapter.openConnection();
      defaultAdapter.getDatabase()
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if closed', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(function () {
          return defaultAdapter.getDatabase();
        })
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if closing', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          defaultAdapter.closeConnection();
          defaultAdapter
            .getDatabase()
            .then(function (database) {
              expect(database).to.be.an.instanceOf(Db);
              return database.createCollection('MongoAdapter#getDatabase');
            })
            .then(function (collection) {
              expect(collection).to.be.an.instanceOf(Collection);
              return collection.drop();
            })
            .then(function (result) {
              expect(result).to.equal(true);
              return defaultAdapter.closeConnection();
            })
            .then(done);
        });
    });

    it('expect to work many times', function (done) {
      var total = 10;
      var counter = 0;

      defaultAdapter
        .getDatabase()
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          for (var i = 0; i < total; i++) {
            work();
          }
        });

      function work() {
        defaultAdapter
          .getDatabase()
          .then(function (database) {
            expect(database).to.be.an.instanceOf(Db);
            return database.collection('MongoAdapter#getDatabase');
          })
          .then(function (collection) {
            expect(collection).to.be.an.instanceOf(Collection);
            return defaultAdapter.closeConnection();
          })
          .then(function () {
            counter++;
            if (counter === total) {
              defaultAdapter
                .getDatabase()
                .then(function (database) {
                  expect(database).to.be.an.instanceOf(Db);
                  return database.dropCollection('MongoAdapter#getDatabase');
                })
                .then(function (result) {
                  expect(result).to.equal(true);
                  return defaultAdapter.closeConnection();
                })
                .then(done);
            }
          });
      }
    });
  });
});
<commit_msg>Found problem opening and closing connection<commit_after>//
// Created by davimacedo on 22/10/15.
//

'use strict';

var chai = require('chai');
var expect = chai.expect;
var AssertionError = chai.AssertionError;
var Promise = require('bluebird');
var mongodb = require('mongodb');
var MongoError = mongodb.MongoError;
var Db = mongodb.Db;
var Collection = mongodb.Collection;
var entity = require('@back4app/back4app-entity');
var settings = entity.settings;
var classes = entity.utils.classes;
var Adapter = entity.adapters.Adapter;
var MongoAdapter = require('../../../').MongoAdapter;

require('../settings');

var defaultAdapter = settings.ADAPTERS.default;

describe('MongoAdapter', function () {
  var mongoAdapter = null;

  it('expect to be instantiable', function () {
    mongoAdapter = new MongoAdapter('');
    mongoAdapter = new MongoAdapter('', {});
  });

  it('expect to not work with wrong arguments', function () {
    expect(function () {
      mongoAdapter = new MongoAdapter();
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter({});
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter('', function () {});
    }).to.throw(AssertionError);

    expect(function () {
      mongoAdapter = new MongoAdapter('', {}, null);
    }).to.throw(AssertionError);
  });

  it('expect to be an instance of Adapter', function () {
    expect(classes.isGeneral(Adapter, MongoAdapter));

    expect(mongoAdapter).to.be.an.instanceOf(Adapter);
  });

  describe('#openConnection', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.openConnection(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve with right connection', function (done) {
      var promise =  defaultAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise
        .then(function (result) {
          expect(result).to.be.an('undefined');
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to reject with invalid parameters', function (done) {
      mongoAdapter = new MongoAdapter(
        '', {}
      );
      var promise = mongoAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(Error);
        done();
      });
    });

    it('expect to reject with wrong connection', function (done) {
      this.timeout(2000);
      mongoAdapter = new MongoAdapter(
        'mongodb://127.0.0.1:6969?connectTimeoutMS=1000'
      );
      var promise = mongoAdapter.openConnection();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(MongoError);
        done();
      });
    });

    it('expect to work if already opened', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.openConnection();
        })
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if asked to open many times', function (done) {
      var total = 10;
      var counter = 0;

      for (var i = 0; i < total; i++) {
        open();
      }

      function open() {
        defaultAdapter
          .openConnection()
          .then(function () {
            return defaultAdapter.closeConnection();
          })
          .then(function () {
            counter++;
            if (counter === total) {
              done();
            }
          });
      }
    });
  });

  describe('#closeConnection', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.closeConnection(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve', function (done) {
      defaultAdapter.openConnection().then(function () {
        var promise = defaultAdapter.closeConnection();
        expect(promise).to.be.an.instanceOf(Promise);
        promise.then(function (result) {
          expect(result).to.be.an('undefined');
          done();
        });
      });
    });

    it('expect to work if still opening', function (done) {
      defaultAdapter
        .openConnection();

      defaultAdapter
        .closeConnection()
        .then(done);
    });

    it('expect to work if already closed', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if asked to close many times', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          var total = 10;
          var counter = 0;

          for (var i = 0; i < total; i++) {
            close();
          }

          function close() {
            defaultAdapter
              .closeConnection()
              .then(function () {
                counter++;
                if (counter === total) {
                  done();
                }
              });
          }
        });
    });
  });

  describe('#getDatabase', function () {
    it('expect to not work with wrong arguments', function () {
      expect(function () {
        defaultAdapter.getDatabase(null);
      }).to.throw(AssertionError);
    });

    it('expect to resolve with right arguments', function (done) {
      var promise = defaultAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to reject with invalid parameters', function (done) {
      mongoAdapter = new MongoAdapter(
        '', {}
      );
      var promise = mongoAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(Error);
        done();
      });
    });

    it('expect to reject with wrong connection', function (done) {
      this.timeout(2000);
      mongoAdapter = new MongoAdapter(
        'mongodb://127.0.0.1:6969?connectTimeoutMS=1000'
      );
      var promise = mongoAdapter.getDatabase();
      expect(promise).to.be.an.instanceOf(Promise);
      promise.catch(function (error) {
        expect(error).to.be.an.instanceOf(MongoError);
        done();
      });
    });

    it('expect to work if already opened', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.getDatabase();
        })
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if still opening', function (done) {
      defaultAdapter.openConnection();
      defaultAdapter.getDatabase()
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if closed', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          return defaultAdapter.closeConnection();
        })
        .then(function () {
          return defaultAdapter.getDatabase();
        })
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          return collection.drop();
        })
        .then(function (result) {
          expect(result).to.equal(true);
          return defaultAdapter.closeConnection();
        })
        .then(done);
    });

    it('expect to work if closing', function (done) {
      defaultAdapter
        .openConnection()
        .then(function () {
          defaultAdapter.closeConnection();
          defaultAdapter
            .getDatabase()
            .then(function (database) {
              expect(database).to.be.an.instanceOf(Db);
              return database.createCollection('MongoAdapter#getDatabase');
            })
            .then(function (collection) {
              expect(collection).to.be.an.instanceOf(Collection);
              return collection.drop();
            })
            .then(function (result) {
              expect(result).to.equal(true);
              return defaultAdapter.closeConnection();
            })
            .then(done);
        });
    });

    it.skip('expect to work many times', function (done) {
      var total = 10;
      var counter = 0;

      defaultAdapter
        .getDatabase()
        .then(function (database) {
          expect(database).to.be.an.instanceOf(Db);
          return database.createCollection('MongoAdapter#getDatabase');
        })
        .then(function (collection) {
          expect(collection).to.be.an.instanceOf(Collection);
          for (var i = 0; i < total; i++) {
            work();
          }
        });

      function work() {
        defaultAdapter
          .getDatabase()
          .then(function (database) {
            expect(database).to.be.an.instanceOf(Db);
            return new Promise (function (resolve, reject) {
              database.collection(
                'MongoAdapter#getDatabase',
                {
                  strict: true
                },
                function (error, collection) {
                  expect(error).to.equal(null);
                  resolve(collection);
                }
              );
            });
          })
          .then(function (collection) {
            expect(collection).to.be.an.instanceOf(Collection);
            return defaultAdapter.closeConnection();
          })
          .then(function () {
            counter++;
            if (counter === total) {
              defaultAdapter
                .getDatabase()
                .then(function (database) {
                  expect(database).to.be.an.instanceOf(Db);
                  return database.dropCollection('MongoAdapter#getDatabase');
                })
                .then(function (result) {
                  expect(result).to.equal(true);
                  return defaultAdapter.closeConnection();
                })
                .then(done);
            }
          });
      }
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>Fix Adding Local Files to Playlist #139<commit_after><|endoftext|>


<commit_before>"use strict";

// Extract the first part of the full domain fullName as the simple Netbios
// fullName.  Then pad out to 15-bytes as the official Netbios short name
// is fixed with.
module.exports = function(fullName, callback) {
  // Only the first part of the domain fullName should be encoded as a NetbIOS
  // fullName.
  var shortName = fullName;
  var scopeId = '';
  var dotIndex = fullName.indexOf('.');
  if (dotIndex > -1) {
    shortName = fullName.substr(0, dotIndex);
    scopeId = fullName.substr(dotIndex + 1);
  }

  if (shortName.length > 15) {
    callback('NetBIOS name [' + shortName + '] too long.  Must be <= 15 chars.');
    return;
  }

  var netbiosName = shortName;

  // space pad fullName out to 15 characters
  for (var i = 0; (shortName.length + i) < 15; ++i) {
    netbiosName += ' ';
  }

  callback(null, netbiosName, scopeId);
};
<commit_msg>single quotes<commit_after>'use strict';

// Extract the first part of the full domain fullName as the simple Netbios
// fullName.  Then pad out to 15-bytes as the official Netbios short name
// is fixed with.
module.exports = function(fullName, callback) {
  // Only the first part of the domain fullName should be encoded as a NetbIOS
  // fullName.
  var shortName = fullName;
  var scopeId = '';
  var dotIndex = fullName.indexOf('.');
  if (dotIndex > -1) {
    shortName = fullName.substr(0, dotIndex);
    scopeId = fullName.substr(dotIndex + 1);
  }

  if (shortName.length > 15) {
    callback('NetBIOS name [' + shortName + '] too long.  Must be <= 15 chars.');
    return;
  }

  var netbiosName = shortName;

  // space pad fullName out to 15 characters
  for (var i = 0; (shortName.length + i) < 15; ++i) {
    netbiosName += ' ';
  }

  callback(null, netbiosName, scopeId);
};
<|endoftext|>


<commit_before>//==================================================
//  Task
//  test:css
//  For the description see [SupeflyCSS Test Task](https://github.com/superfly-css/superfly-css-task-test/)
//==================================================

var gulp = require('gulp');
var cheerio = require('gulp-cheerio');
var highlight = require('gulp-highlight');
var path = require('path');

var PLI = require('superfly-css-pli');
var GLOB = require('glob-patterns');

var renderTestBlock = '\n

';

//---------------------------------------------------
//All the css files to be tested
//---------------------------------------------------
var glob = path.join(PLI.src.test.html, GLOB.ALL_HTML);

//---------------------------------
gulp.task('test:css', function() {
  return gulp
    .src(glob)
    .pipe(cheerio(function($, file) {
      $('.Test-markup > code').each(function() {
        var markup = $(this).html();
        //Insert the Test-render block after the Test-then block
        //Append the markup block to the Test-render block
        $($(this).parent().next()).after(renderTestBlock).next().append(markup);
      });
    }))
    .pipe(highlight())
    .pipe(gulp.dest(PLI.target.test.html));
});
<commit_msg>Removed glob patterns<commit_after>//==================================================
//  Task
//  test:css
//  For the description see [SupeflyCSS Test Task](https://github.com/superfly-css/superfly-css-task-test/)
//==================================================

var gulp = require('gulp');
var cheerio = require('gulp-cheerio');
var highlight = require('gulp-highlight');
var path = require('path');

var PLI = require('superfly-css-pli');

var renderTestBlock = '\n

';

//---------------------------------
gulp.task('test:css', function() {
  return gulp
    .src(PLI.SRC_MAIN_CSS)
    .pipe(cheerio(function($, file) {
      $('.Test-markup > code').each(function() {
        var markup = $(this).html();
        //Insert the Test-render block after the Test-then block
        //Append the markup block to the Test-render block
        $($(this).parent().next()).after(renderTestBlock).next().append(markup);
      });
    }))
    .pipe(highlight())
    .pipe(gulp.dest(PLI.target.test.html));
});
<|endoftext|>


<commit_before><commit_msg>Adds doc for Group - #189<commit_after><|endoftext|>


<commit_before>/*
 *  Copyright 2014 TWO SIGMA INVESTMENTS, LLC
 *
 *  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.
 */

/**
 * Node eval plugin
 * For creating and configuring evaluators that evaluate Javascript code on
 *   a remote node server and update code cell results.
 */
(function () {
    'use strict';
    var url = "./plugins/eval/node/node.js";
    var PLUGIN_NAME = "Node";
    var COMMAND = "node/nodePlugin";

    var serviceBase = null;

    var nodeProto = {
        pluginName: PLUGIN_NAME,
        cmMode: "javascript",
        background: "#80bd01",
        newShell: function (shellID, cb) {
            var self = this;

            if (!shellID) {
                shellID = "";
            }
            //verify server is up and running before a new shell call is attempted
            function checkNodeServerRunning() {
                $.ajax({
                    type: "GET",
                    datatype: "json",
                    url: serviceBase + "/pulse"
                }).fail(function(){
                    setTimeout(function () {
                        checkNodeServerRunning();
                    }, 2000)
                }).done(function(){
                    $.ajax({
                        type: "POST",
                        datatype: "json",
                        url: serviceBase + "/shell",
                        data: {shellid: shellID}
                    }).done(function(response){
                        shellID = response.shellID;
                        cb(shellID);
                    }).fail(function () {
                        console.log("failed to create shell", arguments);
                    });
                })
            }
            checkNodeServerRunning();
        },
        evaluate: function (code, modelOutput) {
            var self = this;
            var progressObj = {
                type: "BeakerDisplay",
                innertype: "Progress",
                object: {
                    message: "submitting ...",
                    startTime: new Date().getTime()
                }
            };
            modelOutput.result = progressObj;
            $.ajax({
                type: "POST",
                datatype: "json",
                url: serviceBase + "/evaluate",
                data: {shellID: self.settings.shellID, code: code}
            }).done(function(ret) {
                modelOutput.result = ret;
                bkHelper.refreshRootScope();
            }).fail(function(xhr, textStatus, error) {
                modelOutput.result = {
                    type: "BeakerDisplay",
                    innertype: "Error",
                    object: xhr.responseText
                };
            });
        },
        autocomplete: function (code, cpos, cb) {
            console.log("Autocomplete Called: Not implemented");
        },
        exit: function (cb) {
            console.log("Exit Called");
            var self = this;
            $.ajax({
                type: "POST",
                datatype: "json",
                url: serviceBase + "/rest/node/exit",
                data: { shellID: self.settings.shellID }
            }).done(cb);
        },
        spec: {}
    };

    var init = function () {
      bkHelper.locatePluginService(PLUGIN_NAME, {
        command: COMMAND,
        startedIndicator: "Server Starting",
        recordOutput: "true"
        }).success(function (ret) {
            serviceBase = ret;
            var NodeShell = function (settings, cb) {
                var self = this;
                var setShellIdCB = function (id) {
                    if (id !== settings.shellID) {
                        console.log("A new Node shell was created.");
                    }
                    settings.shellID = id;
                    self.settings = settings;
                    cb();
                };
                if (!settings.shellID) {
                    settings.shellID = "";
                }
                this.newShell(settings.shellID, setShellIdCB);
                this.perform = function (what) {
                    var action = this.spec[what].action;
                    this[action]();
                };
            };
            NodeShell.prototype = nodeProto;
            bkHelper.getLoadingPlugin(url).onReady(NodeShell);
        }).error(function () {
            alert('fail');
            console.log("process start failed", arguments);
        });
    };
    init();
})();
<commit_msg>Adjusted cell bg color for node plugin<commit_after>/*
 *  Copyright 2014 TWO SIGMA INVESTMENTS, LLC
 *
 *  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.
 */

/**
 * Node eval plugin
 * For creating and configuring evaluators that evaluate Javascript code on
 *   a remote node server and update code cell results.
 */
(function () {
    'use strict';
    var url = "./plugins/eval/node/node.js";
    var PLUGIN_NAME = "Node";
    var COMMAND = "node/nodePlugin";

    var serviceBase = null;

    var nodeProto = {
        pluginName: PLUGIN_NAME,
        cmMode: "javascript",
        background: "#dbe",
        newShell: function (shellID, cb) {
            var self = this;

            if (!shellID) {
                shellID = "";
            }
            //verify server is up and running before a new shell call is attempted
            function checkNodeServerRunning() {
                $.ajax({
                    type: "GET",
                    datatype: "json",
                    url: serviceBase + "/pulse"
                }).fail(function(){
                    setTimeout(function () {
                        checkNodeServerRunning();
                    }, 2000)
                }).done(function(){
                    $.ajax({
                        type: "POST",
                        datatype: "json",
                        url: serviceBase + "/shell",
                        data: {shellid: shellID}
                    }).done(function(response){
                        shellID = response.shellID;
                        cb(shellID);
                    }).fail(function () {
                        console.log("failed to create shell", arguments);
                    });
                })
            }
            checkNodeServerRunning();
        },
        evaluate: function (code, modelOutput) {
            var self = this;
            var progressObj = {
                type: "BeakerDisplay",
                innertype: "Progress",
                object: {
                    message: "submitting ...",
                    startTime: new Date().getTime()
                }
            };
            modelOutput.result = progressObj;
            $.ajax({
                type: "POST",
                datatype: "json",
                url: serviceBase + "/evaluate",
                data: {shellID: self.settings.shellID, code: code}
            }).done(function(ret) {
                modelOutput.result = ret;
                bkHelper.refreshRootScope();
            }).fail(function(xhr, textStatus, error) {
                modelOutput.result = {
                    type: "BeakerDisplay",
                    innertype: "Error",
                    object: xhr.responseText
                };
            });
        },
        autocomplete: function (code, cpos, cb) {
            console.log("Autocomplete Called: Not implemented");
        },
        exit: function (cb) {
            console.log("Exit Called");
            var self = this;
            $.ajax({
                type: "POST",
                datatype: "json",
                url: serviceBase + "/rest/node/exit",
                data: { shellID: self.settings.shellID }
            }).done(cb);
        },
        spec: {}
    };

    var init = function () {
      bkHelper.locatePluginService(PLUGIN_NAME, {
        command: COMMAND,
        startedIndicator: "Server Starting",
        recordOutput: "true"
        }).success(function (ret) {
            serviceBase = ret;
            var NodeShell = function (settings, cb) {
                var self = this;
                var setShellIdCB = function (id) {
                    if (id !== settings.shellID) {
                        console.log("A new Node shell was created.");
                    }
                    settings.shellID = id;
                    self.settings = settings;
                    cb();
                };
                if (!settings.shellID) {
                    settings.shellID = "";
                }
                this.newShell(settings.shellID, setShellIdCB);
                this.perform = function (what) {
                    var action = this.spec[what].action;
                    this[action]();
                };
            };
            NodeShell.prototype = nodeProto;
            bkHelper.getLoadingPlugin(url).onReady(NodeShell);
        }).error(function () {
            alert('fail');
            console.log("process start failed", arguments);
        });
    };
    init();
})();
<|endoftext|>


<commit_before><commit_msg>Cambiada duración de Redes<commit_after><|endoftext|>