<commit_before>/*
 * cmdrjs
 * Version 1.0.3-alpha
 * Copyright 2014 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.1-alpha',
            commands = {},
            activated = false,
            template = '

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 192,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup(['HELP','?','/?'], function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var key in commands) {
                var definition = commands[key];
                if (!!unwrap(definition.available)) {
                    cmdr.write(pad(key, ' ', 10));
                    cmdr.writeLine(definition.description);
                }
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup(['VERSION', 'VER'], function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup(['CLEAR','CLS'], function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup(['QUIT','EXIT'], function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keydown.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select, [contenteditable]') && event.keyCode ==  config.openKey) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && event.keyCode == config.closeKey) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = promptVal();
                            if (value) {
                                execute(value);
                            }
                            event.preventDefault();
                            return false;
                        case 38:
                            historyBack();
                            event.preventDefault();
                            return false;
                        case 40:
                            historyForward();
                            event.preventDefault();
                            return false;
                        case 9:
                            event.preventDefault();
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(promptVal());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = promptVal();
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keydown.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    promptVal(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                promptVal(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            };

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            promptVal(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definition = commands[parsed.name.toUpperCase()];
            if (!definition || !unwrap(definition.available)) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            for (var i = 0, l = definition.names.length; i < l; i++) {
                commands[definition.names[i].toUpperCase()] = definition;
            }
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css('text-indent', getPrefixWidth() + 'px').focus();
                container.animate({
                    scrollTop: container[0].scrollHeight
                }, 1000);
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(promptVal());
            }
            prefix.text('');
            promptVal('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [];

            do {
                var match = exp.exec(command);
                if (match != null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match != null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(names, callback, settings) {
            if (typeof names !== 'string' && !$.isArray(names)) {
                settings = callback;
                callback = names;
                names = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            if (typeof names === 'string') {
                names = [names]
            } else if ($.isArray(names)) {
                names = $.grep(names, function(value) {
                    return typeof value === 'string';
                });
            }

            var definition = {
                names: names,
                callback: callback,
                parse: true,
                available: true
            };

            $.extend(definition, settings);

            if (!$.isArray(definition.names) ||
                definition.names.length === 0 ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            return definition;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

        function unwrap(value) {
            return typeof value === 'function' ? value() : value;
        }

        function promptVal(value) {
            if (typeof value === 'undefined') {
                return prompt.text();
            } else {
                prompt.text(value);
            }
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window['cmdr'] = factory(window['jQuery']);
    }
}));
<commit_msg>version fix<commit_after>/*
 * cmdrjs
 * Version 1.0.2-alpha
 * Copyright 2014 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.1-alpha',
            commands = {},
            activated = false,
            template = '

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 192,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup(['HELP','?','/?'], function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var key in commands) {
                var definition = commands[key];
                if (!!unwrap(definition.available)) {
                    cmdr.write(pad(key, ' ', 10));
                    cmdr.writeLine(definition.description);
                }
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup(['VERSION', 'VER'], function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup(['CLEAR','CLS'], function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup(['QUIT','EXIT'], function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keydown.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select, [contenteditable]') && event.keyCode ==  config.openKey) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && event.keyCode == config.closeKey) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = promptVal();
                            if (value) {
                                execute(value);
                            }
                            event.preventDefault();
                            return false;
                        case 38:
                            historyBack();
                            event.preventDefault();
                            return false;
                        case 40:
                            historyForward();
                            event.preventDefault();
                            return false;
                        case 9:
                            event.preventDefault();
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(promptVal());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = promptVal();
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keydown.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css('text-indent', getPrefixWidth() + 'px').focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    promptVal(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                promptVal(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            };

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            promptVal(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definition = commands[parsed.name.toUpperCase()];
            if (!definition || !unwrap(definition.available)) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            for (var i = 0, l = definition.names.length; i < l; i++) {
                commands[definition.names[i].toUpperCase()] = definition;
            }
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css('text-indent', getPrefixWidth() + 'px').focus();
                container.animate({
                    scrollTop: container[0].scrollHeight
                }, 1000);
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(promptVal());
            }
            prefix.text('');
            promptVal('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [];

            do {
                var match = exp.exec(command);
                if (match != null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match != null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(names, callback, settings) {
            if (typeof names !== 'string' && !$.isArray(names)) {
                settings = callback;
                callback = names;
                names = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            if (typeof names === 'string') {
                names = [names]
            } else if ($.isArray(names)) {
                names = $.grep(names, function(value) {
                    return typeof value === 'string';
                });
            }

            var definition = {
                names: names,
                callback: callback,
                parse: true,
                available: true
            };

            $.extend(definition, settings);

            if (!$.isArray(definition.names) ||
                definition.names.length === 0 ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            return definition;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

        function unwrap(value) {
            return typeof value === 'function' ? value() : value;
        }

        function promptVal(value) {
            if (typeof value === 'undefined') {
                return prompt.text();
            } else {
                prompt.text(value);
            }
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window['cmdr'] = factory(window['jQuery']);
    }
}));
<|endoftext|>


<commit_before>import authControllers from '../controllers';

const usersController = authControllers.users;
const loginController = authControllers.login;
const groupsController = authControllers.group;
const messagesController = authControllers.messages;

module.exports = (app) => {
  app.get('/api', (req, res) => res.status(200).send({
    message: 'Welcome to the Postit API!',
  }));

  app.post('/api/user/signin', loginController.login);

  app.post('/api/user/signup', usersController.create);

  // An API route that allow users create broadcast groups:
  // POST: /api/group
  app.post('/api/group', groupsController.create);

  // An API route that allow users add other users to groups:
  app.post('/api/group/:groupid/user', groupsController.addNewUser);

  // An API route that allows a logged in user post messages to created groups:
  app.post('/api/group/:groupid/message', messagesController.create);

  // An API route that allows a logged in user retrieve messages that have been
  // posted to groups he/she belongs to:
  app.get('/api/group/:groupid/messages', groupsController.list);

  // Root route
  app.get('*', (req, res) => res.send('Sorry, the page u requested does not exist'));
};
<commit_msg>Use middleware to protect routes<commit_after>import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';
import authControllers from '../controllers';

const usersController = authControllers.users;
const loginController = authControllers.login;
const groupsController = authControllers.group;
const messagesController = authControllers.messages;

dotenv.config();

module.exports = (app) => {
  app.get('/api', (req, res) => res.status(200).send({
    message: 'Welcome to the Postit API!',
  }));

  app.post('/api/user/signin', loginController.login);

  app.post('/api/user/signup', usersController.create);

  app.use((req, res, next) => {
    // check header or url parameters or post parameters for token
    const token = req.body.token || req.query.token || req.headers['x-access-token'];

    // decode token
    if (token) {
      // verifies secret and checks exp
      jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
        if (err) {
          return res.json({ success: false, message: 'Failed to authenticate token.' });
        }
        // if everything is good, save to request for use in other routes
        req.decoded = decoded;
        next();
      });
    } else {
      // if there is no token
      // return an error
      return res.status(403).send({
        success: false,
        message: 'No token provided.'
      });
    }
  });

  // An API route that allow users create broadcast groups:
  // POST: /api/group
  app.post('/api/group', groupsController.create);

  // An API route that allow users add other users to groups:
  app.post('/api/group/:groupid/user', groupsController.addNewUser);

  // An API route that allows a logged in user post messages to created groups:
  app.post('/api/group/:groupid/message', messagesController.create);

  // An API route that allows a logged in user retrieve messages that have been
  // posted to groups he/she belongs to:
  app.get('/api/group/:groupid/messages', groupsController.list);

  // Root route
  app.get('*', (req, res) => res.send('Sorry, the page u requested does not exist'));
};
<|endoftext|>


<commit_before>/*
 * charts.js
 * Copyright (c) 2017 thegrumpydictator@gmail.com
 *
 * This file is part of Firefly III.
 *
 * Firefly III is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Firefly III is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
 */
/** global: Chart, defaultChartOptions, accounting, defaultPieOptions, noDataForChart, todayText */
var allCharts = {};

/*
 Make some colours:
 */
var colourSet = [
    [53, 124, 165],
    [0, 141, 76],
    [219, 139, 11],
    [202, 25, 90],
    [85, 82, 153],
    [66, 133, 244],
    [219, 68, 55],
    [244, 180, 0],
    [15, 157, 88],
    [171, 71, 188],
    [0, 172, 193],
    [255, 112, 67],
    [158, 157, 36],
    [92, 107, 192],
    [240, 98, 146],
    [0, 121, 107],
    [194, 24, 91]
];

var fillColors = [];
var strokePointHighColors = [];

for (var i = 0; i < colourSet.length; i++) {
    fillColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.5)");
    strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
}

Chart.defaults.global.legend.display = false;
Chart.defaults.global.animation.duration = 0;
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;

/**
 * Chart line thing
 */
const verticalLinePlugin = {
    getLinePosition: function (chart, pointIndex) {
        const meta = chart.getDatasetMeta(0); // first dataset is used to discover X coordinate of a point
        const data = meta.data;
        return data[pointIndex]._model.x;
    },
    renderVerticalLine: function (chartInstance, pointIndex) {
        const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex);
        const scale = chartInstance.scales['y-axis-0'];
        const context = chartInstance.chart.ctx;

        // render vertical line
        context.beginPath();
        context.strokeStyle = fillColors[3];
        context.moveTo(lineLeftOffset, scale.top);
        context.lineTo(lineLeftOffset, scale.bottom);
        context.stroke();

        // write label
        context.fillStyle = "#444444";
        context.textAlign = 'left';
        context.fillText(todayText, lineLeftOffset, scale.top * 3); // (scale.bottom - scale.top) / 2 + scale.top
    },

    afterDatasetsDraw: function (chart, easing) {
        if (chart.config.lineAtIndex) {
            chart.config.lineAtIndex.forEach(function(pointIndex) {
                this.renderVerticalLine(chart, pointIndex);
            }, this);
        }
    }
};

Chart.plugins.register(verticalLinePlugin);

/**
 *
 * @param data
 * @returns {{}}
 */
function colorizeData(data) {
    var newData = {};
    newData.datasets = [];

    for (var i = 0; i < data.count; i++) {
        newData.labels = data.labels;
        var dataset = data.datasets[i];
        dataset.fill = false;
        dataset.backgroundColor = dataset.borderColor = fillColors[i];
        newData.datasets.push(dataset);
    }
    return newData;
}

/**
 * Function to draw a line chart:
 * @param URI
 * @param container
 */
function lineChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'line';

    drawAChart(URI, container, chartType, options, colorData, -1);
}

function lineChartWithDay(URI, container, today) {
    "use strict";
    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'line';

    drawAChart(URI, container, chartType, options, colorData, today);
}

/**
 * Function to draw a chart with double Y Axes and stacked columns.
 *
 * @param URI
 * @param container
 */
function doubleYChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    options.scales.yAxes = [
        // y axis 0:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "left",
            "id": "y-axis-0"
        },
        // and y axis 1:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "right",
            "id": "y-axis-1"
        }

    ];
    options.stacked = true;
    options.scales.xAxes[0].stacked = true;

    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 * Function to draw a chart with double Y Axes and non stacked columns.
 *
 * @param URI
 * @param container
 */
function doubleYNonStackedChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    options.scales.yAxes = [
        // y axis 0:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "left",
            "id": "y-axis-0"
        },
        // and y axis 1:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "right",
            "id": "y-axis-1"
        }

    ];
    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 *
 * @param URI
 * @param container
 */
function columnChart(URI, container) {
    "use strict";
    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);

}

/**
 *
 * @param URI
 * @param container
 */
function stackedColumnChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);

    options.stacked = true;
    options.scales.xAxes[0].stacked = true;
    options.scales.yAxes[0].stacked = true;

    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 *
 * @param URI
 * @param container
 */
function pieChart(URI, container) {
    "use strict";

    var colorData = false;
    var options = $.extend(true, {}, defaultPieOptions);
    var chartType = 'pie';

    drawAChart(URI, container, chartType, options, colorData);

}

/**
 * @param URI
 * @param container
 * @param chartType
 * @param options
 * @param colorData
 * @param today
 */
function drawAChart(URI, container, chartType, options, colorData, today) {
    var containerObj = $('#' + container);
    if (containerObj.length === 0) {
        return;
    }

    $.getJSON(URI).done(function (data) {
        containerObj.removeClass('general-chart-error');
        if (data.labels.length === 0) {
            // remove the chart container + parent
            var holder = $('#' + container).parent().parent();
            if (holder.hasClass('box') || holder.hasClass('box-body')) {
                // find box-body:
                var boxBody;
                if (!holder.hasClass('box-body')) {
                    boxBody = holder.find('.box-body');
                } else {
                    boxBody = holder;
                }
                boxBody.empty().append($('<p>').append($('<em>').text(noDataForChart)));
            }
            return;
        }

        if (colorData) {
            data = colorizeData(data);
        }

        if (allCharts.hasOwnProperty(container)) {
            allCharts[container].data.datasets = data.datasets;
            allCharts[container].data.labels = data.labels;
            allCharts[container].update();
        } else {
            // new chart!
            var ctx = document.getElementById(container).getContext("2d");
            var chartOpts = {
                type: chartType,
                data: data,
                options: options,
                lineAtIndex: []
            };
            if (today >= 0) {
                chartOpts.lineAtIndex.push(today - 1);
            }
            allCharts[container] = new Chart(ctx, chartOpts);
        }

    }).fail(function () {
        $('#' + container).addClass('general-chart-error');
    });
}
<commit_msg>Fix #1155<commit_after>/*
 * charts.js
 * Copyright (c) 2017 thegrumpydictator@gmail.com
 *
 * This file is part of Firefly III.
 *
 * Firefly III is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Firefly III is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
 */
/** global: Chart, defaultChartOptions, accounting, defaultPieOptions, noDataForChart, todayText */
var allCharts = {};

/*
 Make some colours:
 */
var colourSet = [
    [53, 124, 165],
    [0, 141, 76],
    [219, 139, 11],
    [202, 25, 90],
    [85, 82, 153],
    [66, 133, 244],
    [219, 68, 55],
    [244, 180, 0],
    [15, 157, 88],
    [171, 71, 188],
    [0, 172, 193],
    [255, 112, 67],
    [158, 157, 36],
    [92, 107, 192],
    [240, 98, 146],
    [0, 121, 107],
    [194, 24, 91]
];

var fillColors = [];
var strokePointHighColors = [];

for (var i = 0; i < colourSet.length; i++) {
    fillColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.5)");
    strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
}

Chart.defaults.global.legend.display = false;
Chart.defaults.global.animation.duration = 0;
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;

/**
 * Chart line thing
 */
const verticalLinePlugin = {
    getLinePosition: function (chart, pointIndex) {
        const meta = chart.getDatasetMeta(0); // first dataset is used to discover X coordinate of a point
        const data = meta.data;
        return data[pointIndex]._model.x;
    },
    renderVerticalLine: function (chartInstance, pointIndex) {
        const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex);
        const scale = chartInstance.scales['y-axis-0'];
        const context = chartInstance.chart.ctx;

        // render vertical line
        context.beginPath();
        context.strokeStyle = fillColors[3];
        context.moveTo(lineLeftOffset, scale.top);
        context.lineTo(lineLeftOffset, scale.bottom);
        context.stroke();

        // write label
        context.fillStyle = "#444444";
        context.textAlign = 'left';
        if(pointIndex > 23) {
            todayText = todayText + ' ';
            context.textAlign = 'right';
        }
        context.fillText(todayText, lineLeftOffset, scale.top * 3); // (scale.bottom - scale.top) / 2 + scale.top
    },

    afterDatasetsDraw: function (chart, easing) {
        if (chart.config.lineAtIndex) {
            chart.config.lineAtIndex.forEach(function(pointIndex) {
                this.renderVerticalLine(chart, pointIndex);
            }, this);
        }
    }
};

Chart.plugins.register(verticalLinePlugin);

/**
 *
 * @param data
 * @returns {{}}
 */
function colorizeData(data) {
    var newData = {};
    newData.datasets = [];

    for (var i = 0; i < data.count; i++) {
        newData.labels = data.labels;
        var dataset = data.datasets[i];
        dataset.fill = false;
        dataset.backgroundColor = dataset.borderColor = fillColors[i];
        newData.datasets.push(dataset);
    }
    return newData;
}

/**
 * Function to draw a line chart:
 * @param URI
 * @param container
 */
function lineChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'line';

    drawAChart(URI, container, chartType, options, colorData, -1);
}

function lineChartWithDay(URI, container, today) {
    "use strict";
    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'line';

    drawAChart(URI, container, chartType, options, colorData, today);
}

/**
 * Function to draw a chart with double Y Axes and stacked columns.
 *
 * @param URI
 * @param container
 */
function doubleYChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    options.scales.yAxes = [
        // y axis 0:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "left",
            "id": "y-axis-0"
        },
        // and y axis 1:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "right",
            "id": "y-axis-1"
        }

    ];
    options.stacked = true;
    options.scales.xAxes[0].stacked = true;

    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 * Function to draw a chart with double Y Axes and non stacked columns.
 *
 * @param URI
 * @param container
 */
function doubleYNonStackedChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    options.scales.yAxes = [
        // y axis 0:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "left",
            "id": "y-axis-0"
        },
        // and y axis 1:
        {
            display: true,
            ticks: {
                callback: function (tickValue) {
                    "use strict";
                    return accounting.formatMoney(tickValue);

                },
                beginAtZero: true
            },
            position: "right",
            "id": "y-axis-1"
        }

    ];
    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 *
 * @param URI
 * @param container
 */
function columnChart(URI, container) {
    "use strict";
    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);
    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);

}

/**
 *
 * @param URI
 * @param container
 */
function stackedColumnChart(URI, container) {
    "use strict";

    var colorData = true;
    var options = $.extend(true, {}, defaultChartOptions);

    options.stacked = true;
    options.scales.xAxes[0].stacked = true;
    options.scales.yAxes[0].stacked = true;

    var chartType = 'bar';

    drawAChart(URI, container, chartType, options, colorData);
}

/**
 *
 * @param URI
 * @param container
 */
function pieChart(URI, container) {
    "use strict";

    var colorData = false;
    var options = $.extend(true, {}, defaultPieOptions);
    var chartType = 'pie';

    drawAChart(URI, container, chartType, options, colorData);

}

/**
 * @param URI
 * @param container
 * @param chartType
 * @param options
 * @param colorData
 * @param today
 */
function drawAChart(URI, container, chartType, options, colorData, today) {
    var containerObj = $('#' + container);
    if (containerObj.length === 0) {
        return;
    }

    $.getJSON(URI).done(function (data) {
        containerObj.removeClass('general-chart-error');
        if (data.labels.length === 0) {
            // remove the chart container + parent
            var holder = $('#' + container).parent().parent();
            if (holder.hasClass('box') || holder.hasClass('box-body')) {
                // find box-body:
                var boxBody;
                if (!holder.hasClass('box-body')) {
                    boxBody = holder.find('.box-body');
                } else {
                    boxBody = holder;
                }
                boxBody.empty().append($('<p>').append($('<em>').text(noDataForChart)));
            }
            return;
        }

        if (colorData) {
            data = colorizeData(data);
        }

        if (allCharts.hasOwnProperty(container)) {
            allCharts[container].data.datasets = data.datasets;
            allCharts[container].data.labels = data.labels;
            allCharts[container].update();
        } else {
            // new chart!
            var ctx = document.getElementById(container).getContext("2d");
            var chartOpts = {
                type: chartType,
                data: data,
                options: options,
                lineAtIndex: []
            };
            if (today >= 0) {
                chartOpts.lineAtIndex.push(today - 1);
            }
            allCharts[container] = new Chart(ctx, chartOpts);
        }

    }).fail(function () {
        $('#' + container).addClass('general-chart-error');
    });
}
<|endoftext|>


<commit_before>
/*
  Rolf Niepraschk (Rolf.Niepraschk@gmx.de)
  Inspired by https://github.com/nlf/node-github-hook
*/

var Http = require('http');
var Url = require('url');
var Fs = require('fs');
var execFile = require('child_process').execFile;
var Path = require('path');
var Os = require('os');
var Tmp = require('temp'); Tmp.track();
var Util = require('util');
var inspect = Util.inspect;
var isArray = Util.isArray;

var GitLabHook = function(options, callback) {
  if (!(this instanceof GitLabHook)) return new GitLabHook(options, callback);
  options = options || {};
  this.configFile = options.configFile || 'gitlabhook.conf';
  this.configPathes = options.configPathes ||
    ['/etc/gitlabhook/', '/usr/local/etc/gitlabhook/', '.'];
  this.port = options.port || 3420;
  this.host = options.host || '0.0.0.0';
  this.cmdshell = options.cmdshell || '/bin/sh';
  this.keep = (typeof options.keep === 'undefined') ? false : options.keep;
  this.logger = options.logger || { info: function(){}, error: function(){} };
  this.callback = callback;

  var active = false, tasks;

  if (typeof callback == 'function') {
    active = true;
  } else {
    cfg = readConfigFile(this.configPathes, this.configFile);
    if (cfg) {
      this.logger.info('loading config file: ' + this.configFile);
      this.logger.info('config file:\n' + Util.inspect(cfg));
      for (var i in cfg) options[i] = cfg[i];
      tasks = options.tasks;
      if (typeof tasks == 'object' && Object.keys(tasks).length) {
        this.tasks = tasks;
        active = true;
      }
    } else {
      this.logger.error("can't read config file: ", this.configFile);
    }
  }

  this.logger.info('self: ' + inspect(this) + '\n');

  if (active) this.server = Http.createServer(serverHandler.bind(this));
};

GitLabHook.prototype.listen = function(callback) {
  var self = this;
  if (typeof self.server !== 'undefined') {
    self.server.listen(self.port, self.host, function () {
      self.logger.info(Util.format(
        'listening for github events on %s:%d', self.host, self.port));
      if (typeof callback === 'function') callback();
    });
  } else {
    self.logger.info('server disabled');
  }
};

function readConfigFile(pathes, file) {
  var fname, ret = false;
  for (var i=0;i<pathes.length;i++) {
    fname = Path.join(pathes[i], file);
    try {
      var data = Fs.readFileSync(fname, 'utf-8');
      ret = parse(data);
      break;
    } catch(err) {
    }
  }
  return ret;
}

function parse(data) {
    var result;
    try {
        result = JSON.parse(data);
    } catch (e) {
        result = false;
    }
    return result;
}

function reply(statusCode, res) {
  var headers = {
    'Content-Length': 0
  };
  res.writeHead(statusCode, headers);
  res.end();
}

function executeShellCmds(self, address, data) {
  var repo = data.repository.name;
  var a = data.repository.url.split(/[@:]/);
  var httpUrl = 'http://' + a[1] + ((a[3]) ? ':' + a[2] : '') +
    '/' + a[a.length-1];
  var lastCommit = data.commits[data.commits.length-1];
  var map = {
    '%r': repo,
    '%g': data.repository.url,
    '%h': httpUrl,
    '%u': data.user_name,
    '%b': data.ref,
    '%i': lastCommit.id,
    '%t': lastCommit.timestamp,
    '%m': lastCommit.message,
    '%s': address
  };

  function execute(path, idx) {
    if (idx == cmds.length) {
      self.logger.info('Remove working directory: ' + self.path);
      Tmp.cleanup();
      return;
    }
    var fname = Path.join(path, 'task-' + pad(idx, 3));
    Fs.writeFile(fname, cmds[idx], function (err) {
      if (err) {
        self.logger.error('File creation error: ' + err);
        return;
      }
      self.logger.info('File created: ' + fname);
      execFile(self.cmdshell, [ fname ], { cwd:path, env:process.env },
        function (err, stdout, stderr) {
        if (err) {
          self.logger.error('Exec error: ' + err);
        } else {
          self.logger.info('Executed: ' + self.cmdshell + ' ' + fname);
          process.stdout.write(stdout);
        }
        process.stderr.write(stderr);
        execute(path, ++idx);
      });
    });
  }

  var cmds = getCmds(self.tasks, map, repo);

  if (cmds.length > 0) {

    self.logger.info('cmds: ' + inspect(cmds) + '\n');

    Tmp.mkdir({dir:Os.tmpDir(), prefix:'gitlabhook.'}, function(err, path) {
      if (err) {
        self.logger.error(err);
        return;
      }
      self.path = path;
      self.logger.info('Tempdir: ' + path);
      var i = 0;
      execute(path, i);
    });

  } else {
    self.logger.info('No related commands for repository "' + repo + '"');
  }
}

function serverHandler(req, res) {
  var self = this;
  var url = Url.parse(req.url, true);
  var buffer = [];
  var bufferLength = 0;
  var failed = false;
  var remoteAddress = req.ip || req.socket.remoteAddress ||
    req.socket.socket.remoteAddress;

  req.on('data', function (chunk) {
    if (failed) return;
    buffer.push(chunk);
    bufferLength += chunk.length;
  });

  req.on('end', function (chunk) {
    if (failed) return;
    var data;

    if (chunk) {
      buffer.push(chunk);
      bufferLength += chunk.length;
    }

    self.logger.info(Util.format('received %d bytes from %s\n\n', bufferLength,
      remoteAddress));

    data = Buffer.concat(buffer, bufferLength).toString();
    data = parse(data);

    // invalid json
    if (!data || !data.repository || !data.repository.name) {
       self.logger.error(Util.format('received invalid data from %s, returning 400\n\n',
         remoteAddress));
      return reply(400, res);
    }

    var repo = data.repository.name;

    reply(200, res);

    self.logger.info(Util.format('got event on %s:%s from %s\n\n', repo, data.ref,
      remoteAddress));
    self.logger.info(Util.inspect(data, { showHidden: true, depth: 10 }) + '\n\n');

    if (typeof self.callback == 'function') {
      self.callback(data);
    } else {
      executeShellCmds(self, remoteAddress, data);
    }

  });

  // 405 if the method is wrong
  if (req.method !== 'POST') {
      self.logger.error(Util.format('got invalid method from %s, returning 405',
        remoteAddress));
      failed = true;
      return reply(405, res);
  }

}

function getCmds(tasks, map, repo) {
  var ret = [], x = [];
  if (tasks.hasOwnProperty('*')) x.push(tasks['*']);
  if (tasks.hasOwnProperty(repo)) x.push(tasks[repo]);
  for (var i=0; i<x.length; i++) {
    var cmdStr = (isArray(x[i])) ? x[i].join('\n') : x[i];
    for (var j in map) cmdStr = cmdStr.replace(new RegExp(j, 'g'), map[j]);
    ret.push(cmdStr + '\n');
  }
  return ret;
}

function pad(n, width, z) {
  z = z || '0';
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

module.exports = GitLabHook;

<commit_msg>fixbug when receive a event like Issue events or Merge request events can’t read lastCommit will lead to a crash<commit_after>
/*
  Rolf Niepraschk (Rolf.Niepraschk@gmx.de)
  Inspired by https://github.com/nlf/node-github-hook
*/

var Http = require('http');
var Url = require('url');
var Fs = require('fs');
var execFile = require('child_process').execFile;
var Path = require('path');
var Os = require('os');
var Tmp = require('temp'); Tmp.track();
var Util = require('util');
var inspect = Util.inspect;
var isArray = Util.isArray;

var GitLabHook = function(options, callback) {
  if (!(this instanceof GitLabHook)) return new GitLabHook(options, callback);
  options = options || {};
  this.configFile = options.configFile || 'gitlabhook.conf';
  this.configPathes = options.configPathes ||
    ['/etc/gitlabhook/', '/usr/local/etc/gitlabhook/', '.'];
  this.port = options.port || 3420;
  this.host = options.host || '0.0.0.0';
  this.cmdshell = options.cmdshell || '/bin/sh';
  this.keep = (typeof options.keep === 'undefined') ? false : options.keep;
  this.logger = options.logger || { info: function(){}, error: function(){} };
  this.callback = callback;

  var active = false, tasks;

  if (typeof callback == 'function') {
    active = true;
  } else {
    cfg = readConfigFile(this.configPathes, this.configFile);
    if (cfg) {
      this.logger.info('loading config file: ' + this.configFile);
      this.logger.info('config file:\n' + Util.inspect(cfg));
      for (var i in cfg) options[i] = cfg[i];
      tasks = options.tasks;
      if (typeof tasks == 'object' && Object.keys(tasks).length) {
        this.tasks = tasks;
        active = true;
      }
    } else {
      this.logger.error("can't read config file: ", this.configFile);
    }
  }

  this.logger.info('self: ' + inspect(this) + '\n');

  if (active) this.server = Http.createServer(serverHandler.bind(this));
};

GitLabHook.prototype.listen = function(callback) {
  var self = this;
  if (typeof self.server !== 'undefined') {
    self.server.listen(self.port, self.host, function () {
      self.logger.info(Util.format(
        'listening for github events on %s:%d', self.host, self.port));
      if (typeof callback === 'function') callback();
    });
  } else {
    self.logger.info('server disabled');
  }
};

function readConfigFile(pathes, file) {
  var fname, ret = false;
  for (var i=0;i<pathes.length;i++) {
    fname = Path.join(pathes[i], file);
    try {
      var data = Fs.readFileSync(fname, 'utf-8');
      ret = parse(data);
      break;
    } catch(err) {
    }
  }
  return ret;
}

function parse(data) {
    var result;
    try {
        result = JSON.parse(data);
    } catch (e) {
        result = false;
    }
    return result;
}

function reply(statusCode, res) {
  var headers = {
    'Content-Length': 0
  };
  res.writeHead(statusCode, headers);
  res.end();
}

function executeShellCmds(self, address, data) {
  var repo = data.repository.name;
  var a = data.repository.url.split(/[@:]/);
  var httpUrl = 'http://' + a[1] + ((a[3]) ? ':' + a[2] : '') +
    '/' + a[a.length-1];
  if(data.commits.length == 0)
  {
  	  var map = false;
  }
  else
  {
	  var lastCommit = data.commits[data.commits.length-1];
	  var map = {
	    '%r': repo,
	    '%g': data.repository.url,
	    '%h': httpUrl,
	    '%u': data.user_name,
	    '%b': data.ref,
	    '%i': lastCommit.id,
	    '%t': lastCommit.timestamp,
	    '%m': lastCommit.message,
	    '%s': address
	  };
  }

  function execute(path, idx) {
    if (idx == cmds.length) {
      self.logger.info('Remove working directory: ' + self.path);
      Tmp.cleanup();
      return;
    }
    var fname = Path.join(path, 'task-' + pad(idx, 3));
    Fs.writeFile(fname, cmds[idx], function (err) {
      if (err) {
        self.logger.error('File creation error: ' + err);
        return;
      }
      self.logger.info('File created: ' + fname);
      execFile(self.cmdshell, [ fname ], { cwd:path, env:process.env },
        function (err, stdout, stderr) {
        if (err) {
          self.logger.error('Exec error: ' + err);
        } else {
          self.logger.info('Executed: ' + self.cmdshell + ' ' + fname);
          process.stdout.write(stdout);
        }
        process.stderr.write(stderr);
        execute(path, ++idx);
      });
    });
  }

  var cmds = getCmds(self.tasks, map, repo);

  if (cmds.length > 0) {

    self.logger.info('cmds: ' + inspect(cmds) + '\n');

    Tmp.mkdir({dir:Os.tmpDir(), prefix:'gitlabhook.'}, function(err, path) {
      if (err) {
        self.logger.error(err);
        return;
      }
      self.path = path;
      self.logger.info('Tempdir: ' + path);
      var i = 0;
      execute(path, i);
    });

  } else {
    self.logger.info('No related commands for repository "' + repo + '"');
  }
}

function serverHandler(req, res) {
  var self = this;
  var url = Url.parse(req.url, true);
  var buffer = [];
  var bufferLength = 0;
  var failed = false;
  var remoteAddress = req.ip || req.socket.remoteAddress ||
    req.socket.socket.remoteAddress;

  req.on('data', function (chunk) {
    if (failed) return;
    buffer.push(chunk);
    bufferLength += chunk.length;
  });

  req.on('end', function (chunk) {
    if (failed) return;
    var data;

    if (chunk) {
      buffer.push(chunk);
      bufferLength += chunk.length;
    }

    self.logger.info(Util.format('received %d bytes from %s\n\n', bufferLength,
      remoteAddress));

    data = Buffer.concat(buffer, bufferLength).toString();
    data = parse(data);

    // invalid json
    if (!data || !data.repository || !data.repository.name) {
       self.logger.error(Util.format('received invalid data from %s, returning 400\n\n',
         remoteAddress));
      return reply(400, res);
    }

    var repo = data.repository.name;

    reply(200, res);

    self.logger.info(Util.format('got event on %s:%s from %s\n\n', repo, data.ref,
      remoteAddress));
    self.logger.info(Util.inspect(data, { showHidden: true, depth: 10 }) + '\n\n');

    if (typeof self.callback == 'function') {
      self.callback(data);
    } else {
      executeShellCmds(self, remoteAddress, data);
    }

  });

  // 405 if the method is wrong
  if (req.method !== 'POST') {
      self.logger.error(Util.format('got invalid method from %s, returning 405',
        remoteAddress));
      failed = true;
      return reply(405, res);
  }

}

function getCmds(tasks, map, repo) {
  var ret = [], x = [];
  if (tasks.hasOwnProperty('*')) x.push(tasks['*']);
  if (tasks.hasOwnProperty(repo)) x.push(tasks[repo]);
  for (var i=0; i<x.length; i++) {
    var cmdStr = (isArray(x[i])) ? x[i].join('\n') : x[i];
    if(map != false)
    {
	    for (var j in map) cmdStr = cmdStr.replace(new RegExp(j, 'g'), map[j]);
    }
    ret.push(cmdStr + '\n');
  }
  return ret;
}

function pad(n, width, z) {
  z = z || '0';
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

module.exports = GitLabHook;

<|endoftext|>


<commit_before>const crypto = require('crypto');
const bodyParser = require('body-parser');
const helmet = require('helmet');
const uaparser = require('ua-parser-js');
const storage = require('../storage');
const config = require('../config');
const auth = require('../middleware/auth');
const language = require('../middleware/language');
const pages = require('./pages');
const filelist = require('./filelist');
const clientConstants = require('../clientConstants');

const IS_DEV = config.env === 'development';
const ID_REGEX = '([0-9a-fA-F]{10,16})';

module.exports = function(app) {
  app.set('trust proxy', true);
  app.use(helmet());
  app.use(
    helmet.hsts({
      maxAge: 31536000,
      force: !IS_DEV
    })
  );
  app.use(function(req, res, next) {
    req.ua = uaparser(req.header('user-agent'));
    next();
  });
  app.use(function(req, res, next) {
    req.cspNonce = crypto.randomBytes(16).toString('hex');
    next();
  });
  if (!IS_DEV) {
    app.use(
      helmet.contentSecurityPolicy({
        directives: {
          defaultSrc: ["'self'"],
          connectSrc: [
            "'self'",
            'wss://*.dev.lcip.org',
            'wss://*.send.nonprod.cloudops.mozgcp.net',
            'wss://send.firefox.com',
            'https://*.dev.lcip.org',
            'https://accounts.firefox.com',
            'https://*.accounts.firefox.com',
            'https://sentry.prod.mozaws.net'
          ],
          imgSrc: [
            "'self'",
            'https://*.dev.lcip.org',
            'https://firefoxusercontent.com',
            'https://secure.gravatar.com'
          ],
          scriptSrc: [
            "'self'",
            function(req) {
              return `'nonce-${req.cspNonce}'`;
            }
          ],
          formAction: ["'none'"],
          frameAncestors: ["'none'"],
          objectSrc: ["'none'"],
          reportUri: '/__cspreport__'
        }
      })
    );
  }
  app.use(function(req, res, next) {
    res.set('Pragma', 'no-cache');
    res.set('Cache-Control', 'no-cache');
    next();
  });
  app.use(bodyParser.json());
  app.use(bodyParser.text());
  app.get('/', language, pages.index);
  app.get('/config', function(req, res) {
    res.json(clientConstants);
  });
  app.get('/error', language, pages.blank);
  app.get('/oauth', language, pages.blank);
  app.get('/legal', language, pages.legal);
  app.get('/login', language, pages.index);
  app.get('/app.webmanifest', language, require('./webmanifest'));
  app.get(`/download/:id${ID_REGEX}`, language, pages.download);
  app.get('/unsupported/:reason', language, pages.unsupported);
  app.get(`/api/download/:id${ID_REGEX}`, auth.hmac, require('./download'));
  app.get(
    `/api/download/blob/:id${ID_REGEX}`,
    auth.hmac,
    require('./download')
  );
  app.get(`/api/exists/:id${ID_REGEX}`, require('./exists'));
  app.get(`/api/metadata/:id${ID_REGEX}`, auth.hmac, require('./metadata'));
  app.get('/api/filelist/:id([\\w-]{16})', auth.fxa, filelist.get);
  app.post('/api/filelist/:id([\\w-]{16})', auth.fxa, filelist.post);
  app.post('/api/upload', auth.fxa, require('./upload'));
  app.post(`/api/delete/:id${ID_REGEX}`, auth.owner, require('./delete'));
  app.post(`/api/password/:id${ID_REGEX}`, auth.owner, require('./password'));
  app.post(
    `/api/params/:id${ID_REGEX}`,
    auth.owner,
    auth.fxa,
    require('./params')
  );
  app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));
  app.post('/api/metrics', require('./metrics'));
  app.get('/__version__', function(req, res) {
    // eslint-disable-next-line node/no-missing-require
    res.sendFile(require.resolve('../../dist/version.json'));
  });

  app.get('/__lbheartbeat__', function(req, res) {
    res.sendStatus(200);
  });

  app.get('/__heartbeat__', async (req, res) => {
    try {
      await storage.ping();
      res.sendStatus(200);
    } catch (e) {
      res.sendStatus(500);
    }
  });
};
<commit_msg>no-cache harder<commit_after>const crypto = require('crypto');
const bodyParser = require('body-parser');
const helmet = require('helmet');
const uaparser = require('ua-parser-js');
const storage = require('../storage');
const config = require('../config');
const auth = require('../middleware/auth');
const language = require('../middleware/language');
const pages = require('./pages');
const filelist = require('./filelist');
const clientConstants = require('../clientConstants');

const IS_DEV = config.env === 'development';
const ID_REGEX = '([0-9a-fA-F]{10,16})';

module.exports = function(app) {
  app.set('trust proxy', true);
  app.use(helmet());
  app.use(
    helmet.hsts({
      maxAge: 31536000,
      force: !IS_DEV
    })
  );
  app.use(function(req, res, next) {
    req.ua = uaparser(req.header('user-agent'));
    next();
  });
  app.use(function(req, res, next) {
    req.cspNonce = crypto.randomBytes(16).toString('hex');
    next();
  });
  if (!IS_DEV) {
    app.use(
      helmet.contentSecurityPolicy({
        directives: {
          defaultSrc: ["'self'"],
          connectSrc: [
            "'self'",
            'wss://*.dev.lcip.org',
            'wss://*.send.nonprod.cloudops.mozgcp.net',
            'wss://send.firefox.com',
            'https://*.dev.lcip.org',
            'https://accounts.firefox.com',
            'https://*.accounts.firefox.com',
            'https://sentry.prod.mozaws.net'
          ],
          imgSrc: [
            "'self'",
            'https://*.dev.lcip.org',
            'https://firefoxusercontent.com',
            'https://secure.gravatar.com'
          ],
          scriptSrc: [
            "'self'",
            function(req) {
              return `'nonce-${req.cspNonce}'`;
            }
          ],
          formAction: ["'none'"],
          frameAncestors: ["'none'"],
          objectSrc: ["'none'"],
          reportUri: '/__cspreport__'
        }
      })
    );
  }
  app.use(function(req, res, next) {
    res.set('Pragma', 'no-cache');
    res.set(
      'Cache-Control',
      'private, no-cache, no-store, must-revalidate, max-age=0'
    );
    next();
  });
  app.use(bodyParser.json());
  app.use(bodyParser.text());
  app.get('/', language, pages.index);
  app.get('/config', function(req, res) {
    res.json(clientConstants);
  });
  app.get('/error', language, pages.blank);
  app.get('/oauth', language, pages.blank);
  app.get('/legal', language, pages.legal);
  app.get('/login', language, pages.index);
  app.get('/app.webmanifest', language, require('./webmanifest'));
  app.get(`/download/:id${ID_REGEX}`, language, pages.download);
  app.get('/unsupported/:reason', language, pages.unsupported);
  app.get(`/api/download/:id${ID_REGEX}`, auth.hmac, require('./download'));
  app.get(
    `/api/download/blob/:id${ID_REGEX}`,
    auth.hmac,
    require('./download')
  );
  app.get(`/api/exists/:id${ID_REGEX}`, require('./exists'));
  app.get(`/api/metadata/:id${ID_REGEX}`, auth.hmac, require('./metadata'));
  app.get('/api/filelist/:id([\\w-]{16})', auth.fxa, filelist.get);
  app.post('/api/filelist/:id([\\w-]{16})', auth.fxa, filelist.post);
  app.post('/api/upload', auth.fxa, require('./upload'));
  app.post(`/api/delete/:id${ID_REGEX}`, auth.owner, require('./delete'));
  app.post(`/api/password/:id${ID_REGEX}`, auth.owner, require('./password'));
  app.post(
    `/api/params/:id${ID_REGEX}`,
    auth.owner,
    auth.fxa,
    require('./params')
  );
  app.post(`/api/info/:id${ID_REGEX}`, auth.owner, require('./info'));
  app.post('/api/metrics', require('./metrics'));
  app.get('/__version__', function(req, res) {
    // eslint-disable-next-line node/no-missing-require
    res.sendFile(require.resolve('../../dist/version.json'));
  });

  app.get('/__lbheartbeat__', function(req, res) {
    res.sendStatus(200);
  });

  app.get('/__heartbeat__', async (req, res) => {
    try {
      await storage.ping();
      res.sendStatus(200);
    } catch (e) {
      res.sendStatus(500);
    }
  });
};
<|endoftext|>


<commit_before>$(document).ready(() => {
    //flowtype
    $('.main__ritem-header h3').flowtype({
        minimum: 500,
        maximum: 1200,
        minFont: 20,
        maxFont: 40,
        fontRatio: 30
    });

    $('#showall').flowtype({
        minimum: 500,
        maximum: 1200,
        minFont: 12,
        maxFont: 40,
        fontRatio: 30
    });

    const animeName = ['Naruto', 'One Piece', 'Fairy Tail', 'Bleach', 'One Punch Man', 'Dragon Ball Super', 'Pokemon', 'Black Rock Shooter', 'Sword Art Online', '5cm/s', 'Date A Live', 'Attack on the Titan', 'Bikini Warriors', 'Tokyo Ghoul', 'Fairy Tail', 'Hunter x Hunter', 'Digimon', 'Gumball', 'Stand By Me', 'Adventure Time', 'Inu Yasha', 'Masou Gakuen HxH', 'Overload', 'God Eater', 'Ajin', 'Gurren Lagann', 'Danmachi', 'Gintama'];

    setInterval(function () {
        let random = Math.floor(Math.random() * 28) + 1;
        $('.header').css('background-image', 'url("public/img/' + random + '.jpg")');
        $('.header__album h2').html(animeName[random - 1]);
    }, 5000);

    $(function () {
        $('a[href*="#"]:not([href="#"])').click(function () {
            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
                var target = $(this.hash);
                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
                if (target.length) {
                    $('html, body').animate({
                        scrollTop: target.offset().top
                    }, 1000);
                    return false;
                }
            }
        });
    });
})
<commit_msg>fix top slider<commit_after>$(document).ready(() => {
    //flowtype
    $('.main__ritem-header h3').flowtype({
        minimum: 500,
        maximum: 1200,
        minFont: 20,
        maxFont: 40,
        fontRatio: 30
    });

    $('#showall').flowtype({
        minimum: 500,
        maximum: 1200,
        minFont: 12,
        maxFont: 40,
        fontRatio: 30
    });

    const animeName = ['Naruto', 'One Piece', 'Fairy Tail', 'Bleach', 'One Punch Man', 'Dragon Ball Super', 'Pokemon', 'Black Rock Shooter', 'Sword Art Online', '5cm/s', 'Date A Live', 'Attack on the Titan', 'Bikini Warriors', 'Tokyo Ghoul', 'Fairy Tail', 'Hunter x Hunter', 'Digimon', 'Gumball', 'Stand By Me', 'Adventure Time', 'Inu Yasha', 'Masou Gakuen HxH', 'Overload', 'God Eater', 'Ajin', 'Gurren Lagann', 'Danmachi', 'Gintama'];

    setInterval(function () {
        let random = Math.floor(Math.random() * 28) + 1;
        $('.header').css('background-image', 'url("http://localhost/webmovie.dev/public/img/' + random + '.jpg")');
        $('.header__album h2').html(animeName[random - 1]);
    }, 5000);

    $(function () {
        $('a[href*="#"]:not([href="#"])').click(function () {
            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
                var target = $(this.hash);
                target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
                if (target.length) {
                    $('html, body').animate({
                        scrollTop: target.offset().top
                    }, 1000);
                    return false;
                }
            }
        });
    });
})
<|endoftext|>


<commit_before>var express     = require("express");
var router      = express.Router();
var blog        = require("../models/blog");

/**
 * Render Login Page
 * if auth redirect to blogs
 */
router.get("/login", function authenticatedOrNot(req, res, next) {
    if(req.isAuthenticated()) {
        res.redirect("/admin#/blogs");
    } else {
        next();
    }}, function(req, res) {
    res.render("admin/login", { message: req.flash('error') });
});

/**
 * Logout
 */
router.get("/logout", function(req, res) {
    req.logout();

    res.redirect("/login");
});

/**
 * Render Main Page
 */
router.get("/", function(req, res) {
    blog.find(function(err, blogs) {
        if(err) throw(err);

        res.render("client/index", { title: "Dimitri Mikadze", blogs: blogs });
    });
});

/**
 * Render blog by url param id
 */
router.get("/blog/:name/:id", function(req, res) {

    var name = req.params.name;
    var id = req.params.id;

    blog.findById(id, function(req, blog) {
       res.render("client/blog/blog", {
           title: name.replace("-", " "),
           blog: blog
       })
    });
});

// ===========================================
//                  Demos
// ===========================================

router.get("/demos/vanilla-slideshow", function(req, res) {
    res.render("demos/vanilla-slideshow.html");
});

/**
 * Download vanilla slideshow
 */
router.get("/download-vanilla-slideshow", function(req, res) {
    res.download("../client/views/demos/vanilla-slideshow.rar");
});

module.exports = router;<commit_msg>update<commit_after>var express     = require("express");
var router      = express.Router();
var blog        = require("../models/blog");

/**
 * Render Login Page
 * if auth redirect to blogs
 */
router.get("/login", function authenticatedOrNot(req, res, next) {
    if(req.isAuthenticated()) {
        res.redirect("/admin#/blogs");
    } else {
        next();
    }}, function(req, res) {
    res.render("admin/login", { message: req.flash('error') });
});

/**
 * Logout
 */
router.get("/logout", function(req, res) {
    req.logout();

    res.redirect("/login");
});

/**
 * Render Main Page
 */
router.get("/", function(req, res) {
    blog.find(function(err, blogs) {
        if(err) throw(err);

        res.render("client/index", {
            title: "Dimitri Mikadze",
            blogs: blogs,
            desc: "Dimitri Mikadze Personal Blog",
            url: "/"
        });
    });
});

/**
 * Render blog by url param id
 */
router.get("/blog/:name/:id", function(req, res) {

    var name = req.params.name;
    var id = req.params.id;

    blog.findById(id, function(req, blog) {
       res.render("client/blog/blog", {
           title: name.replace("-", " "),
           blog: blog,
           desc: blog.short_desc,
           url: "/blog/" + name + "/" + id
       })
    });
});

// ===========================================
//                  Demos
// ===========================================

router.get("/demos/vanilla-slideshow", function(req, res) {
    res.render("demos/vanilla-slideshow.html");
});

/**
 * Download vanilla slideshow
 */
router.get("/download-vanilla-slideshow", function(req, res) {
    res.download("../client/views/demos/vanilla-slideshow.rar");
});

module.exports = router;<|endoftext|>