<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, appshell, $, window */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Dialogs         = require("widgets/Dialogs"),
        DefaultDialogs  = require("widgets/DefaultDialogs"),
        // TODO: we have to figure out how we're going to build/deploy makedrive.js, this is hacky.
        // since it requires a manual `grunt build` step in src/thirdparty/makedrive
        MakeDrive       = require("thirdparty/makedrive/client/dist/makedrive"),
        Dialog          = require("thirdparty/filer-dialogs/filer-dialogs");

    var fs              = MakeDrive.fs(),
        Path            = MakeDrive.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    // Give extensions access to MakeDrive's sync functionality. The hosting app
    // needs to call sync.connect(serverURL) when the user is logged in, for example.
    appshell.MakeDrive = MakeDrive;

    var sync = fs.sync;

    // Try to upgrade to a syncing filesystem
    sync.connect('{{sockethost}}');

    //TODO: Do we want to do anything other than console.log for all these events?
    sync.on('syncing', function() {
        console.log('sync started');
    });
    sync.on('error', function(e) {
        console.log('sync error: ', e);

        Dialogs.showModalDialog(DefaultDialogs.DIALOG_ID_ERROR, "MakeDrive Sync Error", e);
    });
    sync.on('completed', function() {
        console.log('sync completed');
    });
    sync.on('updates', function() {
        console.log('server has updates');
    });

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        Dialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        Dialog.showSaveAsDialog.apply(null, arguments);
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?number} err A Filer error code
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        path = Path.normalize(path);

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        fs.rename(oldPath, newPath, _wrap(callback));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }
                stat(path, function (err, stat) {
                    callback(err, stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.unlink(path, function(err){
            callback(_mapError(err));
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
              if(err) {
                  return;
              }
              _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<commit_msg>Better error and console logs for sync events<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, appshell, $, window */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Dialogs         = require("widgets/Dialogs"),
        DefaultDialogs  = require("widgets/DefaultDialogs"),
        // TODO: we have to figure out how we're going to build/deploy makedrive.js, this is hacky.
        // since it requires a manual `grunt build` step in src/thirdparty/makedrive
        MakeDrive       = require("thirdparty/makedrive/client/dist/makedrive"),
        Dialog          = require("thirdparty/filer-dialogs/filer-dialogs");

    var fs              = MakeDrive.fs(),
        Path            = MakeDrive.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    // Give extensions access to MakeDrive's sync functionality. The hosting app
    // needs to call sync.connect(serverURL) when the user is logged in, for example.
    appshell.MakeDrive = MakeDrive;

    var sync = fs.sync;

    // Try to upgrade to a syncing filesystem
    sync.connect('{{sockethost}}');

    //TODO: Do we want to do anything other than console.log for all these events?
    sync.on('syncing', function() {
        console.log('MakeDrive sync started');
    });
    sync.on('connected', function() {
        console.log('Connected to MakeDrive server');
    });
    sync.on('disconnected', function() {
        console.log('Disconnected from MakeDrive server');
    });
    sync.on('error', function(e) {
        // Try to get better info from the error object
        if(e.code && e.message) {
            e = 'Error code: ' + e.code + ' - ' + e.message;
        } else if(e.stack) {
            e = e.stack;
        } else if(e.data) {
            e = e.data;
        } else if(e.error) {
            e = e.error;
        }
        console.log('sync error: ', e);

        Dialogs.showModalDialog(DefaultDialogs.DIALOG_ID_ERROR, "MakeDrive Sync Error", e);
    });
    sync.on('completed', function() {
        console.log('MakeDrive sync completed');
    });

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        Dialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        Dialog.showSaveAsDialog.apply(null, arguments);
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?number} err A Filer error code
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        path = Path.normalize(path);

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        fs.rename(oldPath, newPath, _wrap(callback));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }
                stat(path, function (err, stat) {
                    callback(err, stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.unlink(path, function(err){
            callback(_mapError(err));
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
              if(err) {
                  return;
              }
              _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<|endoftext|>


<commit_before>'use strict';

// update the following string whenever the asset cache needs to be flushed

module.exports = '20161026a';
<commit_msg>new assets version<commit_after>'use strict';

// update the following string whenever the asset cache needs to be flushed

module.exports = '20170210';
<|endoftext|>


<commit_before>"use strict";
var authen = require('authen');
var Auth = require('../handlers/auth');
var CtxAdapter = require('./ctx_adapter');

var AuthUnit = function () {
	this.units = null;
	this.settings = null;

	this.adapter = null;
	this.providers = {};
	this.providersByKey = {};

	this.revokerFactory = null;

	this.handler = this.createHandlerFactory();
};

AuthUnit.prototype.unitInit = function (units) {
	this.units = units; // can be useful for other init
	this.settings = units.require('core.settings');
	this.init();
};

AuthUnit.prototype.setRevokerFactory = function (f) {
	this.revokerFactory = f;
};

AuthUnit.prototype.init = function () {
	this.initMainAdapter(this.getAdapterSettings());
	this.initProviders(this.getProvidersSettings());
};

AuthUnit.prototype.getAuthSettings = function () {
	return this.settings.core.auth;
};

AuthUnit.prototype.getAdapterSettings = function () {
	return this.getAuthSettings().adapter;
};

AuthUnit.prototype.getProvidersSettings = function () {
	return this.getAuthSettings().providers;
};

AuthUnit.prototype.getHandlerSettings = function () {
	return this.getAuthSettings().handler;
};

AuthUnit.prototype.getAlgoMaps = function (type) {
	var result = this.getAuthSettings().algoMaps;
	var s = this.getProvidersSettings()[type];
	if (s != null) {
		s = s.tokener;
		if (s != null) {
			result = s.algoMaps;
		}
	}
	return result;
};

AuthUnit.prototype.initMainAdapter = function (settings) {
	this.adapter = this.createMainAdapter(settings);
};

AuthUnit.prototype.initProviders = function (providersSettings) {
	for (var type in providersSettings) {
		this.initProvider(type, providersSettings[type]);
	}
};

AuthUnit.prototype.initProvider = function (type, settings) {
	settings = settings || {};
	var provider = this.createProvider(type, settings.provider);

	var tokener = this.initTokener(type, settings);
	var adapter = this.obtainAdapter(type, settings.adapter);
	var revoker = this.createRevoker(type, settings.revoker);

	provider.type = type;
	provider.setTokener(tokener);
	provider.setAdapter(adapter);
	provider.setRevoker(revoker);

	this.addProvider(provider);
};

AuthUnit.prototype.addProvider = function (provider) {
	this.providers[provider.type] = provider;
	this.providersByKey[provider.options.key || ''] = provider;
};

AuthUnit.prototype.createProvider = function (type, settings) {
	return new authen.AuthProvider(settings);
};

AuthUnit.prototype.initTokener = function (type, settings) {
	var tokener = this.createTokener(type, settings.tokener);
	var signer = this.createSigner(type, settings.signer);
	var crypter = this.createCrypter(type, settings.crypter);
	tokener.setSigner(signer);
	tokener.setCrypter(crypter);
	tokener.setAlgoMaps(this.getAlgoMaps(type));
	return tokener;
};

AuthUnit.prototype.createTokener = function (type, settings) {
	return new authen.AuthTokener(settings);
};

AuthUnit.prototype.createSigner = function (type, settings) {
	var result = null;
	if (settings != null) {
		result = new authen.Signer(settings);
	}
	return result;
};

AuthUnit.prototype.createCrypter = function (type, settings) {
	var result = null;
	if (settings != null) {
		result = new authen.Crypter(settings);
	}
	return result;
};

AuthUnit.prototype.obtainAdapter = function (type, settings) {
	var result;
	if (settings == 'main') {
		result = this.adapter;
	}
	else {
		result = this.createAdapter(type, settings);
	}
	return result;
};

AuthUnit.prototype.createMainAdapter = function (settings) {
	return this.createAdapter(settings);
};

AuthUnit.prototype.createAdapter = function (type, settings) {
	settings = settings || {};
	var httpAdapter = this.createHttpAdapter(type, settings.http);
	return new CtxAdapter(httpAdapter, settings.ctx);
};

AuthUnit.prototype.createHttpAdapter = function (type, settings) {
	return new authen.HttpAdapter(settings);
};

AuthUnit.prototype.createRevoker = function (type, settings) {
	var result = null;
	if (this.revokerFactory != null) {
		result = this.revokerFactory(type, settings);
	}
	return result;
};

AuthUnit.prototype.createHandler = function (settings) {
	return new Auth(settings);
};

AuthUnit.prototype.initHandler = function (authorizationFunc) {
	var auth = this.createHandler(this.getHandlerSettings());
	auth.setAdapter(this.adapter);
	auth.setProviders(this.providersByKey);
	auth.setAuthorizationFunc(authorizationFunc);
	return auth;
};

AuthUnit.prototype.createHandlerFactory = function () {
	var self = this;
	var result = function (authorizationFunc) {
		return self.initHandler(authorizationFunc);
	};
	return result;
};

module.exports = AuthUnit;
<commit_msg>AuthUnit is 'init required' now<commit_after>"use strict";
var authen = require('authen');
var Auth = require('../handlers/auth');
var CtxAdapter = require('./ctx_adapter');

var AuthUnit = function () {
	this.units = null;
	this.settings = null;

	this.adapter = null;
	this.providers = {};
	this.providersByKey = {};

	this.revokerFactory = null;

	this.handler = this.createHandlerFactory();
};

AuthUnit.prototype.unitIsInitRequired = true;

AuthUnit.prototype.unitInit = function (units) {
	this.units = units; // can be useful for other init
	this.settings = units.require('core.settings');
	this.init();
};

AuthUnit.prototype.setRevokerFactory = function (f) {
	this.revokerFactory = f;
};

AuthUnit.prototype.init = function () {
	this.initMainAdapter(this.getAdapterSettings());
	this.initProviders(this.getProvidersSettings());
};

AuthUnit.prototype.getAuthSettings = function () {
	return this.settings.core.auth;
};

AuthUnit.prototype.getAdapterSettings = function () {
	return this.getAuthSettings().adapter;
};

AuthUnit.prototype.getProvidersSettings = function () {
	return this.getAuthSettings().providers;
};

AuthUnit.prototype.getHandlerSettings = function () {
	return this.getAuthSettings().handler;
};

AuthUnit.prototype.getAlgoMaps = function (type) {
	var result = this.getAuthSettings().algoMaps;
	var s = this.getProvidersSettings()[type];
	if (s != null) {
		s = s.tokener;
		if (s != null) {
			result = s.algoMaps;
		}
	}
	return result;
};

AuthUnit.prototype.initMainAdapter = function (settings) {
	this.adapter = this.createMainAdapter(settings);
};

AuthUnit.prototype.initProviders = function (providersSettings) {
	for (var type in providersSettings) {
		this.initProvider(type, providersSettings[type]);
	}
};

AuthUnit.prototype.initProvider = function (type, settings) {
	settings = settings || {};
	var provider = this.createProvider(type, settings.provider);

	var tokener = this.initTokener(type, settings);
	var adapter = this.obtainAdapter(type, settings.adapter);
	var revoker = this.createRevoker(type, settings.revoker);

	provider.type = type;
	provider.setTokener(tokener);
	provider.setAdapter(adapter);
	provider.setRevoker(revoker);

	this.addProvider(provider);
};

AuthUnit.prototype.addProvider = function (provider) {
	this.providers[provider.type] = provider;
	this.providersByKey[provider.options.key || ''] = provider;
};

AuthUnit.prototype.createProvider = function (type, settings) {
	return new authen.AuthProvider(settings);
};

AuthUnit.prototype.initTokener = function (type, settings) {
	var tokener = this.createTokener(type, settings.tokener);
	var signer = this.createSigner(type, settings.signer);
	var crypter = this.createCrypter(type, settings.crypter);
	tokener.setSigner(signer);
	tokener.setCrypter(crypter);
	tokener.setAlgoMaps(this.getAlgoMaps(type));
	return tokener;
};

AuthUnit.prototype.createTokener = function (type, settings) {
	return new authen.AuthTokener(settings);
};

AuthUnit.prototype.createSigner = function (type, settings) {
	var result = null;
	if (settings != null) {
		result = new authen.Signer(settings);
	}
	return result;
};

AuthUnit.prototype.createCrypter = function (type, settings) {
	var result = null;
	if (settings != null) {
		result = new authen.Crypter(settings);
	}
	return result;
};

AuthUnit.prototype.obtainAdapter = function (type, settings) {
	var result;
	if (settings == 'main') {
		result = this.adapter;
	}
	else {
		result = this.createAdapter(type, settings);
	}
	return result;
};

AuthUnit.prototype.createMainAdapter = function (settings) {
	return this.createAdapter(settings);
};

AuthUnit.prototype.createAdapter = function (type, settings) {
	settings = settings || {};
	var httpAdapter = this.createHttpAdapter(type, settings.http);
	return new CtxAdapter(httpAdapter, settings.ctx);
};

AuthUnit.prototype.createHttpAdapter = function (type, settings) {
	return new authen.HttpAdapter(settings);
};

AuthUnit.prototype.createRevoker = function (type, settings) {
	var result = null;
	if (this.revokerFactory != null) {
		result = this.revokerFactory(type, settings);
	}
	return result;
};

AuthUnit.prototype.createHandler = function (settings) {
	return new Auth(settings);
};

AuthUnit.prototype.initHandler = function (authorizationFunc) {
	var auth = this.createHandler(this.getHandlerSettings());
	auth.setAdapter(this.adapter);
	auth.setProviders(this.providersByKey);
	auth.setAuthorizationFunc(authorizationFunc);
	return auth;
};

AuthUnit.prototype.createHandlerFactory = function () {
	var self = this;
	var result = function (authorizationFunc) {
		return self.initHandler(authorizationFunc);
	};
	return result;
};

module.exports = AuthUnit;
<|endoftext|>


<commit_before>/**
 * The Element.Dimensions module tests
 *
 * Copyright (C) 2008-2009 Nikolay V. Nemshilov aka St. <nemshilov#gma-il>
 */
ElementDimensionsTest = TestCase.create({
  name: 'ElementDimensionsTest',

  beforeAll: function() {
    // makes the window scroll down
    this.spoof = new Element('div', {
      style: 'height: 2000px'
    }).insertTo(document.body);

    window.scrollTo(0, 100);
  },

  setUp: function() {
    this.div = new Element('div', {
      style: {
        width:   '200px',
        height:  '100px',
        margin:  '50px',
        padding: '50px',
        border:  '50px solid transparent'
      }
    }).insertTo(this.spoof, 'before');

    // screws with the manual position calculation
    this.p = new Element('p').insertTo(this.spoof, 'before').insert(this.div);
  },

  tearDown: function() {
    this.p.remove();
  },

  afterAll: function() {
    this.spoof.remove();
    window.scrollTo(0,0);
  },

  testSize: function() {
    this.assertEqual({x: 400, y: 300}, this.div.sizes());
  },

  testPosition: function() {
    var pos = this.div.position();
    this.assert(pos.x > 50 && pos.x < 70 && pos.y > 50 && pos.y < 100);
  },

  testScrolls: function() {
    this.assertEqual({x:0, y:0}, this.div.scrolls());
  },

  testDimensions: function() {
    var dims = this.div.dimensions();
    this.assertEqual(400, dims.width);
    this.assertEqual(300, dims.height);
    this.assertEqual(0, dims.scrollLeft);
    this.assertEqual(0, dims.scrollTop);
    this.assert(dims.top > 50);
    this.assert(dims.left > 50);
  },

  testSetWidth: function() {
    this.assertSame(this.div, this.div.setWidth(600));
    this.assertEqual(600, this.div.offsetWidth);

    this.assertEqual(300, this.div.offsetHeight);
  },

  testSetHeight: function() {
    this.assertSame(this.div, this.div.setHeight(600));
    this.assertEqual(600, this.div.offsetHeight);

    this.assertEqual(400, this.div.offsetWidth);
  },

  testResize: function() {
    this.assertSame(this.div, this.div.resize(500, 600));
    this.assertEqual({x: 500, y: 600}, this.div.sizes());

    this.assertSame(this.div, this.div.resize({x: 444, y: 666}));
    this.assertEqual({x: 444, y: 666}, this.div.sizes());
  },

  testMoveTo: function() {
    this.div.setStyle('position: absolute; margin: 0');
    this.assertSame(this.div, this.div.moveTo(40, 40));
    this.assertEqual({x: 40, y: 40}, this.div.position());
  }
});<commit_msg>Element#moveTo unit test update<commit_after>/**
 * The Element.Dimensions module tests
 *
 * Copyright (C) 2008-2009 Nikolay V. Nemshilov aka St. <nemshilov#gma-il>
 */
ElementDimensionsTest = TestCase.create({
  name: 'ElementDimensionsTest',

  beforeAll: function() {
    // makes the window scroll down
    this.spoof = new Element('div', {
      style: 'height: 2000px'
    }).insertTo(document.body);

    window.scrollTo(0, 100);
  },

  setUp: function() {
    this.div = new Element('div', {
      style: {
        width:   '200px',
        height:  '100px',
        margin:  '50px',
        padding: '50px',
        border:  '50px solid transparent'
      }
    }).insertTo(this.spoof, 'before');

    // screws with the manual position calculation
    this.p = new Element('p').insertTo(this.spoof, 'before').insert(this.div);
  },

  tearDown: function() {
    this.p.remove();
  },

  afterAll: function() {
    this.spoof.remove();
    window.scrollTo(0,0);
  },

  testSize: function() {
    this.assertEqual({x: 400, y: 300}, this.div.sizes());
  },

  testPosition: function() {
    var pos = this.div.position();
    this.assert(pos.x > 50 && pos.x < 70 && pos.y > 50 && pos.y < 100);
  },

  testScrolls: function() {
    this.assertEqual({x:0, y:0}, this.div.scrolls());
  },

  testDimensions: function() {
    var dims = this.div.dimensions();
    this.assertEqual(400, dims.width);
    this.assertEqual(300, dims.height);
    this.assertEqual(0, dims.scrollLeft);
    this.assertEqual(0, dims.scrollTop);
    this.assert(dims.top > 50);
    this.assert(dims.left > 50);
  },

  testSetWidth: function() {
    this.assertSame(this.div, this.div.setWidth(600));
    this.assertEqual(600, this.div.offsetWidth);

    this.assertEqual(300, this.div.offsetHeight);
  },

  testSetHeight: function() {
    this.assertSame(this.div, this.div.setHeight(600));
    this.assertEqual(600, this.div.offsetHeight);

    this.assertEqual(400, this.div.offsetWidth);
  },

  testResize: function() {
    this.assertSame(this.div, this.div.resize(500, 600));
    this.assertEqual({x: 500, y: 600}, this.div.sizes());

    this.assertSame(this.div, this.div.resize({x: 444, y: 666}));
    this.assertEqual({x: 444, y: 666}, this.div.sizes());
  },

  testMoveTo: function() {
    this.div.setStyle('position: absolute; margin: 0');

    this.assertSame(this.div, this.div.moveTo(40, 40));
    this.assertEqual({x: 40, y: 40}, this.div.position());

    this.div.insertTo(document.body).moveTo({x: 80, y: 80});
    this.assertEqual({x: 80, y: 80}, this.div.position());
  }
});<|endoftext|>


<commit_before>'use strict';

const crypto = require('crypto');
const qs = require('querystring');

const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');

const config = require('../config');
const db = require('./database');

class Mail {
  constructor() {

    this.email = db.settings.get('auth.email').value();

    if (process.env.NODE_ENV !== 'production') {
      this.transporter = nodemailer.createTransport({
        jsonTransport: true
      });
    } else {
      this.transporter = nodemailer.createTransport(config.authentication.mail);
    }

  }

  set address(adress) {
    this.email = adress;
    db.settings.get('auth').set('email', this.email).write();
  }

  get address() {
    return this.email;
  }

  send(token) {

    const uri = db.settings.get('uri').value();

    const body =
      `${uri}/authentication?token=${token}

      Add the following string to the end of URLs that you use for your streaming software.
      ?token=${token}`;

    if (process.env.NODE_ENV === 'development') {

      this.transporter.sendMail({
        from: 'Broadcast Notification System',
        to: this.email,
        subject: 'Access token',
        text: `${uri}/authentication?token=${token}`
      }, (err, info) => {
        console.log(info.envelope);
        console.log(info.messageId);
        console.log(info.message);
      });

    } else {

      this.transporter.sendMail({
        from: 'Broadcast Notification System',
        to: this.email,
        subject: 'Access token',
        text: body
      }, (err, info) => {
        if (err) {
          console.error(err);
        } else {
          console.log(info);
        }
      });

    }
  }
}

const mail = new Mail();

class JSONWebToken {
  constructor() {

    this.secret = db.settings.get('auth.secret').value();
    if (!this.secret) {
      this.secret = crypto.randomBytes(24).toString('hex');
      db.settings.get('auth').set('secret', this.secret).write();
    }

  }

  signToken() {
    return new Promise(async(resolve, reject) => {

      let token;

      try {
        token = await jwt.sign({
          iss: 'BNS',
          email: mail.address,
          iat: Math.floor(Date.now() / 1000) - 30,
          exp: Math.floor(Date.now() / 1000) + (config.authentication.tokenExp * 24 * 60 * 60),
        }, this.secret);
      } catch (err) {
        return reject(err);
      }

      db.settings.get('auth').set('expiration_date', Math.floor(Date.now() / 1000) + (10070 * 60)).write();
      mail.send(token);

      console.info(new Date(), 'Token successfully signed!');
      resolve();

    });
  }

  verifyToken(token) {
    return new Promise(async(resolve, reject) => {

      try {
        await jwt.verify(token, this.secret);
      } catch (err) {
        return reject(err);
      }

      resolve();

    });
  }

  ifExpired() {

    let expDate = db.settings.get('auth.expiration_date').value(),
      date = Date.now();

    if (mail.adress && (!expDate || date > expDate)) this.signToken();

  }

}

class Authentication extends JSONWebToken {
  constructor() {

    super();

    this.cookieSecure = false;

    // if (process.env.NODE_ENV === 'development') {
    //   this.cookieSecure = false;
    // } else {
    //   this.cookieSecure = true;
    // }

  }

  signUp(email) {
    mail.address = email;
    super.signToken();
  }

  koaMiddleware() {
    return async(ctx, next) => {

      const url = ctx.url;
      const authPath = '/authentication';

      if (!mail.address &&
        !url.startsWith(`${authPath}/signup`) &&
        !url.startsWith(`${authPath}/ressources`)) {
        return ctx.redirect(`${authPath}/signup`);
      }

      if (url.startsWith(`${authPath}`) && url.indexOf('?token') === -1) {
        return await next();
      }

      let token;

      if (ctx.request.query.token) {
        token = ctx.request.query.token;
      } else if (ctx.cookies.get('jwt')) {
        token = ctx.cookies.get('jwt');
      } else {
        ctx.status = 401;
        return await ctx.render('authentication/locked');
      }

      await new Promise(async(resolve, reject) => {
        try {
          await super.verifyToken(token);
        } catch (err) {
          return reject(err);
        }

        resolve();
      }).then(() => {
        return new Promise(async(resolve, reject) => {

          if (ctx.request.query.token) {
            try {
              await ctx.cookies.set('jwt', token, {
                secure: this.cookieSecure,
                httpOnly: true,
                maxAge: config.authentication.cookieExp * 60 * 1000,
                overwrite: true
              });
            } catch (err) {
              return reject(err);
            }
          }

          resolve();

        });
      }).catch(async err => {

        ctx.status = 401;
        await ctx.render('authentication/locked');
        console.error(err);

      });

      await next();

    };
  }

  socketMiddleware() {
    return async(socket, next) => {

      const cookies = socket.request.headers.cookie,
        token = qs.parse(cookies, ';', '=').jwt;

      if (token) {
        try {
          await super.verifyToken(token);
        } catch (err) {
          console.error(new Error(err));
          return next(new Error(err));
        }
      }

      next();

    };
  }

}

const authentication = new Authentication();
module.exports = authentication;
<commit_msg>some authentication fixes and improvements<commit_after>'use strict';

const crypto = require('crypto');
const qs = require('querystring');

const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');

const config = require('../config');
const db = require('./database');

class Mail {
  constructor() {

    this.email = db.settings.get('auth.email').value();

    if (process.env.NODE_ENV === 'development') {
      this.transporter = nodemailer.createTransport({
        jsonTransport: true
      });
    } else {
      this.transporter = nodemailer.createTransport(config.authentication.mail);
    }

  }

  set address(adress) {
    this.email = adress;
    db.settings.get('auth').set('email', this.email).write();
  }

  get address() {
    return this.email;
  }

  send(token) {

    const uri = db.settings.get('uri').value();

    const body =
      `${uri}/authentication?token=${token}

      Add the following string to the end of URLs that you use for your streaming software.
      ?token=${token}`;

    if (process.env.NODE_ENV === 'development') {

      this.transporter.sendMail({
        from: 'Broadcast Notification System',
        to: this.email,
        subject: 'Access token',
        text: `${uri}/authentication?token=${token}`
      }, (err, info) => {
        console.log(info.envelope);
        console.log(info.messageId);
        console.log(info.message);
      });

    } else {

      this.transporter.sendMail({
        from: 'Broadcast Notification System',
        to: this.email,
        subject: 'Access token',
        text: body
      }, (err, info) => {
        if (err) {
          console.error(err);
        } else {
          console.log(info);
        }
      });

    }
  }
}

const mail = new Mail();

class JSONWebToken {
  constructor() {

    this.secret = db.settings.get('auth.secret').value();
    if (!this.secret) {
      this.secret = crypto.randomBytes(24).toString('hex');
      db.settings.get('auth').set('secret', this.secret).write();
    }

  }

  signToken() {
    return new Promise(async(resolve, reject) => {

      let token;

      const exp_date = Math.floor(Date.now() / 1000) + (config.authentication.tokenExp * 24 * 60 * 60);

      try {
        token = await jwt.sign({
          iss: 'BNS',
          email: mail.address,
          iat: Math.floor(Date.now() / 1000),
          exp: exp_date,
        }, this.secret);
      } catch (err) {
        return reject(err);
      }

      db.settings.get('auth').set('expiration_date', exp_date - 1800).write();
      mail.send(token);

      console.info(new Date(), 'Token successfully signed!');
      resolve();

    });
  }

  verifyToken(token) {
    return new Promise(async(resolve, reject) => {

      try {
        await jwt.verify(token, this.secret);
      } catch (err) {
        return reject(err);
      }

      resolve();

    });
  }

  ifExpired() {

    const expDate = db.settings.get('auth.expiration_date').value(),
      date = Math.floor(Date.now() / 1000);

    if (mail.address && (!expDate || date > expDate)) {
      console.info('JWT has been expired! A new token will be signed.');
      this.signToken();
    }

  }

}

class Authentication extends JSONWebToken {
  constructor() {

    super();

    this.cookieSecure = false;

    // if (process.env.NODE_ENV === 'development') {
    //   this.cookieSecure = false;
    // } else {
    //   this.cookieSecure = true;
    // }

  }

  signUp(email) {
    mail.address = email;
    super.signToken();
  }

  koaMiddleware() {
    return async(ctx, next) => {

      const url = ctx.url;
      const authPath = '/authentication';

      if (!mail.address &&
        !url.startsWith(`${authPath}/signup`) &&
        !url.startsWith(`${authPath}/ressources`)) {
        return ctx.redirect(`${authPath}/signup`);
      }

      if (url.startsWith(`${authPath}`) && url.indexOf('?token') === -1) {
        return await next();
      }

      let token;

      if (ctx.request.query.token) {
        token = ctx.request.query.token;
      } else if (ctx.cookies.get('jwt')) {
        token = ctx.cookies.get('jwt');
      } else {
        ctx.status = 401;
        return await ctx.render('authentication/locked');
      }

      await new Promise(async(resolve, reject) => {
        try {
          await super.verifyToken(token);
        } catch (err) {
          return reject(err);
        }

        resolve();
      }).then(() => {
        return new Promise(async(resolve, reject) => {

          if (ctx.request.query.token) {
            try {
              await ctx.cookies.set('jwt', token, {
                secure: this.cookieSecure,
                httpOnly: true,
                maxAge: config.authentication.cookieExp * 60 * 1000,
                overwrite: true
              });
            } catch (err) {
              return reject(err);
            }
          }

          resolve();

        });
      }).catch(async err => {

        ctx.status = 401;
        await ctx.render('authentication/locked');
        console.error(err);

      });

      await next();

    };
  }

  socketMiddleware() {
    return async(socket, next) => {

      const cookies = socket.request.headers.cookie,
        token = qs.parse(cookies, ';', '=').jwt;

      if (token) {
        try {
          await super.verifyToken(token);
        } catch (err) {
          console.error(new Error(err));
          return next(new Error(err));
        }
      }

      next();

    };
  }

}

const authentication = new Authentication();
module.exports = authentication;
<|endoftext|>


<commit_before>'use strict'

var request = require('request'),
    common = require('./common'),
    apiUrl = common.urls.api,
    paths = common.urls.paths,
    regex = common.regex.auth,
    handleError = common.handleError

function getQueryString(params){
    return {
        'user[email]': params.email,
        'user[password]': params.password,
        grant_type: 'password'
    }
}

function authenticate(params){
    return new Promise((resolve, reject) =>{
        var url = apiUrl + paths.auth
        var qs = getQueryString(params)
        request.post({ url:url, qs:qs }, (err, response, body) => {
            var response = JSON.parse(body)
            if(response.error)
                reject(response.error)
            else
                resolve({
                    authToken: regex.authenticityToken.exec(response.update)[1],
                    user: response.current_user
                })
        })
    })
}

module.exports = authenticate<commit_msg>added cookie handle<commit_after>'use strict'

var requestLib = require('request'),
    jar = requestLib.jar(),
    request = requestLib.defaults({jar: jar}),
    common = require('./common'),
    apiUrl = common.urls.api,
    paths = common.urls.paths,
    regex = common.regex.auth,
    handleError = common.handleError

function getQueryString(params){
    return {
        'user[email]': params.email,
        'user[password]': params.password,
        grant_type: 'password'
    }
}

function authenticate(params){
    return new Promise((resolve, reject) =>{
        var url = apiUrl + paths.auth
        var qs = getQueryString(params)
        request.post({ url:url, qs:qs }, (err, response, body) => {
            var cookie_string = jar.getCookieString(url); // "key1=value1; key2=value2; ..."
            var cookies = jar.getCookies(url);
            var response = JSON.parse(body)
            if(response.error)
                reject(response.error)
            else
                resolve({
                    authenticityToken: regex.authenticityToken.exec(response.update)[1],
                    user: response.current_user,
                    cookieString: jar.getCookieString(url),
                    cookies: jar.getCookies(url)
                })
        })
    })
}

module.exports = authenticate<|endoftext|>


<commit_before>// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/

import webpack from 'webpack';

export default {
  output: {
    pathinfo: true,
  },
  // Something in `fathom-web/utils.js` breaks when eval'd,
  // so comment out 'eval' tool for now???
  devtool: 'cheap-source-map',
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
  ],
};
<commit_msg>Update obsolete comment in webpack.snippets.dev<commit_after>// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/

import webpack from 'webpack';

export default {
  output: {
    pathinfo: true,
  },
  // Something in `fathom-web/utils.js` breaks when eval'd,
  // so don't use the 'eval' tool for now, even though it's a
  // cheaper sourcemap generator.
  devtool: 'cheap-source-map',
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"development"',
    }),
  ],
};
<|endoftext|>


<commit_before>describe('Scroll View', function() {
  var sc;
  beforeEach(function() {
    sc = document.createElement('scroll-content');
    s = document.createElement('scroll');
    sc.appendChild(s);
  });

  it('Should init', function() {
    var sv = new ionic.views.ScrollNative({
      el: sc
    });
  });

  it('Should bind to event listeners', function() {
    spyOn(sc,'addEventListener');
    spyOn(document,'addEventListener');
    var sv = new ionic.views.ScrollNative({
      el: sc
    });

    expect(document.addEventListener).toHaveBeenCalled();
    expect(document.addEventListener.mostRecentCall.args[0]).toBe('resetScrollView');
    expect(sc.addEventListener).toHaveBeenCalled();
    expect(sc.addEventListener.callCount).toBe(4);
    expect(sc.addEventListener.mostRecentCall.args[0]).toBe('scrollChildIntoView');
  });

  it('Should remove event listeners on cleanup', function() {
    spyOn(sc,'removeEventListener');
    var sv = new ionic.views.ScrollNative({
      el: sc
    });
    sv.__cleanup();

    expect(sc.removeEventListener).toHaveBeenCalled();
    expect(sc.removeEventListener.callCount).toBe(6);
    expect(sc.removeEventListener.mostRecentCall.args[0]).toBe('resetScrollView');
  });

});
<commit_msg>Stupid tests are stupid<commit_after>describe('Scroll View', function() {
  var sc;
  beforeEach(function() {
    sc = document.createElement('scroll-content');
    s = document.createElement('scroll');
    sc.appendChild(s);
  });

  it('Should init', function() {
    var sv = new ionic.views.ScrollNative({
      el: sc
    });
  });

});
<|endoftext|>


<commit_before>// Copyright (c) 2012 Tom Steele, Jason Doyle
// See the file license.txt for copying permission
var async = require('async');
var dns = require('dns');
var tls = require('tls');
var https = require('https');
var http = require('http');
var url = require('url');

//
// dictionary based lookup
//
exports.dictionary = function(domain, names, concurrency, callback) {
  var results = [];
  var q = async.queue(function (lookup, queueCallback) {
    lookup = lookup + '.' + domain;
    dns.resolve4(lookup, function (err, addresses) {
      if (err) {
       queueCallback();
      }
      else {
        results.push( { ip: addresses[0],
                        name:  lookup,
                        src: 'dictionary'
                       }
                     );
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(names);
};

//
// reverse ip lookup
//
exports.reverse = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    dns.reverse(host, function (err, domains) {
      if (err) {
        queueCallback();
      }
      else {
        domains.forEach(function(domain) {
          results.push( { ip: host,
                          name: domain,
                          src: 'reverse'
                         });
        });
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// grabs hostnames from ssl certificates
//
exports.cert = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var cleartextStream = tls.connect(443, host, function () {
      var cert = cleartextStream.getPeerCertificate();
      var cn = cert['subject']['CN'];
      var sns = cert['subjectalname'];
      if (cn) {
        results.push( { ip: host,
                        name: cn,
                        src: 'cert'
                      });
      }
      if (sns) {
        sns.forEach(function(sn) {
          results.push( { ip: host,
                          name: sn,
                          src: 'cert'
                        });
        });
      }
     queueCallback();
    });
    cleartextStream.on('error', queueCallback);
    cleartextStream.on('data', queueCallback);
    cleartextStream.on('end', queueCallback);
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// query bing for vhosts using api
//
exports.bingApi = function(hosts, concurrency, options, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var count = 50;
    var offset = 0;
    var message = '';
    var params = '?Query=%27ip:' + host + '%27' +
                 '&$top=' + count +
                 '&$skip=' + offset +
                 '&Adult=%27Off%27&$format=json';
    options.path = options.path.replace(/\?.*/, params);
    var req = https.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });

      res.on('end', function() {
        var urls = JSON.parse(message).d.results;
        urls.forEach(function(element) {
            results.push({ ip: host,
                           name: url.parse(element.Url)['hostname'],
                           src: 'bing-api'
                         });
        });
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// query bing for vhosts without api key
//
exports.bing = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var offset = 0;
    var message = '';
    var params = '?q=ip:' + host +
                 '&first=' + offset;
    var options = { hostname: 'www.bing.com',
                    path: '/search' + params };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });

      res.on('end', function() {
        var urls = message.match(/\"><cite>.*?<\/cite>/gm);
        if (urls) {
          urls.forEach(function(u) {
            u = u.match(/cite>(.*?)</i);
            if (u) {
              if (u[1].search('//')) {
                u[1] = 'http://'.concat(u[1]); // make url.parse happy
              }
              results.push({ ip: host,
                             name: url.parse(u[1])['hostname'],
                             src: 'bing'
                           });
            }
          });
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// grab name records from robtex.com one c-network at a time
//
exports.robtex = function(hosts, concurrency, callback) {
  var cNetworks = []; // unique C-networks
  for (var i = 0; i < hosts.length; i++) {
    var dup = false;
    var cnet = hosts[i].split(".", 3).join(".");
    for (var c = 0; c < cNetworks.length; c++) {
      if (cnet == cNetworks[c]) {
        dup = true;
        break;
      }
    }
    if (dup) {
      break;
    }
    cNetworks.push(cnet);
  }
  var results = [];
  var q = async.queue(function (cnet, queueCallback) {
    var message = '';
    var options = {
      hostname: 'cnet.robtex.com',
      path: '/' + cnet + '.html'
    };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });
      res.on('end', function() {
        var htmlRows = message.match(/<tr>[\w\W]*?<\/tr>/mg);
        for (var i = 0; i < htmlRows.length; i++) {
          var ipMatch = htmlRows[i].match(/ip\.robtex\.com\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\./);
          if (ipMatch) {
            var ipaddr = ipMatch[1];
            for (var c = 0; c < hosts.length; c++) { // check if ip in scope
              if (ipaddr == hosts[c]) {
                var hostname = htmlRows[i].match(/>([a-z0-9-\.]{2,}[a-z])<\/a>/i);
                if (hostname) {
                    results.push( { ip: ipaddr,
                                    name: hostname[1],
                                    src: 'robtex'
                                  });
                }
              }
            }
          }
          ipMatch = null;
          hostname = null;
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(cNetworks);
};

//
// parse http response headers
// TODO: build regex to match all header params
//
exports.headersHttp = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var req = http.request({'host': host}, function(res) {
      res.on('end', function() {
        if (res.headers.location) {
          var hostname = url.parse(res.headers.location)['hostname'];
          // we don't want an ip
          if (hostname && hostname.match(/[a-zA-Z]+/)) {
            results.push( { ip: host,
                            name: hostname,
                            src: 'headers-http'
                          });
          }
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// parse https response headers
//
exports.headersHttps = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var req = https.request({'host': host}, function(res) {
      res.on('end', function() {
        if (res.headers.location) {
          var hostname = url.parse(res.headers.location)['hostname'];
          // we dont want an ip
          if (hostname && hostname.match(/[a-zA-Z]+/)) {
            results.push( { ip: host,
                            name: hostname,
                            src: 'headers-https'
                          });
          }
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// grab names from serversniff.net
//
exports.serversniff = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var message = '';
    var options = {
      hostname: 'serversniff.net',
      path: '/hip-' + host
    };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });
      res.on('end', function() {
        var htmlTable = message.match(/<table>[\w\W]*?<\/table>/m);
        if (htmlTable) {
          results[host] = [];
          var rePattern = /<b>\s([a-z0-9\.\-]*)\s<\/b>/gi;
          // TODO: fix to use capture group
          var hostnames = htmlTable[0].match(rePattern);
        }
        if (hostnames) {
          hostnames.forEach(function(h){
            var name = h.match(/<b>\s([\w\W]*)\s<\/b>/i);
            results.push({ip:host, name:name[1], src: 'server-snifff'});
          });
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// Only return results that pass FCrDNS
//
exports.fcrdns = function(results, concurrency, callback) {
  var cleanResults = [];
  var q = async.queue(function (record, queueCallback) {
    dns.resolve4(record.name, function (err, addresses) {
      if (err) {
        queueCallback();
      }
      else {
        cleanResults.push( { ip: addresses[0],
                             name: record.name,
                             src: record.src
                           });
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function () { callback(cleanResults) };
  q.push(results);
};
<commit_msg>Moving for loops in robtext to Array.forEach<commit_after>// Copyright (c) 2012 Tom Steele, Jason Doyle
// See the file license.txt for copying permission
var async = require('async');
var dns = require('dns');
var tls = require('tls');
var https = require('https');
var http = require('http');
var url = require('url');

//
// dictionary based lookup
//
exports.dictionary = function(domain, names, concurrency, callback) {
  var results = [];
  var q = async.queue(function (lookup, queueCallback) {
    lookup = lookup + '.' + domain;
    dns.resolve4(lookup, function (err, addresses) {
      if (err) {
       queueCallback();
      }
      else {
        results.push( { ip: addresses[0],
                        name:  lookup,
                        src: 'dictionary'
                       }
                     );
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(names);
};

//
// reverse ip lookup
//
exports.reverse = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    dns.reverse(host, function (err, domains) {
      if (err) {
        queueCallback();
      }
      else {
        domains.forEach(function(domain) {
          results.push( { ip: host,
                          name: domain,
                          src: 'reverse'
                         });
        });
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// grabs hostnames from ssl certificates
//
exports.cert = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var cleartextStream = tls.connect(443, host, function () {
      var cert = cleartextStream.getPeerCertificate();
      var cn = cert['subject']['CN'];
      var sns = cert['subjectalname'];
      if (cn) {
        results.push( { ip: host,
                        name: cn,
                        src: 'cert'
                      });
      }
      if (sns) {
        sns.forEach(function(sn) {
          results.push( { ip: host,
                          name: sn,
                          src: 'cert'
                        });
        });
      }
     queueCallback();
    });
    cleartextStream.on('error', queueCallback);
    cleartextStream.on('data', queueCallback);
    cleartextStream.on('end', queueCallback);
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// query bing for vhosts using api
//
exports.bingApi = function(hosts, concurrency, options, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var count = 50;
    var offset = 0;
    var message = '';
    var params = '?Query=%27ip:' + host + '%27' +
                 '&$top=' + count +
                 '&$skip=' + offset +
                 '&Adult=%27Off%27&$format=json';
    options.path = options.path.replace(/\?.*/, params);
    var req = https.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });

      res.on('end', function() {
        var urls = JSON.parse(message).d.results;
        urls.forEach(function(element) {
            results.push({ ip: host,
                           name: url.parse(element.Url)['hostname'],
                           src: 'bing-api'
                         });
        });
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// query bing for vhosts without api key
//
exports.bing = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var offset = 0;
    var message = '';
    var params = '?q=ip:' + host +
                 '&first=' + offset;
    var options = { hostname: 'www.bing.com',
                    path: '/search' + params };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });

      res.on('end', function() {
        var urls = message.match(/\"><cite>.*?<\/cite>/gm);
        if (urls) {
          urls.forEach(function(u) {
            u = u.match(/cite>(.*?)</i);
            if (u) {
              if (u[1].search('//')) {
                u[1] = 'http://'.concat(u[1]); // make url.parse happy
              }
              results.push({ ip: host,
                             name: url.parse(u[1])['hostname'],
                             src: 'bing'
                           });
            }
          });
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function() { callback(results) };
  q.push(hosts);
};

//
// grab name records from robtex.com one c-network at a time
//
exports.robtex = function(hosts, concurrency, callback) {
  var cNetworks = []; // unique C-networks
  for (var i = 0; i < hosts.length; i++) {
    var dup = false;
    var cnet = hosts[i].split(".", 3).join(".");
    for (var c = 0; c < cNetworks.length; c++) {
      if (cnet == cNetworks[c]) {
        dup = true;
        break;
      }
    }
    if (dup) {
      break;
    }
    cNetworks.push(cnet);
  }
  var results = [];
  var q = async.queue(function (cnet, queueCallback) {
    var message = '';
    var options = {
      hostname: 'cnet.robtex.com',
      path: '/' + cnet + '.html'
    };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });
      res.on('end', function() {
        var htmlRows = message.match(/<tr>[\w\W]*?<\/tr>/mg);
        htmlRows.forEach(function(row) {
          var ipMatch = row.match(/ip\.robtex\.com\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\./);
          if (ipMatch) {
            var ipaddr = ipMatch[1];
            hosts.forEach(function(h) {
              if (ipaddr === hosts[c]) {
                var hn = row.match(/>([a-z0-9-\.]{2,}[a-z])<\/a>/i);
                if (hn) {
                  results.push({ip: ipaddr, name: hn[1], src: 'robtext'});
                }
              }
            });
          }
        });
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(cNetworks);
};

//
// parse http response headers
// TODO: build regex to match all header params
//
exports.headersHttp = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var req = http.request({'host': host}, function(res) {
      res.on('end', function() {
        if (res.headers.location) {
          var hostname = url.parse(res.headers.location)['hostname'];
          // we don't want an ip
          if (hostname && hostname.match(/[a-zA-Z]+/)) {
            results.push( { ip: host,
                            name: hostname,
                            src: 'headers-http'
                          });
          }
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// parse https response headers
//
exports.headersHttps = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var req = https.request({'host': host}, function(res) {
      res.on('end', function() {
        if (res.headers.location) {
          var hostname = url.parse(res.headers.location)['hostname'];
          // we dont want an ip
          if (hostname && hostname.match(/[a-zA-Z]+/)) {
            results.push( { ip: host,
                            name: hostname,
                            src: 'headers-https'
                          });
          }
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// grab names from serversniff.net
//
exports.serversniff = function(hosts, concurrency, callback) {
  var results = [];
  var q = async.queue(function (host, queueCallback) {
    var message = '';
    var options = {
      hostname: 'serversniff.net',
      path: '/hip-' + host
    };
    var req = http.request(options, function(res) {
      res.on('data', function(chunk) {
        message += chunk;
      });
      res.on('end', function() {
        var htmlTable = message.match(/<table>[\w\W]*?<\/table>/m);
        if (htmlTable) {
          results[host] = [];
          var rePattern = /<b>\s([a-z0-9\.\-]*)\s<\/b>/gi;
          // TODO: fix to use capture group
          var hostnames = htmlTable[0].match(rePattern);
        }
        if (hostnames) {
          hostnames.forEach(function(h) {
            var hn = h.match(/<b>\s([\w\W]*)\s<\/b>/i);
            results.push({ip:host, name:hn[1], src: 'server-snifff'});
          });
        }
        queueCallback();
      });
    });
    req.end();
    req.on('error', function() {
      queueCallback();
    });
  }, concurrency);
  q.drain = function () { callback(results) };
  q.push(hosts);
};

//
// Only return results that pass FCrDNS
//
exports.fcrdns = function(results, concurrency, callback) {
  var cleanResults = [];
  var q = async.queue(function (record, queueCallback) {
    dns.resolve4(record.name, function (err, addresses) {
      if (err) {
        queueCallback();
      }
      else {
        cleanResults.push( { ip: addresses[0],
                             name: record.name,
                             src: record.src
                           });
        queueCallback();
      }
    });
  }, concurrency);
  q.drain = function () { callback(cleanResults) };
  q.push(results);
};
<|endoftext|>


<commit_before>/*
 * JavaScript Canvas to Blob 2.0.3
 * https://github.com/blueimp/JavaScript-Canvas-to-Blob
 *
 * Copyright 2012, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 *
 * Based on stackoverflow user Stoive's code snippet:
 * http://stackoverflow.com/q/4998908
 */

/*jslint nomen: true, regexp: true */
/*global window, atob, Blob, ArrayBuffer, Uint8Array, define */

(function (window) {
    'use strict';
    var CanvasPrototype = window.HTMLCanvasElement &&
            window.HTMLCanvasElement.prototype,
        hasBlobConstructor = window.Blob && (function () {
            try {
                return Boolean(new Blob());
            } catch (e) {
                return false;
            }
        }()),
        hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
            (function () {
                try {
                    return new Blob([new Uint8Array(100)]).size === 100;
                } catch (e) {
                    return false;
                }
            }()),
        BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
            window.MozBlobBuilder || window.MSBlobBuilder,
        dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
            window.ArrayBuffer && window.Uint8Array && function (dataURI) {
                var byteString,
                    arrayBuffer,
                    intArray,
                    i,
                    mimeString,
                    bb;
                if (dataURI.split(',')[0].indexOf('base64') >= 0) {
                    // Convert base64 to raw binary data held in a string:
                    byteString = atob(dataURI.split(',')[1]);
                } else {
                    // Convert base64/URLEncoded data component to raw binary data:
                    byteString = decodeURIComponent(dataURI.split(',')[1]);
                }
                // Write the bytes of the string to an ArrayBuffer:
                arrayBuffer = new ArrayBuffer(byteString.length);
                intArray = new Uint8Array(arrayBuffer);
                for (i = 0; i < byteString.length; i += 1) {
                    intArray[i] = byteString.charCodeAt(i);
                }
                // Separate out the mime component:
                mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
                // Write the ArrayBuffer (or ArrayBufferView) to a blob:
                if (hasBlobConstructor) {
                    return new Blob(
                        [hasArrayBufferViewSupport ? intArray : arrayBuffer],
                        {type: mimeString}
                    );
                }
                bb = new BlobBuilder();
                bb.append(arrayBuffer);
                return bb.getBlob(mimeString);
            };
    if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
        if (CanvasPrototype.mozGetAsFile) {
            CanvasPrototype.toBlob = function (callback, type) {
                callback(this.mozGetAsFile('blob', type));
            };
        } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
            CanvasPrototype.toBlob = function (callback, type) {
                callback(dataURLtoBlob(this.toDataURL(type)));
            };
        }
    }
    if (typeof define === 'function' && define.amd) {
        define(function () {
            return dataURLtoBlob;
        });
    } else {
        window.dataURLtoBlob = dataURLtoBlob;
    }
}(window));
<commit_msg>* quality argument support<commit_after>/*
 * JavaScript Canvas to Blob 2.0.3
 * https://github.com/blueimp/JavaScript-Canvas-to-Blob
 *
 * Copyright 2012, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 *
 * Based on stackoverflow user Stoive's code snippet:
 * http://stackoverflow.com/q/4998908
 */

/*jslint nomen: true, regexp: true */
/*global window, atob, Blob, ArrayBuffer, Uint8Array, define */

(function (window) {
    'use strict';
    var CanvasPrototype = window.HTMLCanvasElement &&
            window.HTMLCanvasElement.prototype,
        hasBlobConstructor = window.Blob && (function () {
            try {
                return Boolean(new Blob());
            } catch (e) {
                return false;
            }
        }()),
        hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&
            (function () {
                try {
                    return new Blob([new Uint8Array(100)]).size === 100;
                } catch (e) {
                    return false;
                }
            }()),
        BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
            window.MozBlobBuilder || window.MSBlobBuilder,
        dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&
            window.ArrayBuffer && window.Uint8Array && function (dataURI) {
                var byteString,
                    arrayBuffer,
                    intArray,
                    i,
                    mimeString,
                    bb;
                if (dataURI.split(',')[0].indexOf('base64') >= 0) {
                    // Convert base64 to raw binary data held in a string:
                    byteString = atob(dataURI.split(',')[1]);
                } else {
                    // Convert base64/URLEncoded data component to raw binary data:
                    byteString = decodeURIComponent(dataURI.split(',')[1]);
                }
                // Write the bytes of the string to an ArrayBuffer:
                arrayBuffer = new ArrayBuffer(byteString.length);
                intArray = new Uint8Array(arrayBuffer);
                for (i = 0; i < byteString.length; i += 1) {
                    intArray[i] = byteString.charCodeAt(i);
                }
                // Separate out the mime component:
                mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
                // Write the ArrayBuffer (or ArrayBufferView) to a blob:
                if (hasBlobConstructor) {
                    return new Blob(
                        [hasArrayBufferViewSupport ? intArray : arrayBuffer],
                        {type: mimeString}
                    );
                }
                bb = new BlobBuilder();
                bb.append(arrayBuffer);
                return bb.getBlob(mimeString);
            };
    if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
        if (CanvasPrototype.mozGetAsFile) {
            CanvasPrototype.toBlob = function (callback, type) {
                callback(this.mozGetAsFile('blob', type));
            };
        } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
            CanvasPrototype.toBlob = function (callback, type, quality) {
                callback(dataURLtoBlob(this.toDataURL(type, quality)));
            };
        }
    }
    if (typeof define === 'function' && define.amd) {
        define(function () {
            return dataURLtoBlob;
        });
    } else {
        window.dataURLtoBlob = dataURLtoBlob;
    }
}(window));
<|endoftext|>


<commit_before>let groupId;
let locationsLimit = 1;
let groupUser;

function init() {
  getUserData();
  getGroupId();
  checkMembership();
  createLogoutUrl();
  loadPosts();
  getPollOptions();
  fetchBlobstoreUrlAndShowForm();
  loadMembers();
  loadClosestGroupLocations();
  autocomplete();
  loadTags();
}

/** Fetch current user's data from the server */
function getUserData() {
  fetch("/user")
    .then(response => response.json())
    .then(user => {
      groupUser = user;
      const formImg = document.getElementById("post-form-img");
      formImg.className = "user-img-blank align-vertical";
      const navImg = document.getElementById("profile-btn");
      navImg.className = "profile-btn-blank";
      if (user.profilePic != null && user.profilePic != "") {
        const authorProfileImg = document.createElement("img");
        authorProfileImg.className = "user-img align-vertical";
        authorProfileImg.src = "serve?blob-key=" + user.profilePic;
        formImg.append(authorProfileImg);

        const navProfileImg = document.createElement("img");
        navProfileImg.className = "profile-btn-img";
        navProfileImg.src = "serve?blob-key=" + user.profilePic;
        navImg.append(navProfileImg);
      }
    });
}

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var myArr = JSON.parse(this.responseText);
    let script = document.createElement('script');
    script.src = "https://maps.googleapis.com/maps/api/js?key=" + myArr[0].GOOGLE_MAPS_API_KEY;
    script.innerHTML = "async defer";
    document.getElementsByTagName('head')[0].appendChild(script);
  }
};
xmlhttp.open("GET", "scripts/api_key.json", true);
xmlhttp.send();

function getGroupId() {
  groupId = window.location.search.substring(1).split("groupId=")[1];
}

function findClosestGroupLocations() {
  fetch(`/create-quadtree?groupId=${groupId}`, { method: "POST" }).then(() => {
		loadClosestGroupLocations();
	});
}

function loadClosestGroupLocations() {
  fetch(`/central-group-locations?groupId=${groupId}`).then(response => response.json()).then((allCentralGroupLocations) => {
    const groupLocations = document.getElementById("locations-container");
    if (allCentralGroupLocations.length == 0) {
      groupLocations.innerHTML = "No locations available. Please add more members or members are too far away.";
      let mapElement = document.getElementById('map');
      mapElement.style.display = "none";
    } else {
      groupLocations.innerHTML = "";
      for (let i = 1; i < locationsLimit + 1; i++) {
        groupLocations.appendChild(createLocationComponent(allCentralGroupLocations[i]));
      }
      let mapElement = document.getElementById('map');
      mapElement.style.display = "block";
      createMap(allCentralGroupLocations, locationsLimit);
    }
  });
}

function locationAmount() {
  const amount = document.getElementById("number");
  locationsLimit = parseInt(amount.value);
  loadClosestGroupLocations();
}

function createLocationComponent(location){
  const locationDiv = document.createElement("div");

  const locationName = document.createElement("p");
  locationName.className = "location-name";
  locationName.innerText = location.locationName;
  locationDiv.append(locationName);

  const locationAddress = document.createElement("p");
  locationAddress.className = "location-detail";
  locationAddress.innerText = location.address;
  locationDiv.append(locationAddress);

  const locationLatLon = document.createElement("p");
  locationLatLon.className = "location-detail";
  locationLatLon.innerText = location.coordinate.latitude + ", " + location.coordinate.longitude;
  locationDiv.append(locationLatLon);

  const locationDistance = document.createElement("p");
  locationDistance.className = "location-detail";
  locationDistance.innerText = location.distance + "mi";
  locationDiv.append(locationDistance);

  return locationDiv;
}

function checkMembership() {
  fetch(`/join-group?groupId=${groupId}`)
    .then(response => response.json())
    .then(isMemberData =>
      handleJoinGroupModal(isMemberData["groupName"], isMemberData["isMember"])
    );
}

function handleJoinGroupModal(groupName, isMember) {
  setGroupBannerText(groupName);
  if (!isMember) {
    showJoinGroupModal(groupName);
  } else {
    hideJoinGroupModal();
  }
}

function showJoinGroupModal(groupName) {
  document.getElementById("join-group-modal").style.display = "block";
  let paragraph = document.getElementById("join-group-text");
  paragraph.style.display = "block";
  let text = document.createTextNode(`Join ${groupName} to view its content`);
  paragraph.appendChild(text);

  let button = document.getElementById("join-group-btn");
  button.style.display = "block";
  button.addEventListener("click", joinGroup);

  let aTag = document.getElementById("go-to-profile");
  aTag.style.display = "block";
  aTag.setAttribute("href", "profile.html");
}

function hideJoinGroupModal() {
  document.getElementById("join-group-modal").style.display = "none";
  document.getElementById("join-group-text").style.display = "none";
  document.getElementById("join-group-btn").style.display = "none";
  document.getElementById("go-to-profile").style.display = "none";
}

function joinGroup() {
  fetch(`/join-group?groupId=${groupId}`, { method: "POST" }).then(
    hideJoinGroupModal
  );
}

function setGroupBannerText(groupName) {
  document.getElementById("group-name").textContent = groupName;
}
<commit_msg>spacing<commit_after>let groupId;
let locationsLimit = 1;
let groupUser;

function init() {
  getUserData();
  getGroupId();
  checkMembership();
  createLogoutUrl();
  loadPosts();
  getPollOptions();
  fetchBlobstoreUrlAndShowForm();
  loadMembers();
  loadClosestGroupLocations();
  autocomplete();
  loadTags();
}

/** Fetch current user's data from the server */
function getUserData() {
  fetch("/user")
    .then(response => response.json())
    .then(user => {
      groupUser = user;
      const formImg = document.getElementById("post-form-img");
      formImg.className = "user-img-blank align-vertical";
      const navImg = document.getElementById("profile-btn");
      navImg.className = "profile-btn-blank";
      if (user.profilePic != null && user.profilePic != "") {
        const authorProfileImg = document.createElement("img");
        authorProfileImg.className = "user-img align-vertical";
        authorProfileImg.src = "serve?blob-key=" + user.profilePic;
        formImg.append(authorProfileImg);

        const navProfileImg = document.createElement("img");
        navProfileImg.className = "profile-btn-img";
        navProfileImg.src = "serve?blob-key=" + user.profilePic;
        navImg.append(navProfileImg);
      }
    });
}

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var myArr = JSON.parse(this.responseText);
    let script = document.createElement('script');
    script.src = "https://maps.googleapis.com/maps/api/js?key=" + myArr[0].GOOGLE_MAPS_API_KEY;
    script.innerHTML = "async defer";
    document.getElementsByTagName('head')[0].appendChild(script);
  }
};
xmlhttp.open("GET", "scripts/api_key.json", true);
xmlhttp.send();

function getGroupId() {
  groupId = window.location.search.substring(1).split("groupId=")[1];
}

function findClosestGroupLocations() {
  fetch(`/create-quadtree?groupId=${groupId}`, { method: "POST" }).then(() => {
		loadClosestGroupLocations();
  });
}

function loadClosestGroupLocations() {
  fetch(`/central-group-locations?groupId=${groupId}`).then(response => response.json()).then((allCentralGroupLocations) => {
    const groupLocations = document.getElementById("locations-container");
    if (allCentralGroupLocations.length == 0) {
      groupLocations.innerHTML = "No locations available. Please add more members or members are too far away.";
      let mapElement = document.getElementById('map');
      mapElement.style.display = "none";
    } else {
      groupLocations.innerHTML = "";
      for (let i = 1; i < locationsLimit + 1; i++) {
        groupLocations.appendChild(createLocationComponent(allCentralGroupLocations[i]));
      }
      let mapElement = document.getElementById('map');
      mapElement.style.display = "block";
      createMap(allCentralGroupLocations, locationsLimit);
    }
  });
}

function locationAmount() {
  const amount = document.getElementById("number");
  locationsLimit = parseInt(amount.value);
  loadClosestGroupLocations();
}

function createLocationComponent(location){
  const locationDiv = document.createElement("div");

  const locationName = document.createElement("p");
  locationName.className = "location-name";
  locationName.innerText = location.locationName;
  locationDiv.append(locationName);

  const locationAddress = document.createElement("p");
  locationAddress.className = "location-detail";
  locationAddress.innerText = location.address;
  locationDiv.append(locationAddress);

  const locationLatLon = document.createElement("p");
  locationLatLon.className = "location-detail";
  locationLatLon.innerText = location.coordinate.latitude + ", " + location.coordinate.longitude;
  locationDiv.append(locationLatLon);

  const locationDistance = document.createElement("p");
  locationDistance.className = "location-detail";
  locationDistance.innerText = location.distance + "mi";
  locationDiv.append(locationDistance);

  return locationDiv;
}

function checkMembership() {
  fetch(`/join-group?groupId=${groupId}`)
    .then(response => response.json())
    .then(isMemberData =>
      handleJoinGroupModal(isMemberData["groupName"], isMemberData["isMember"])
    );
}

function handleJoinGroupModal(groupName, isMember) {
  setGroupBannerText(groupName);
  if (!isMember) {
    showJoinGroupModal(groupName);
  } else {
    hideJoinGroupModal();
  }
}

function showJoinGroupModal(groupName) {
  document.getElementById("join-group-modal").style.display = "block";
  let paragraph = document.getElementById("join-group-text");
  paragraph.style.display = "block";
  let text = document.createTextNode(`Join ${groupName} to view its content`);
  paragraph.appendChild(text);

  let button = document.getElementById("join-group-btn");
  button.style.display = "block";
  button.addEventListener("click", joinGroup);

  let aTag = document.getElementById("go-to-profile");
  aTag.style.display = "block";
  aTag.setAttribute("href", "profile.html");
}

function hideJoinGroupModal() {
  document.getElementById("join-group-modal").style.display = "none";
  document.getElementById("join-group-text").style.display = "none";
  document.getElementById("join-group-btn").style.display = "none";
  document.getElementById("go-to-profile").style.display = "none";
}

function joinGroup() {
  fetch(`/join-group?groupId=${groupId}`, { method: "POST" }).then(
    hideJoinGroupModal
  );
}

function setGroupBannerText(groupName) {
  document.getElementById("group-name").textContent = groupName;
}
<|endoftext|>


<commit_before>var beacon = require('../lib/beacon-controller.js');
var parameters = require('../lib/command-line-parameters.js');
var path = require('path');
var ipc = require('node-ipc');

/*
 * prints an alert to consult help guide in no options are provided
 */
exports.noOptionsAlert = function() {
    console.log("You didn't specify any options.")
    console.log("Run (klyng --help) for more info.");
};

/*
 * prints the help guide of the cli tool
 */
exports.help = function() {

    var guide = parameters.getUsage({
        title: "klyng",
        hide: ["app"],
        description: [
            "A command line tool to run klyng apps"
        ],
        synopsis: [
            "klyng --help",
            "klyng --beacon-up",
            "klyng --beacon-down",
            "klyng -n <number-of-processes> <path-to-klyng-app-entry>"
        ]
    });

    console.log(guide);
};

/*
 * starts the beacon process in the background
 */
exports.beaconUp = function() {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running)
            console.log('The beacon is already up and listening.');
        else
            return beacon.start();
    })
    .then(function(started) {
        if(started)
            console.log('The beacon is now up and listening.');
        else if(started === false)
            console.log("Some Error Occured");
    })
    .then(function() {
        ipc.disconnect('klyng_beacon');
    });
};

/*
 * shuts the beacon process down if running
 */
 exports.beaconDown = function() {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running) {
            return beacon.stop();
        }
        else {
            console.log("The beacon is not up.");
        }
    })
    .then(function(stopped) {
        if(stopped) {
            console.log("The beacon is now down.");
        }
        else if(stopped === false) {
            console.log("Some Error Occured");
        }
    });
};

/*
 * initaites a specified klyng job
 * signals the beacon process to spawn the parallel process
 * starts listening for control and monitoring messages from the beacon
 * @param job {Object}: the klyng job description
 */
exports.run = function(job) {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running) {
            return true;
        }
        else {
            return beacon.start();
        }
    })
    .then(function(started) {
        if(started) {
            return beacon.signalToRun(job);
        }
        else {
            console.log("Some Error Occured");
        }
    })
    .then(function(signaled) {
        if(signaled) {
            if(signaled === 'busy') {
                console.log('The beacon is busy.');
                ipc.disconnect('klyng_beacon');
            }
            else {

                var remainingProcessesCount = job.size;

                ipc.of.klyng_beacon.on('MONITOR:MSG', function(message, socket) {

                    if(message.type === 'process:stdout') {
                        console.log(message.data.line);
                    }
                    else if(message.type === 'process:exit') {
                        remainingProcessesCount--;
                        if(!remainingProcessesCount)
                            beacon.signalDone()
                    }
                });
            }
        }
        else {
            console.log("Some Error Occured");
        }
    });
};
<commit_msg>restructured the cli controller<commit_after>var beacon = require('../lib/beacon-controller.js');
var parameters = require('../lib/command-line-parameters.js');
var path = require('path');
var ipc = require('node-ipc');

/*
 * prints an alert to consult help guide in no options are provided
 */
function noOptionsAlert() {
    console.log("You didn't specify any options.")
    console.log("Run (klyng --help) for more info.");
}

/*
 * prints the help guide of the cli tool
 */
function help() {

    var guide = parameters.getUsage({
        title: "klyng",
        hide: ["app"],
        description: [
            "A command line tool to run klyng apps"
        ],
        synopsis: [
            "klyng --help",
            "klyng --beacon-up",
            "klyng --beacon-down",
            "klyng -n <number-of-processes> <path-to-klyng-app-entry>"
        ]
    });

    console.log(guide);
}

/*
 * starts the beacon process in the background
 */
function beaconUp() {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running)
            console.log('The beacon is already up and listening.');
        else
            return beacon.start();
    })
    .then(function(started) {
        if(started)
            console.log('The beacon is now up and listening.');
        else if(started === false)
            console.log("Some Error Occured");
    })
    .then(function() {
        ipc.disconnect('klyng_beacon');
    });
}

/*
 * shuts the beacon process down if running
 */
 function beaconDown() {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running) {
            return beacon.stop();
        }
        else {
            console.log("The beacon is not up.");
        }
    })
    .then(function(stopped) {
        if(stopped) {
            console.log("The beacon is now down.");
        }
        else if(stopped === false) {
            console.log("Some Error Occured");
        }
    });
}

/*
 * initaites a specified klyng job
 * signals the beacon process to spawn the parallel process
 * starts listening for control and monitoring messages from the beacon
 * @param job {Object}: the klyng job description
 */
function run(job) {

    beacon.checkIfRunning()
    .then(function(running) {
        if(running) {
            return true;
        }
        else {
            return beacon.start();
        }
    })
    .then(function(started) {
        if(started) {
            return beacon.signalToRun(job);
        }
        else {
            console.log("Some Error Occured");
        }
    })
    .then(function(signaled) {
        if(signaled) {
            if(signaled === 'busy') {
                console.log('The beacon is busy.');
                ipc.disconnect('klyng_beacon');
            }
            else {

                var remainingProcessesCount = job.size;

                ipc.of.klyng_beacon.on('MONITOR:MSG', function(message, socket) {

                    if(message.type === 'process:stdout') {
                        console.log(message.data.line);
                    }
                    else if(message.type === 'process:exit') {
                        remainingProcessesCount--;
                        if(!remainingProcessesCount)
                            beacon.signalDone()
                    }
                });
            }
        }
        else {
            console.log("Some Error Occured");
        }
    });
}

module.exports = {
    noOptionsAlert: noOptionsAlert,
    help: help,
    beaconUp: beaconUp,
    beaconDown: beaconDown,
    run: run
};
<|endoftext|>


<commit_before>// The `ledger print` command returns a readable stream that outputs the Ledger file 'pretty printed'
module.exports.run = function() {
  // print Ledger transactions sorted by date
  var process = this.cli.exec(['print', '--sort', 'd']);

  return process.stdout;
};<commit_msg>fix print command<commit_after>// The `ledger print` command returns a readable stream that outputs the Ledger file 'pretty printed'
module.exports.run = function(cli) {
  // print Ledger transactions sorted by date
  var process = cli.exec(['print', '--sort', 'd']);

  return process.stdout;
};
<|endoftext|>