diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a125f80 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +**/node_modules +.eslintrc.json +.gitignore +.npmignore +cloud-config.yaml +Dockerfile +run-dev-container \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..8ced7ba --- /dev/null +++ b/.npmignore @@ -0,0 +1,6 @@ +.dockerignore +.eslintrc.json +.gitignore +cloud-config.yaml +Dockerfile +run-dev-container \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fc0b398..7f3e924 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ FROM ubuntu:16.04 + # initialize .ssh directory RUN mkdir -p ~/.ssh \ && chmod 700 ~/.ssh \ @@ -23,9 +24,6 @@ RUN export DEBIAN_FRONTEND=noninteractive \ mysql-client \ mysql-server \ nginx \ - nodejs \ - nodejs-legacy \ - npm \ openssh-server \ postfix \ python \ @@ -38,8 +36,12 @@ RUN export DEBIAN_FRONTEND=noninteractive \ tmux \ vim \ && add-apt-repository -y ppa:ondrej/php \ - && apt-get update \ + && add-apt-repository ppa:certbot/certbot \ + && curl -sL https://deb.nodesource.com/setup_10.x | bash \ + # && apt-get update \ # above calls apt-get update && apt-get install -y --allow-unauthenticated --no-install-recommends \ + certbot python3-pyasn1 \ + nodejs \ php-apcu \ php5.6-cli \ php5.6-curl \ @@ -66,14 +68,19 @@ RUN service nginx stop \ # install Habitat client and packages for emergence -RUN curl -s https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh | sudo bash -RUN hab pkg install jarvus/sencha-cmd/5.1.3.61/20170606195324 jarvus/underscore \ +RUN curl -s https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh | bash +RUN hab pkg install jarvus/sencha-cmd/6.5.2.15 jarvus/underscore \ && hab pkg binlink jarvus/sencha-cmd sencha \ && hab pkg binlink jarvus/underscore underscore +# install helpful administrative commands +RUN npm install -g htpasswd + + # install emergence -RUN npm install -g emergence +COPY . /src +RUN npm install -g /src # setup and expose emergence diff --git a/bin/certbot-auth b/bin/certbot-auth new file mode 100755 index 0000000..40f7b6e --- /dev/null +++ b/bin/certbot-auth @@ -0,0 +1,36 @@ +#!/bin/bash + +log () { + echo "emergence-certbot-auth: $@" +} + +die () { + echo >&2 "emergence-certbot-auth: $@" + exit 1 +} + + +# check usage +[ -n "${CERTBOT_DOMAIN}" ] || die "required environment variable missing: \$CERTBOT_DOMAIN" +[ -n "${CERTBOT_VALIDATION}" ] || die "required environment variable missing: \$CERTBOT_VALIDATION" +[ -n "${CERTBOT_TOKEN}" ] || die "required environment variable missing: \$CERTBOT_TOKEN" + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + +# resolve site handle for domain +SITE_HANDLE="$(${DIR}/resolve-site ${CERTBOT_DOMAIN})" +[ -n "${SITE_HANDLE}" ] || die "could not resolve domain '${CERTBOT_DOMAIN}' under /emergence/sites/*/site.json" + + +# write auth file +log "writing ${SITE_HANDLE}/${CERTBOT_TOKEN}" +echo "${CERTBOT_VALIDATION}" | "${DIR}/write-file" "${SITE_HANDLE}" "site-root/.well-known/acme-challenge/${CERTBOT_TOKEN}" || die "failed to write token to VFS" diff --git a/bin/certbot-cleanup b/bin/certbot-cleanup new file mode 100755 index 0000000..8984a7e --- /dev/null +++ b/bin/certbot-cleanup @@ -0,0 +1,35 @@ +#!/bin/bash + +log () { + echo "emergence-certbot-cleanup: $@" +} + +die () { + echo >&2 "emergence-certbot-cleanup: $@" + exit 1 +} + + +# check usage +[ -n "${CERTBOT_DOMAIN}" ] || die "required environment variable missing: \$CERTBOT_DOMAIN" +[ -n "${CERTBOT_TOKEN}" ] || die "required environment variable missing: \$CERTBOT_TOKEN" + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + +# resolve site handle for domain +SITE_HANDLE="$(${DIR}/resolve-site ${CERTBOT_DOMAIN})" +[ -n "${SITE_HANDLE}" ] || die "could not resolve domain '${CERTBOT_DOMAIN}' under /emergence/sites/*/site.json" + + +# delete auth file +log "deleting ${SITE_HANDLE}/${CERTBOT_TOKEN}" +"${DIR}/delete-file" "${SITE_HANDLE}" "site-root/.well-known/acme-challenge/${CERTBOT_TOKEN}" || die "failed to delete token from VFS" diff --git a/bin/delete-file b/bin/delete-file new file mode 100755 index 0000000..3765ee0 --- /dev/null +++ b/bin/delete-file @@ -0,0 +1,44 @@ +#!/bin/bash + +die () { + echo >&2 "$@" + exit 1 +} + + +# check usage +[ -n "$1" ] && [ -n "$2" ] || die "Usage: emergence-delete-file " + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + +# execute php script +cat <<'END_OF_PHP' | "${DIR}/shell" "$1" --stdin "$2" +delete(); + exit(0); +} catch (Exception $e) { + error_log('emergence-delete-file: failed to delete file from VFS: '.$e->getMessage()); + exit(1); +} + +END_OF_PHP + + diff --git a/bin/read-file b/bin/read-file new file mode 100755 index 0000000..76c8b25 --- /dev/null +++ b/bin/read-file @@ -0,0 +1,39 @@ +#!/bin/bash + +die () { + echo >&2 "$@" + exit 1 +} + + +# check usage +[ -n "$1" ] && [ -n "$2" ] || die "Usage: emergence-read-file " + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + +# execute php script +cat <<'END_OF_PHP' | "${DIR}/shell" "$1" --stdin "$2" +RealPath); +exit(0); + +END_OF_PHP + + diff --git a/bin/resolve-site b/bin/resolve-site new file mode 100755 index 0000000..1c8be6e --- /dev/null +++ b/bin/resolve-site @@ -0,0 +1,45 @@ +#!/bin/bash + +die () { + echo >&2 "emergence-resolve-site: $@" + exit 1 +} + + +# check usage +[ -n "$1" ] || die "Usage: emergence-resolve-site " +[ -d "/emergence/sites" ] || die "/emergence/sites not found" + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + +# determine path to underscore +UNDERSCORE="$DIR/../node_modules/.bin/underscore" + + +# search sites +pushd /emergence/sites > /dev/null +for SITE_DIR in `find . -maxdepth 1 ! -path . -type d`; do + SITE_HANDLE="$(basename ${SITE_DIR})" + SITE_HOSTNAMES="$(sudo cat ${SITE_DIR}/site.json | $UNDERSCORE process '(data.hostnames||[]).concat([data.primary_hostname]).filter(x=>x)' --outfmt text)" + + for SITE_HOSTNAME in $SITE_HOSTNAMES; do + if [[ "${1}" == $SITE_HOSTNAME ]]; then # NOT MATCHING WILDCARD + echo "${SITE_HANDLE}" + exit 0 + fi + done +done +popd > /dev/null + + +# return failure if no match found +exit 1 diff --git a/bin/shell b/bin/shell index 588c56d..44810ac 100755 --- a/bin/shell +++ b/bin/shell @@ -57,6 +57,10 @@ fi # execute interactive shell TERM=$TERM sudo -E -u www-data -g www-data php -d auto_prepend_file=$autoPrependScript -d apc.enable_cli=on -d memory_limit=-1 $INPUT_ARGS +SCRIPT_STATUS=$? # clean up rm $autoPrependScript; + +# relay exit status of php script +exit $SCRIPT_STATUS diff --git a/bin/write-file b/bin/write-file new file mode 100755 index 0000000..f984791 --- /dev/null +++ b/bin/write-file @@ -0,0 +1,58 @@ +#!/bin/bash + +die () { + echo >&2 "$@" + exit 1 +} + + +# check usage +[ -n "$1" ] && [ -n "$2" ] || die "Usage: emergence-write-file [host-file-path]" + + +# determine location of this script +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + + + + +# read stdin to tmp +if [ -z "${3}" ]; then + # determine path to underscore + UNDERSCORE="$DIR/../node_modules/.bin/underscore" + + # read application group name + APP_GROUP="$(sudo cat /emergence/config.json | $UNDERSCORE extract --outfmt text group)" + INPUT_FILE="$(mktemp)" + chgrp "${APP_GROUP}" "${INPUT_FILE}" + chmod g+r "${INPUT_FILE}" + + cat - > "${INPUT_FILE}" +elif [ ! -f "${3}" ]; then + die "Input file ${3} not found" +else + INPUT_FILE="${3}" +fi + + +# execute php script +cat <<'END_OF_PHP' | exec "${DIR}/shell" "${1}" --stdin "${2}" "${INPUT_FILE}" +getMessage()); + exit(1); +} + +END_OF_PHP + + diff --git a/kernel-lib/server.js b/kernel-lib/server.js index 1d715a8..14930fa 100644 --- a/kernel-lib/server.js +++ b/kernel-lib/server.js @@ -7,7 +7,8 @@ var http = require('http'), url = require('url'), static = require('node-static'), events = require('events'), - nodeCleanup = require('node-cleanup'); + nodeCleanup = require('node-cleanup'), + httpAuth = require('http-auth'); exports.createServer = function (paths, options) { @@ -41,9 +42,9 @@ util.inherits(Server, events.EventEmitter); Server.prototype.start = function () { // create authenticator - this.httpAuth = require('http-auth')({ - authRealm: 'Emergence Node Management', - authFile: '/emergence/admins.htpasswd' + const basicAuth = httpAuth.basic({ + realm: 'Emergence Node Management', + file: '/emergence/admins.htpasswd' }); // create static fileserver @@ -58,7 +59,7 @@ Server.prototype.start = function () { this.webProtocol = 'https'; } else { - this.webServer = http.createServer(this.handleWebRequest.bind(this)).listen(this.options.port, this.options.host); + this.webServer = http.createServer(basicAuth, this.handleRequest.bind(this)).listen(this.options.port, this.options.host); this.webProtocol = 'http'; } @@ -72,14 +73,6 @@ Server.prototype.start = function () { console.log('Management server listening on '+this.webProtocol+'://'+this.options.host+':'+this.options.port); }; -Server.prototype.handleWebRequest = function (request, response) { - var me = this; - - me.httpAuth.apply(request, response, function () { - me.handleRequest(request, response); - }); -}; - Server.prototype.handleRequest = function (request, response) { var me = this; diff --git a/kernel-lib/services/mysql.js b/kernel-lib/services/mysql.js index f835738..aebe8df 100644 --- a/kernel-lib/services/mysql.js +++ b/kernel-lib/services/mysql.js @@ -41,7 +41,7 @@ function MysqlService (name, controller) { // check binary version console.log(me.name+': detecting mysqld version...'); - versionMatch = shell.exec(me.options.execPath+' --version').output.match(/mysqld\s+Ver\s+(\d+(\.\d+)*)(-MariaDB)?/); + versionMatch = shell.exec(me.options.execPath+' --version').stdout.match(/mysqld\s+Ver\s+(\d+(\.\d+)*)(-MariaDB)?/); if (!versionMatch) { throw 'Failed to detect mysql version'; diff --git a/kernel-lib/sites.js b/kernel-lib/sites.js index 57b0810..5cb96ca 100644 --- a/kernel-lib/sites.js +++ b/kernel-lib/sites.js @@ -4,8 +4,8 @@ var _ = require('underscore'), path = require('path'), util = require('util'), events = require('events'), - posix = require('posix'), spawn = require('child_process').spawn, + shell = require('shelljs'), hostile = require('hostile'), phpShellScript = path.resolve(__dirname, '../bin/shell'); @@ -26,8 +26,8 @@ function Sites (config) { me.options = options || {}; me.options.sitesDir = me.options.sitesDir || '/emergence/sites'; me.options.localhost = me.options.localhost || '127.0.0.1'; - me.options.dataUID = me.options.dataUID || posix.getpwnam(config.user).uid; - me.options.dataGID = me.options.dataGID || posix.getgrnam(config.group).gid; + me.options.dataUID = parseInt(me.options.dataUID || shell.exec(`id -u ${config.user}`).stdout.trim(), 10); + me.options.dataGID = parseInt(me.options.dataGID || shell.exec(`getent group ${config.group}`).stdout.split(':')[2], 10); me.options.dataMode = me.options.dataMode || '775'; // create required directories diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e597869 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,904 @@ +{ + "name": "emergence", + "version": "1.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONSelect": { + "version": "0.4.0", + "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=", + "optional": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "apache-crypt": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz", + "integrity": "sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw=", + "requires": { + "unix-crypt-td-js": "^1.0.0" + } + }, + "apache-md5": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.2.tgz", + "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "coffee-script": { + "version": "1.12.7", + "integrity": "sha1-wF2uDLeVkdBbMHCoQzqYyaiczFM=", + "optional": true + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "hostile": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hostile/-/hostile-1.3.0.tgz", + "integrity": "sha1-bJnRSA+bQQGB0E3pLEG+P946C0c=", + "requires": { + "chalk": "^1.0.0", + "minimist": "^1.1.0", + "once": "^1.3.0", + "split": "^1.0.0", + "through": "^2.3.4" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, + "http-auth": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.2.3.tgz", + "integrity": "sha1-Y2hCtx1uHyyY26Ca9UQXof74thw=", + "requires": { + "apache-crypt": "^1.1.2", + "apache-md5": "^1.0.6", + "bcryptjs": "^2.3.0", + "uuid": "^3.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "msgpack": { + "version": "1.0.2", + "integrity": "sha1-kj4sXP+mXIQY6bIo0RJHk5acQpw=", + "optional": true, + "requires": { + "nan": "^2.0.9" + } + }, + "mysql2": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.5.tgz", + "integrity": "sha512-zedaOOyb3msuuZcJJnxIX/EGOpmljDG7B+UevRH5lqcv+yhy9eCwkArBz8/AO+/rlY3/oCsOdG8R5oD6k0hNfg==", + "requires": { + "denque": "^1.4.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.4.24", + "long": "^4.0.0", + "lru-cache": "^4.1.3", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.1" + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + } + }, + "nan": { + "version": "2.4.0", + "integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI=", + "optional": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-cleanup": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=" + }, + "node-phpfpm": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/node-phpfpm/-/node-phpfpm-1.0.1.tgz", + "integrity": "sha1-MGq4gTSbiQYy8N69SqPTQj0MU8Y=", + "requires": { + "fastcgi-client": "0.0.1", + "urlencode-for-php": "^1.0.2" + }, + "dependencies": { + "fastcgi-client": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/fastcgi-client/-/fastcgi-client-0.0.1.tgz", + "integrity": "sha1-EEbUL/LO4qmsA/6gRpWz73MRhhw=" + }, + "flat": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-1.6.1.tgz", + "integrity": "sha1-R2udu3DV6TQNu8A4veCEoglFkhw=", + "requires": { + "is-buffer": "~1.1.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "urlencode-for-php": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/urlencode-for-php/-/urlencode-for-php-1.0.4.tgz", + "integrity": "sha512-e4SU1jHM4v2Ld32pDkt6KBpmRVxHm6MMvfBVORipf8PZa/RMOj0yftmGJgD4o2NmcP97lZR037ugVq/0TmgZfA==", + "requires": { + "flat": "^1.6.0" + } + } + } + }, + "node-static": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", + "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", + "requires": { + "colors": ">=0.6.0", + "mime": "^1.2.9", + "optimist": ">=0.3.4" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + } + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", + "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "underscore-cli": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/underscore-cli/-/underscore-cli-0.2.19.tgz", + "integrity": "sha1-JNyWnJNvHQ7hHT51FKMtpJGS8JI=", + "requires": { + "JSONSelect": "*", + "coffee-script": "*", + "commander": "1.0.5", + "msgpack": "*", + "underscore": "1.8.3", + "underscore.string": "3.2.3" + }, + "dependencies": { + "commander": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/commander/-/commander-1.0.5.tgz", + "integrity": "sha1-RXKVu5duOI6d0NtS3kMz4knz2Iw=", + "requires": { + "keypress": "0.1.x" + } + }, + "keypress": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", + "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=" + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "underscore.string": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz", + "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=" + } + } + }, + "unix-crypt-td-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.0.0.tgz", + "integrity": "sha1-HAgkFQSBvHoB1J6Y8exmjYJBLzs=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json index ab9daca..bf72bfb 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,20 @@ { "name": "emergence", "preferGlobal": true, - "version": "1.0.7", + "version": "1.1.0", "license": "MIT", "dependencies": { - "hostile": "^1.0.2", - "http-auth": "1.2.7", - "mysql2": "^1.5.1", - "node-cleanup": "^2.1.2", - "node-phpfpm": "^1.0.1", - "node-static": "git+https://github.com/JarvusInnovations/node-static.git", - "posix": "^4.0.2", - "semver": "^5.1.0", - "shelljs": "^0.5.3", - "underscore": "1.3.x", - "underscore-cli": "^0.2.19", - "yargs": "^11.0.0" + "hostile": "^1.3.x", + "http-auth": "^3.2.x", + "mysql2": "^1.6.x", + "node-cleanup": "^2.1.x", + "node-phpfpm": "^1.0.x", + "node-static": "^0.7.x", + "semver": "^6.0.x", + "shelljs": "^0.8.x", + "underscore": "^1.9.x", + "underscore-cli": "^0.2.x", + "yargs": "^13.2.x" }, "bin": { "emergence-kernel": "./bin/kernel", @@ -24,7 +23,13 @@ "emergence-su": "./bin/su", "emergence-create-site": "./bin/create-site.sh", "emergence-mysql-shell": "./bin/mysql-shell", - "emergence-fire-event": "./bin/fire-event" + "emergence-fire-event": "./bin/fire-event", + "emergence-read-file": "./bin/read-file", + "emergence-write-file": "./bin/write-file", + "emergence-delete-file": "./bin/delete-file", + "emergence-resolve-site": "./bin/resolve-site", + "emergence-certbot-auth": "./bin/certbot-auth", + "emergence-certbot-cleanup": "./bin/certbot-cleanup" }, "repository": { "type": "git", diff --git a/php-bootstrap/lib/HttpProxy.class.php b/php-bootstrap/lib/HttpProxy.class.php index 638405b..be620e7 100644 --- a/php-bootstrap/lib/HttpProxy.class.php +++ b/php-bootstrap/lib/HttpProxy.class.php @@ -62,7 +62,7 @@ public static function relayRequest($options) } // get cookies - if (!isset($options['cookies'])) { + if (!isset($options['cookies']) && !empty($_SERVER['HTTP_COOKIE'])) { $options['cookies'] = $_SERVER['HTTP_COOKIE']; } diff --git a/php-bootstrap/lib/Site.class.php b/php-bootstrap/lib/Site.class.php index 43d129e..3775d25 100644 --- a/php-bootstrap/lib/Site.class.php +++ b/php-bootstrap/lib/Site.class.php @@ -194,43 +194,12 @@ public static function handleRequest() return Emergence::handleRequest(); } - // TEMPORARY: bypass routing for some scripts - // TODO: delete this - foreach (['develop', 'editor', 'app'] AS $bypassRoute) { - if (static::$pathStack[0] == $bypassRoute) { - static::$resolvedPath = [array_shift(static::$pathStack)]; - return static::executeScript(static::resolvePath("site-root/$bypassRoute.php")); - } - } - - // TODO: delete this too - if (static::$pathStack[0] == 'site-admin') { - if (count(static::$pathStack) > 1) { - static::$resolvedPath = [array_shift(static::$pathStack), array_shift(static::$pathStack)]; - return static::executeScript(static::resolvePath("site-root/site-admin/".static::$resolvedPath[1].".php")); - } else { - static::$resolvedPath = [array_shift(static::$pathStack)]; - return static::executeScript(static::resolvePath("site-root/site-admin/_index.php")); - } - } - - // header('Content-Type: text/plain'); - - // printf("Getting result for pathStack: %s\n", implode('/', static::$pathStack)); - // resolve request path against site-root filesystem $pathResult = static::getRequestPathResult(static::$pathStack); static::$resolvedNode = $pathResult['resolvedNode']; static::$resolvedPath = $pathResult['resolvedPath']; static::$pathStack = $pathResult['pathStack']; - // print_r([ - // '$pathResult[resolvedNode]' => sprintf('%s:%s', $pathResult['resolvedNode']->Class, $pathResult['resolvedNode']->FullPath), - // '$pathResult[resolvedPath]' => implode('/', $pathResult['resolvedPath']), - // '$pathResult[pathStack]' => implode('/', $pathResult['pathStack']), - // '$pathResult[searchPath]' => implode('/', $pathResult['searchPath']) - // ]); - // bail now if no node found if (!static::$resolvedNode) { return static::respondNotFound(); @@ -296,32 +265,20 @@ public static function getRequestPathResult($path) $path = static::splitPath($path); } - // header('Content-Type: text/plain'); - // printf("getRequestPathResult(%s)\n", implode('/', $path)); - // rewrite empty path to default page if (empty($path[0]) && static::$defaultPage) { $path = array(static::$defaultPage); } // crawl down path stack until a handler is found - // printf("while (\$handle = array_shift(%s))\n", implode(',', $path)); $searchPath = array('site-root'); while ($handle = array_shift($path)) { - - // printf( - // "\n\t\$searchPath=%s\n\t\$handle=%s\n\t\$path=.../%s\n", - // implode('/', $searchPath), - // $handle, implode('/', $path) - // ); - $foundNode = null; // if path component doesn't already end in .php, check for a .php match first if (substr($handle, -4) != '.php') { array_push($searchPath, $handle.'.php'); $foundNode = static::resolvePath($searchPath); - // printf("\t\t%s\t%s\n", $foundNode ? 'matched' : 'missed', implode('/', $searchPath)); array_pop($searchPath); // don't match a collection as a script @@ -334,7 +291,6 @@ public static function getRequestPathResult($path) if (!$foundNode) { array_push($searchPath, $handle); $foundNode = static::resolvePath($searchPath); - // printf("\t\t%s\t%s\n", $foundNode ? 'matched' : 'missed', implode('/', $searchPath)); array_pop($searchPath); } @@ -358,8 +314,6 @@ public static function getRequestPathResult($path) $searchPath[] = $foundNode->Handle; } - // print("\nDone while.\n\n"); - return [ 'resolvedNode' => $resolvedNode, 'resolvedPath' => $resolvedPath,