diff --git a/akka-bbb-apps/.dockerignore b/akka-bbb-apps/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..c9c56767351f2752f2fad6e75af920655d3efa8d --- /dev/null +++ b/akka-bbb-apps/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile + diff --git a/akka-bbb-apps/Dockerfile b/akka-bbb-apps/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..e8adc296c1cbe6f283c5c44dea86fe2a01a90019 --- /dev/null +++ b/akka-bbb-apps/Dockerfile @@ -0,0 +1,24 @@ +FROM bbb-common-message AS builder + +ARG COMMON_VERSION=0.0.1-SNAPSHOT + +COPY . /source + +RUN cd /source \ + && find -name build.sbt -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-message[^\"]*\"[ ]*%[ ]*\)\"[^\"]*\"\(.*\)|\1\"$COMMON_VERSION\"\2|g" {} \; \ + && sbt compile + +RUN apt-get update \ + && apt-get -y install fakeroot + +RUN cd /source \ + && sbt debian:packageBin + +# FROM ubuntu:16.04 +FROM openjdk:8-jre-slim-stretch + +COPY --from=builder /source/target/*.deb /root/ + +RUN dpkg -i /root/*.deb + +CMD ["/usr/share/bbb-apps-akka/bin/bbb-apps-akka"] diff --git a/akka-bbb-fsesl/Dockerfile b/akka-bbb-fsesl/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..ff06041d93c9a190dfd4b85ae11368ae5f76ad3b --- /dev/null +++ b/akka-bbb-fsesl/Dockerfile @@ -0,0 +1,26 @@ +FROM bbb-fsesl-client AS builder + +ARG COMMON_VERSION=0.0.1-SNAPSHOT + +COPY . /source + +RUN cd /source \ + && find -name build.sbt -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-message[^\"]*\"[ ]*%[ ]*\)\"[^\"]*\"\(.*\)|\1\"$COMMON_VERSION\"\2|g" {} \; \ + && find -name build.sbt -exec sed -i "s|\(.*org.bigbluebutton.*bbb-fsesl-client[^\"]*\"[ ]*%[ ]*\)\"[^\"]*\"\(.*\)|\1\"$COMMON_VERSION\"\2|g" {} \; \ + && sbt compile + +RUN apt-get update \ + && apt-get -y install fakeroot + +RUN cd /source \ + && sbt debian:packageBin + +FROM openjdk:8-jre-slim-stretch + +COPY --from=builder /source/target/*.deb /root/ + +RUN dpkg -i /root/*.deb + +COPY wait-for-it.sh /usr/local/bin/ + +CMD ["/usr/share/bbb-fsesl-akka/bin/bbb-fsesl-akka"] diff --git a/akka-bbb-fsesl/wait-for-it.sh b/akka-bbb-fsesl/wait-for-it.sh new file mode 100755 index 0000000000000000000000000000000000000000..bbe404324bce73f9ca9999dd2d6936cf90e5c184 --- /dev/null +++ b/akka-bbb-fsesl/wait-for-it.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +cmdname=$(basename $0) + +echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $TIMEOUT -gt 0 ]]; then + echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + else + echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + fi + start_ts=$(date +%s) + while : + do + if [[ $ISBUSY -eq 1 ]]; then + nc -z $HOST $PORT + result=$? + else + (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 + result=$? + fi + if [[ $result -eq 0 ]]; then + end_ts=$(date +%s) + echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + break + fi + sleep 1 + done + return $result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $QUIET -eq 1 ]]; then + timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + else + timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + fi + PID=$! + trap "kill -INT -$PID" INT + wait $PID + RESULT=$? + if [[ $RESULT -ne 0 ]]; then + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + fi + return $RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + hostport=(${1//:/ }) + HOST=${hostport[0]} + PORT=${hostport[1]} + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -h) + HOST="$2" + if [[ $HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + HOST="${1#*=}" + shift 1 + ;; + -p) + PORT="$2" + if [[ $PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + PORT="${1#*=}" + shift 1 + ;; + -t) + TIMEOUT="$2" + if [[ $TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$HOST" == "" || "$PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +TIMEOUT=${TIMEOUT:-15} +STRICT=${STRICT:-0} +CHILD=${CHILD:-0} +QUIET=${QUIET:-0} + +# check to see if timeout is from busybox? +# check to see if timeout is from busybox? +TIMEOUT_PATH=$(realpath $(which timeout)) +if [[ $TIMEOUT_PATH =~ "busybox" ]]; then + ISBUSY=1 + BUSYTIMEFLAG="-t" +else + ISBUSY=0 + BUSYTIMEFLAG="" +fi + +if [[ $CHILD -gt 0 ]]; then + wait_for + RESULT=$? + exit $RESULT +else + if [[ $TIMEOUT -gt 0 ]]; then + wait_for_wrapper + RESULT=$? + else + wait_for + RESULT=$? + fi +fi + +if [[ $CLI != "" ]]; then + if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then + echoerr "$cmdname: strict mode, refusing to execute subprocess" + exit $RESULT + fi + exec "${CLI[@]}" +else + exit $RESULT +fi diff --git a/bbb-common-message/Dockerfile b/bbb-common-message/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..223159915350214fdaf6c9f9493bf52c6f7e9580 --- /dev/null +++ b/bbb-common-message/Dockerfile @@ -0,0 +1,13 @@ +FROM sbt:0.13.8 + +ARG COMMON_VERSION + +COPY . /bbb-common-message + +RUN cd /bbb-common-message \ + && sed -i "s|\(version := \)\".*|\1\"$COMMON_VERSION\"|g" build.sbt \ + && echo 'publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))' | tee -a build.sbt \ + && sbt compile \ + && sbt publish \ + && sbt publishLocal + diff --git a/bbb-common-web/Dockerfile b/bbb-common-web/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..874219a3ba36e6b2ef2ed34321cdaa7734155c4f --- /dev/null +++ b/bbb-common-web/Dockerfile @@ -0,0 +1,13 @@ +FROM bbb-common-message + +ARG COMMON_VERSION + +COPY . /bbb-common-web + +RUN cd /bbb-common-web \ + && sed -i "s|\(version := \)\".*|\1\"$COMMON_VERSION\"|g" build.sbt \ + && find -name build.sbt -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-message[^\"]*\"[ ]*%[ ]*\)\"[^\"]*\"\(.*\)|\1\"$COMMON_VERSION\"\2|g" {} \; \ + && echo 'publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))' | tee -a build.sbt \ + && sbt compile \ + && sbt publish \ + && sbt publishLocal diff --git a/bbb-fsesl-client/Dockerfile b/bbb-fsesl-client/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..c9fd93a8417e592f09e68ec1e258e0b16d139279 --- /dev/null +++ b/bbb-fsesl-client/Dockerfile @@ -0,0 +1,13 @@ +FROM bbb-common-message + +ARG COMMON_VERSION + +COPY . /bbb-fsesl-client + +RUN cd /bbb-fsesl-client \ + && sed -i "s|\(version := \)\".*|\1\"$COMMON_VERSION\"|g" build.sbt \ + && find -name build.sbt -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-message[^\"]*\"[ ]*%[ ]*\)\"[^\"]*\"\(.*\)|\1\"$COMMON_VERSION\"\2|g" {} \; \ + && echo 'publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))' | tee -a build.sbt \ + && sbt compile \ + && sbt publish \ + && sbt publishLocal diff --git a/bbb-lti/.dockerignore b/bbb-lti/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..94143827ed065ca0d7d5be1b765d255c5c32cd9a --- /dev/null +++ b/bbb-lti/.dockerignore @@ -0,0 +1 @@ +Dockerfile diff --git a/bbb-lti/Dockerfile b/bbb-lti/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..4503f2d172e525085026332f16b97e38b46f4a2c --- /dev/null +++ b/bbb-lti/Dockerfile @@ -0,0 +1,52 @@ +FROM java:8-jdk AS builder + +RUN mkdir -p /root/tools \ + && cd /root/tools \ + && wget http://services.gradle.org/distributions/gradle-2.12-bin.zip \ + && unzip gradle-2.12-bin.zip \ + && ln -s gradle-2.12 gradle + +RUN mkdir -p /root/tools \ + && cd /root/tools \ + && wget https://github.com/grails/grails-core/releases/download/v2.5.2/grails-2.5.2.zip \ + && unzip grails-2.5.2.zip \ + && ln -s grails-2.5.2 grails + +ENV PATH="/root/tools/gradle/bin:/root/tools/grails/bin:${PATH}" + +COPY . /source + +# build with: +# docker build -t mconftec/bbb-lti --build-arg title=Mconf --build-arg description='Single Sign On into Mconf' --build-arg vendor_code=mconf --build-arg vendor_name=Mconf --build-arg vendor_description='Mconf web conferencing' --build-arg vendor_url=https://mconf.com . + +ARG title=BigBlueButton +ARG description='Single Sign On into BigBlueButton' +ARG vendor_code=bigbluebutton +ARG vendor_name=BigBlueButton +ARG vendor_description='Open source web conferencing system for distance learning.' +ARG vendor_url=http://www.bigbluebutton.org/ + +RUN cd /source \ + && sed -i "s|\(<blti:title>\)[^<]*|\1$title|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && sed -i "s|\(<blti:description>\)[^<]*|\1$description|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && sed -i "s|\(<lticp:code>\)[^<]*|\1$vendor_code|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && sed -i "s|\(<lticp:name>\)[^<]*|\1$vendor_name|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && sed -i "s|\(<lticp:description>\)[^<]*|\1$vendor_description|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && sed -i "s|\(<lticp:url>\)[^<]*|\1$vendor_url|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \ + && grails war + +FROM tomcat:7-jre8 + +WORKDIR $CATALINA_HOME + +# clean default webapps +RUN rm -r webapps/* + +COPY --from=builder /source/target/lti-*.war webapps/lti.war + +RUN unzip -q webapps/lti.war -d webapps/lti \ + && rm webapps/lti.war + +COPY docker-entrypoint.sh /usr/local/bin/ + +CMD ["docker-entrypoint.sh"] diff --git a/bbb-lti/docker-entrypoint.sh b/bbb-lti/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..608af0aa7ad42fa92ec1d1b73f85021484974b78 --- /dev/null +++ b/bbb-lti/docker-entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/bash -xe + +export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -DbigbluebuttonSalt=$BIGBLUEBUTTON_SHARED_SECRET -DbigbluebuttonURL=$BIGBLUEBUTTON_URL -DltiEndPoint=$LTI_ENDPOINT -DltiConsumers=$LTI_CONSUMERS -DltiAllRecordedByDefault=$RECORDED_BY_DEFAULT" +sed -i "s|^securerandom\.source=.*|securerandom.source=file:/dev/./urandom|g" $JAVA_HOME/lib/security/java.security + +catalina.sh run + diff --git a/bbb-webhooks/Dockerfile b/bbb-webhooks/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..afa9470fdc7330c434f6433c62ce1179b7dd3042 --- /dev/null +++ b/bbb-webhooks/Dockerfile @@ -0,0 +1,16 @@ +FROM node:8 + +ADD . app + +WORKDIR app + +RUN cp config_local.js.example config_local.js + +ENV NODE_ENV production + +RUN npm install \ + && npm cache clear --force + +EXPOSE 3005 + +CMD ["node", "app.js"] diff --git a/bbb-webhooks/application.js b/bbb-webhooks/application.js index 2817826712746cc2f49e2819e2c2482b84d56e79..b6e9985b1254bf729a2d226204d680600ead0903 100644 --- a/bbb-webhooks/application.js +++ b/bbb-webhooks/application.js @@ -13,8 +13,12 @@ const async = require("async"); module.exports = class Application { constructor() { - config.redis.pubSubClient = redis.createClient(); - config.redis.client = redis.createClient() + const options = { + host : process.env.REDIS_HOST || config.redis.host, + port : process.env.REDIS_PORT || config.redis.port + }; + config.redis.pubSubClient = redis.createClient(options); + config.redis.client = redis.createClient(options); this.webHooks = new WebHooks(); this.webServer = new WebServer(); } diff --git a/bbb-webhooks/callback_emitter.js b/bbb-webhooks/callback_emitter.js index 11416774cb1461cb5a37009d868dc497f13c7ce2..6ec7d553632c42d0c4a71da85bfb371cd80c59c6 100644 --- a/bbb-webhooks/callback_emitter.js +++ b/bbb-webhooks/callback_emitter.js @@ -62,11 +62,19 @@ module.exports = class CallbackEmitter extends EventEmitter { _emitMessage(callback) { let data,requestOptions; + const serverDomain = process.env.SERVER_DOMAIN || config.bbb.serverDomain; + const sharedSecret = process.env.SHARED_SECRET || config.bbb.sharedSecret; + const bearerAuth = process.env.BEARER_AUTH || config.bbb.auth2_0; + + // data to be sent + // note: keep keys in alphabetical order + data = { + event: "[" + this.message + "]", + timestamp: this.timestamp, + domain: serverDomain + }; - if (config.bbb.auth2_0) { - // Send data as a JSON - data = "[" + this.message + "]"; - + if (bearerAuth) { const callbackURL = this.callbackURL; requestOptions = { @@ -76,20 +84,13 @@ module.exports = class CallbackEmitter extends EventEmitter { method: "POST", form: data, auth: { - bearer: config.bbb.sharedSecret + bearer: sharedSecret } }; } else { - // data to be sent - // note: keep keys in alphabetical order - data = { - event: "[" + this.message + "]", - timestamp: this.timestamp - }; - // calculate the checksum - const checksum = Utils.checksum(`${this.callbackURL}${JSON.stringify(data)}${config.bbb.sharedSecret}`); + const checksum = Utils.checksum(`${this.callbackURL}${JSON.stringify(data)}${sharedSecret}`); // get the final callback URL, including the checksum const urlObj = url.parse(this.callbackURL, true); diff --git a/bbb-webhooks/config.js b/bbb-webhooks/config.js index 80845f1fc9183e360f06b21d470aa922442451df..cfc7ccda07e0a8f5f33c3f695da7c6e9d274d9b9 100644 --- a/bbb-webhooks/config.js +++ b/bbb-webhooks/config.js @@ -51,6 +51,8 @@ config.mappings.timeout = 1000*60*60*24; // 24 hours, in ms // Redis config.redis = {}; +config.redis.host = '127.0.0.1'; +config.redis.port = 6379; config.redis.keys = {}; config.redis.keys.hook = id => `bigbluebutton:webhooks:hook:${id}`; config.redis.keys.hooks = "bigbluebutton:webhooks:hooks"; diff --git a/bbb-webhooks/config/monit-bbb-webhooks b/bbb-webhooks/config/monit-bbb-webhooks deleted file mode 100755 index 18e1f1e445dfa9f30f84907d7d8312e48f0bcb91..0000000000000000000000000000000000000000 --- a/bbb-webhooks/config/monit-bbb-webhooks +++ /dev/null @@ -1,12 +0,0 @@ -#!monit -set logfile /var/log/monit.log - -check process bbb-webhooks with pidfile "/var/run/bbb-webhooks.pid" - start program = "/sbin/start bbb-webhooks" - stop program = "/sbin/stop bbb-webhooks" - - if failed port 3005 protocol HTTP - request /bigbluebutton/api/hooks/ping - with timeout 30 seconds - then restart - # if 5 restarts within 5 cycles then timeout diff --git a/bbb-webhooks/config/upstart-bbb-webhooks.conf b/bbb-webhooks/config/upstart-bbb-webhooks.conf deleted file mode 100644 index af2e5069340f1650edcc42dede5ece593d76d1e1..0000000000000000000000000000000000000000 --- a/bbb-webhooks/config/upstart-bbb-webhooks.conf +++ /dev/null @@ -1,34 +0,0 @@ -# bbb-webhooks - -description "bbb-webhooks" -author "BigBlueButton" - -start on (local-filesystems and net-device-up IFACE=eth3) -stop on shutdown - -# respawn # we're using monit for it - -env USER=firstuser -env APP=app.js -env CMD_OPTS="" -env SRC_DIR="/usr/local/bigbluebutton/bbb-webhooks" -env LOGFILE="/var/log/bbb-webhooks.log" -env NODE=/usr/local/bin/node -env PIDFILE="/var/run/bbb-webhooks.pid" -env NODE_ENV="production" - -script - cd $SRC_DIR - echo $$ > $PIDFILE - exec sudo -u $USER NODE_ENV=$NODE_ENV $NODE $APP $CMD_OPTS 1>> $LOGFILE 2>> $LOGFILE -end script - -pre-start script - # Date format same as (new Date()).toISOString() for consistency - echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> $LOGFILE -end script - -pre-stop script - rm $PIDFILE - echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> $LOGFILE -end script diff --git a/bbb-webhooks/config_local.js.example b/bbb-webhooks/config_local.js.example index 0a64ac0d5fc504b12c270cead9d4cd99d0e4f7ea..0bebd13924dafc0e7f86e9cfb5d84ebe8a390551 100644 --- a/bbb-webhooks/config_local.js.example +++ b/bbb-webhooks/config_local.js.example @@ -4,6 +4,7 @@ const config = {}; // Shared secret of your BigBlueButton server. config.bbb = {}; +config.bbb.serverDomain = "myserver.com"; config.bbb.sharedSecret = "mysharedsecret"; // Whether to use Auth2.0 or not, Auth2.0 sends the sharedSecret whithin an Authorization header as a bearer config.bbb.auth2_0 = false; diff --git a/bbb-webhooks/extra/events.js b/bbb-webhooks/extra/events.js index 9abaf828d5622b2b69aed49f16e58bd5df8f5add..c527879ac95f1d8062087c1ecedfbb9581ea38a9 100644 --- a/bbb-webhooks/extra/events.js +++ b/bbb-webhooks/extra/events.js @@ -6,7 +6,7 @@ const redis = require("redis"); const config = require('../config.js'); var target_meeting = null; var events_printed = []; -var subscriber = redis.createClient(); +var subscriber = redis.createClient(process.env.REDIS_PORT || config.redis.port, process.env.REDIS_HOST || config.redis.host); subscriber.on("psubscribe", function(channel, count) { console.log("subscribed to " + channel); diff --git a/bbb-webhooks/messageMapping.js b/bbb-webhooks/messageMapping.js index a18badce776842d5d6252c86a012c8dad79a4023..7ea2062c8a022894279ad9f4f15c20f82a4aac7e 100644 --- a/bbb-webhooks/messageMapping.js +++ b/bbb-webhooks/messageMapping.js @@ -147,31 +147,36 @@ module.exports = class MessageMapping { } rapTemplate(messageObj) { - data = messageObj.payload + const data = messageObj.payload; this.mappedObject.data = { "type": "event", "id": this.mapInternalMessage(messageObj.header.name), "attributes": { "meeting": { "internal-meeting-id": data.meeting_id, - "external-meeting-id": IDMapping.getExternalMeetingID(data.meeting_id) + "external-meeting-id": data.external_meeting_id }, - "recording": { - "name": data.metadata.meetingName, - "isBreakout": data.metadata.isBreakout, - "startTime": data.startTime, - "endTime": data.endTime, - "size": data.playback.size, - "rawSize": data.rawSize, - "metadata": data.metadata, - "playback": data.playback, - "download": data.download - } + "success": data.success, + "step-time": data.step_time }, "event": { "ts": messageObj.header.current_time } }; + + if (this.mappedObject.data["id"] == "rap-publish-ended") { + this.mappedObject.data["attributes"]["recording"] = { + "name": data.metadata.meetingName, + "isBreakout": data.metadata.isBreakout, + "startTime": data.startTime, + "endTime": data.endTime, + "size": data.playback.size, + "rawSize": data.rawSize, + "metadata": data.metadata, + "playback": data.playback, + "download": data.download + } + } this.mappedMessage = JSON.stringify(this.mappedObject); Logger.info("[MessageMapping] Mapped message:", this.mappedMessage); } diff --git a/bbb-webhooks/package-lock.json b/bbb-webhooks/package-lock.json index 756667bad9b6e41d2e885a38a2ee14ed62a66509..d219d53434a1cd81410f9b651b99fd5f20f757e5 100644 --- a/bbb-webhooks/package-lock.json +++ b/bbb-webhooks/package-lock.json @@ -4,42 +4,14 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "accepts": { - "version": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", - "integrity": "sha1-1xyW99QdD+2iw4zRToonwEFY30o=", - "requires": { - "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "negotiator": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz" - }, - "dependencies": { - "mime-db": { - "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", - "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" - }, - "mime-types": { - "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", - "requires": { - "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" - } - } - } - }, - "asn1": { - "version": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" - }, - "assert-plus": { - "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" - }, "assertion-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" }, "async": { - "version": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", "integrity": "sha1-rDYTsdqb7RtHUQu0ZRuJMeRxRsc=" }, "asynckit": { @@ -48,44 +20,152 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "aws-sign2": { - "version": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "bl": { - "version": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", - "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", - "requires": { - "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - } - }, "body-parser": { - "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", - "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", - "requires": { - "bytes": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "qs": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "raw-body": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz" - } - }, - "boom": { - "version": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { - "hoek": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz" + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "1.6.16" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.5.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": "2.1.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" + }, + "mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "requires": { + "mime-db": "1.35.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.19" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + } } }, "brace-expansion": { @@ -104,45 +184,27 @@ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, - "bytes": { - "version": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" - }, - "caseless": { - "version": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz", - "integrity": "sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ=" - }, - "chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", - "requires": { - "assertion-error": "1.0.2", - "deep-eql": "0.1.3", - "type-detect": "1.0.0" - } - }, - "charenc": { - "version": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" - }, - "coffee-script": { - "version": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.8.0.tgz", - "integrity": "sha1-nJ8dK0pSoADe0Vtll5FwNkgmPB0=", + "build": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", + "integrity": "sha1-cH/gJv/O3crL/c3zVur9pk8VEEY=", "requires": { - "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + "cssmin": "0.3.2", + "jsmin": "1.0.1", + "jxLoader": "0.1.1", + "moo-server": "1.3.0", + "promised-io": "0.3.5", + "timespan": "2.3.0", + "uglify-js": "1.3.5", + "walker": "1.0.7", + "winston": "0.8.3", + "wrench": "1.3.9" } }, - "colors": { - "version": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=" - }, - "combined-stream": { - "version": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", - "requires": { - "delayed-stream": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" - } + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" }, "commander": { "version": "2.9.0", @@ -165,22 +227,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "content-disposition": { - "version": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz", - "integrity": "sha1-QoT+auBjCHRjnkToCkGMKTQTXp4=" - }, - "content-type": { - "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" - }, - "cookie": { - "version": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" - }, - "cookie-signature": { - "version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.5.tgz", - "integrity": "sha1-oSLj8VA+yg9TVXlbBxG7I2jUUPk=" - }, "cookiejar": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", @@ -189,82 +235,36 @@ }, "core-util-is": { "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "crc": { - "version": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz", - "integrity": "sha1-XZyPt3okXNXsopHl0tAFM0urAII=" - }, - "crypt": { - "version": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" - }, - "cryptiles": { - "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", - "requires": { - "boom": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz" - } - }, - "ctype": { - "version": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, - "cycle": { - "version": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + "cssmin": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", + "integrity": "sha1-3c5MVHtRCuDVlKjx+/iq+OLFwA0=" }, "debug": { "version": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "dev": true, "requires": { "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" } }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "requires": { - "type-detect": "0.1.1" - }, - "dependencies": { - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" - } - } - }, "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" }, - "delayed-stream": { - "version": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" - }, - "depd": { - "version": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, - "destroy": { - "version": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", - "integrity": "sha1-tDO0ck5x/YVR2YhRdIUcX8N34sk=" - }, "diff": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" }, - "ee-first": { - "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "escape-html": { - "version": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" }, "escape-string-regexp": { "version": "1.0.5", @@ -272,91 +272,260 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "etag": { - "version": "https://registry.npmjs.org/etag/-/etag-1.5.1.tgz", - "integrity": "sha1-VMUN4E7kJpVWKSWsVmWIKRvn6eo=", - "requires": { - "crc": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz" - } - }, "express": { - "version": "https://registry.npmjs.org/express/-/express-4.10.2.tgz", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.10.2.tgz", "integrity": "sha1-3wbd6U2WiTKCnUQKIATF7+ZElbA=", "requires": { - "accepts": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", - "content-disposition": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz", - "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.5.tgz", - "debug": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", - "depd": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "etag": "https://registry.npmjs.org/etag/-/etag-1.5.1.tgz", - "finalhandler": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.2.tgz", - "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz", - "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "merge-descriptors": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "methods": "https://registry.npmjs.org/methods/-/methods-1.1.0.tgz", - "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", - "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.3.tgz", - "proxy-addr": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz", - "qs": "https://registry.npmjs.org/qs/-/qs-2.3.2.tgz", - "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", - "send": "https://registry.npmjs.org/send/-/send-0.10.1.tgz", - "serve-static": "https://registry.npmjs.org/serve-static/-/serve-static-1.7.2.tgz", - "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz", - "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "vary": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz" + "accepts": "1.1.4", + "content-disposition": "0.5.0", + "cookie": "0.1.2", + "cookie-signature": "1.0.5", + "debug": "2.1.3", + "depd": "1.0.1", + "escape-html": "1.0.1", + "etag": "1.5.1", + "finalhandler": "0.3.2", + "fresh": "0.2.4", + "media-typer": "0.3.0", + "merge-descriptors": "0.0.2", + "methods": "1.1.0", + "on-finished": "2.1.1", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.3", + "proxy-addr": "1.0.10", + "qs": "2.3.2", + "range-parser": "1.0.3", + "send": "0.10.1", + "serve-static": "1.7.2", + "type-is": "1.5.7", + "utils-merge": "1.0.0", + "vary": "1.0.1" }, "dependencies": { + "accepts": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.1.4.tgz", + "integrity": "sha1-1xyW99QdD+2iw4zRToonwEFY30o=", + "requires": { + "mime-types": "2.0.14", + "negotiator": "0.4.9" + } + }, + "content-disposition": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz", + "integrity": "sha1-QoT+auBjCHRjnkToCkGMKTQTXp4=" + }, + "cookie": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", + "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" + }, + "cookie-signature": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.5.tgz", + "integrity": "sha1-oSLj8VA+yg9TVXlbBxG7I2jUUPk=" + }, + "crc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz", + "integrity": "sha1-XZyPt3okXNXsopHl0tAFM0urAII=" + }, "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", "integrity": "sha1-zoqxte6PvuK/o7Yzyrk9NmtjQY4=", "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz" + "ms": "0.7.0" } }, "depd": { - "version": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=" }, + "destroy": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", + "integrity": "sha1-tDO0ck5x/YVR2YhRdIUcX8N34sk=" + }, "ee-first": { - "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz", "integrity": "sha1-ag18YiHkkP7v2S7D9EHJzozQl/Q=" }, + "escape-html": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", + "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + }, + "etag": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.5.1.tgz", + "integrity": "sha1-VMUN4E7kJpVWKSWsVmWIKRvn6eo=", + "requires": { + "crc": "3.2.1" + } + }, + "finalhandler": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.2.tgz", + "integrity": "sha1-ezibD9Nkem+QvVZOImJL+KSnf7U=", + "requires": { + "debug": "2.1.3", + "escape-html": "1.0.1", + "on-finished": "2.1.1" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz", + "integrity": "sha1-NYJJkgbJcjcUGQ7ddLRgT+tKYUw=" + }, + "ipaddr.js": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz", + "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", + "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" + }, + "methods": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.0.tgz", + "integrity": "sha1-XcpO4S31L/OwVhRZhqjwHLyGQ28=" + }, + "mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + }, "mime-db": { - "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" }, "mime-types": { - "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", "requires": { - "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" + "mime-db": "1.12.0" } }, "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz", "integrity": "sha1-hlvpTC5zl62KV9pqYzpuLzB5i4M=" }, + "negotiator": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", + "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" + }, "on-finished": { - "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", "integrity": "sha1-+CyhyeOk8yhrG5k4YQ5bhja9PLI=", "requires": { - "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz" + "ee-first": "1.1.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-to-regexp": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.3.tgz", + "integrity": "sha1-IbmrgidCed4lsVbqCP0SylG4rss=" + }, + "proxy-addr": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz", + "integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.0.5" } }, "qs": { - "version": "https://registry.npmjs.org/qs/-/qs-2.3.2.tgz", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.2.tgz", "integrity": "sha1-1F7CSeS5sCmvAIgpoQHV/36XJ5A=" }, + "range-parser": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", + "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=" + }, + "send": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.10.1.tgz", + "integrity": "sha1-d0XFDscvEVEVmA6PsXmuwBkA4Io=", + "requires": { + "debug": "2.1.3", + "depd": "1.0.1", + "destroy": "1.0.3", + "escape-html": "1.0.1", + "etag": "1.5.1", + "fresh": "0.2.4", + "mime": "1.2.11", + "ms": "0.6.2", + "on-finished": "2.1.1", + "range-parser": "1.0.3" + }, + "dependencies": { + "ms": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", + "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + } + } + }, + "serve-static": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.7.2.tgz", + "integrity": "sha1-MWTOBtTmw0Wb3MnWAY+0+zXoSzk=", + "requires": { + "escape-html": "1.0.1", + "parseurl": "1.3.2", + "send": "0.10.1", + "utils-merge": "1.0.0" + } + }, "type-is": { - "version": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz", + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.5.7.tgz", "integrity": "sha1-uTaKWTzG730GReeLL0xky+zQXpA=", "requires": { - "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz" + "media-typer": "0.3.0", + "mime-types": "2.0.14" } + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + }, + "vary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz", + "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA=" } } }, @@ -366,56 +535,6 @@ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "dev": true }, - "eyes": { - "version": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" - }, - "finalhandler": { - "version": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.2.tgz", - "integrity": "sha1-ezibD9Nkem+QvVZOImJL+KSnf7U=", - "requires": { - "debug": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", - "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz" - }, - "dependencies": { - "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", - "integrity": "sha1-zoqxte6PvuK/o7Yzyrk9NmtjQY4=", - "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz" - } - }, - "ee-first": { - "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz", - "integrity": "sha1-ag18YiHkkP7v2S7D9EHJzozQl/Q=" - }, - "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz", - "integrity": "sha1-hlvpTC5zl62KV9pqYzpuLzB5i4M=" - }, - "on-finished": { - "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", - "integrity": "sha1-+CyhyeOk8yhrG5k4YQ5bhja9PLI=", - "requires": { - "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz" - } - } - } - }, - "forever-agent": { - "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" - }, - "form-data": { - "version": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", - "requires": { - "async": "https://registry.npmjs.org/async/-/async-0.9.0.tgz", - "combined-stream": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "mime": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" - } - }, "formatio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", @@ -430,20 +549,17 @@ "integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak=", "dev": true }, - "forwarded": { - "version": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" - }, - "fresh": { - "version": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz", - "integrity": "sha1-NYJJkgbJcjcUGQ7ddLRgT+tKYUw=" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, "glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", @@ -476,43 +592,6 @@ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "hawk": { - "version": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", - "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", - "requires": { - "boom": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "cryptiles": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "hoek": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "sntp": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz" - } - }, - "hoek": { - "version": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" - }, - "http-errors": { - "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz" - } - }, - "http-signature": { - "version": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", - "requires": { - "asn1": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "ctype": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" - } - }, - "iconv-lite": { - "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -525,23 +604,22 @@ }, "inherits": { "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz", - "integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "isarray": { "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, - "isstream": { - "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "js-yaml": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", + "integrity": "sha1-1znY7oZGHlSzVNan19HyrZoWf2I=" }, - "json-stringify-safe": { - "version": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "jsmin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", + "integrity": "sha1-570NzWSWw79IYyNb9GGj2YqjuYw=" }, "json3": { "version": "3.3.2", @@ -554,8 +632,20 @@ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.22.tgz", "integrity": "sha1-MzCvdWyralQnAMZLLk5KoGLVL/8=" }, + "jxLoader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", + "integrity": "sha1-ATTqUUTlM7WU/B/yX/GU4jXFPs0=", + "requires": { + "js-yaml": "0.3.7", + "moo-server": "1.3.0", + "promised-io": "0.3.5", + "walker": "1.0.7" + } + }, "lodash": { - "version": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz", "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=" }, "lodash._baseassign": { @@ -603,6 +693,11 @@ "lodash._isiterateecall": "3.0.9" } }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -631,29 +726,23 @@ "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.2.tgz", "integrity": "sha1-JpS5U8nqTQE+W4v7qJHJkQJbJik=" }, - "media-typer": { - "version": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" - }, - "methods": { - "version": "https://registry.npmjs.org/methods/-/methods-1.1.0.tgz", - "integrity": "sha1-XcpO4S31L/OwVhRZhqjwHLyGQ28=" - }, - "mime": { - "version": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.4" + } }, "mime-db": { "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", - "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=" + "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=", + "dev": true }, "mime-types": { "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", + "dev": true, "requires": { "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz" } @@ -672,10 +761,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, - "mkdirp": { - "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=" - }, "mocha": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", @@ -715,19 +800,21 @@ } } }, + "moo-server": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", + "integrity": "sha1-XceVaVZaENbv7VQ5SR5p0jkuWPE=" + }, "ms": { "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, "native-promise-only": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=" }, - "negotiator": { - "version": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", - "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" - }, "nise": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nise/-/nise-1.0.1.tgz", @@ -755,25 +842,59 @@ } }, "nock": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.14.tgz", - "integrity": "sha1-IhFVAlMXPOKYvNifyoJeg4E8pys=", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.4.3.tgz", + "integrity": "sha512-inJFXR3REBvHbZy6nVVwaoKbVTR8Y4Ag051Y/pd2pNPy7HDYtQkenfilBwxToNsW9p1RTeBUml4SPK/mWrFihA==", "requires": { - "chai": "3.5.0", - "debug": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", + "chai": "4.1.2", + "debug": "3.1.0", "deep-equal": "1.0.1", - "json-stringify-safe": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "lodash": "4.17.4", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.10", "mkdirp": "0.5.1", - "propagate": "0.4.0", - "qs": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "semver": "5.4.1" + "propagate": "1.0.0", + "qs": "6.5.2", + "semver": "5.5.0" }, "dependencies": { + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "requires": { + "assertion-error": "1.0.2", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "4.0.8" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" }, "mkdirp": { "version": "0.5.1", @@ -782,24 +903,34 @@ "requires": { "minimist": "0.0.8" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "propagate": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-1.0.0.tgz", + "integrity": "sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" } } }, - "node-uuid": { - "version": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" - }, - "oauth-sign": { - "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz", - "integrity": "sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k=" - }, - "on-finished": { - "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -809,23 +940,16 @@ "wrappy": "1.0.2" } }, - "parseurl": { - "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" - }, "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=", "dev": true }, - "path-to-regexp": { - "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.3.tgz", - "integrity": "sha1-IbmrgidCed4lsVbqCP0SylG4rss=" - }, - "pkginfo": { - "version": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", - "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" }, "process-nextick-args": { "version": "1.0.7", @@ -833,83 +957,259 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, - "propagate": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", - "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=" - }, - "proxy-addr": { - "version": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz", - "integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=", - "requires": { - "forwarded": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "ipaddr.js": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz" - } + "promised-io": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.5.tgz", + "integrity": "sha1-StIXuzZYvKrplGsXqGaOzYUeE1Y=" }, - "punycode": { - "version": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "psl": { + "version": "1.1.28", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", + "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==" }, "qs": { "version": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" - }, - "range-parser": { - "version": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", - "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=" + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true }, - "raw-body": { - "version": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", "requires": { - "bytes": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.5", + "redis-parser": "2.6.0" } }, - "readable-stream": { - "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - } + "redis-commands": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==" }, - "redis": { - "version": "https://registry.npmjs.org/redis/-/redis-0.12.1.tgz", - "integrity": "sha1-ZN92rQ/IrOuuvSoGReikj6xJGF4=" + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" }, "request": { - "version": "https://registry.npmjs.org/request/-/request-2.47.0.tgz", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.47.0.tgz", "integrity": "sha1-Cen9Gk/tZZOoBe+CArIPDF7LSF8=", "requires": { - "aws-sign2": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "bl": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", - "caseless": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz", - "combined-stream": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "forever-agent": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "form-data": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "hawk": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", - "http-signature": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "json-stringify-safe": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "node-uuid": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "oauth-sign": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz", - "qs": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "stringstream": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "tough-cookie": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "tunnel-agent": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" + "aws-sign2": "0.5.0", + "bl": "0.9.5", + "caseless": "0.6.0", + "combined-stream": "0.0.7", + "forever-agent": "0.5.2", + "form-data": "0.1.4", + "hawk": "1.1.1", + "http-signature": "0.10.1", + "json-stringify-safe": "5.0.1", + "mime-types": "1.0.2", + "node-uuid": "1.4.8", + "oauth-sign": "0.4.0", + "qs": "2.3.3", + "stringstream": "0.0.6", + "tough-cookie": "2.4.3", + "tunnel-agent": "0.4.3" }, "dependencies": { + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" + }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "requires": { + "readable-stream": "1.0.34" + } + }, + "boom": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "requires": { + "hoek": "0.9.1" + } + }, + "caseless": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz", + "integrity": "sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ=" + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "requires": { + "delayed-stream": "0.0.5" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "requires": { + "boom": "0.4.2" + } + }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" + }, + "forever-agent": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" + }, + "form-data": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", + "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", + "requires": { + "async": "0.9.0", + "combined-stream": "0.0.7", + "mime": "1.2.11" + } + }, + "hawk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", + "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", + "requires": { + "boom": "0.4.2", + "cryptiles": "0.2.2", + "hoek": "0.9.1", + "sntp": "0.2.4" + } + }, + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "requires": { + "asn1": "0.1.11", + "assert-plus": "0.1.5", + "ctype": "0.5.3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + }, "mime-types": { - "version": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "oauth-sign": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz", + "integrity": "sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, "qs": { - "version": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "sntp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "requires": { + "hoek": "0.9.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "1.1.28", + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" } } }, @@ -919,142 +1219,75 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "samsam": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=" }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - }, - "send": { - "version": "https://registry.npmjs.org/send/-/send-0.10.1.tgz", - "integrity": "sha1-d0XFDscvEVEVmA6PsXmuwBkA4Io=", + "sha1": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.0.tgz", + "integrity": "sha1-j8IEe+OezrHcVOv+NaUEmxigBAs=", "requires": { - "debug": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", - "depd": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "destroy": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", - "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "etag": "https://registry.npmjs.org/etag/-/etag-1.5.1.tgz", - "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz", - "mime": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "ms": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", - "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz" + "charenc": "0.0.2", + "crypt": "0.0.2" }, "dependencies": { - "debug": { - "version": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz", - "integrity": "sha1-zoqxte6PvuK/o7Yzyrk9NmtjQY4=", - "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz" - }, - "dependencies": { - "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz", - "integrity": "sha1-hlvpTC5zl62KV9pqYzpuLzB5i4M=" - } - } - }, - "depd": { - "version": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=" + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, - "ee-first": { - "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz", - "integrity": "sha1-ag18YiHkkP7v2S7D9EHJzozQl/Q=" - }, - "ms": { - "version": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" - }, - "on-finished": { - "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.1.1.tgz", - "integrity": "sha1-+CyhyeOk8yhrG5k4YQ5bhja9PLI=", - "requires": { - "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz" - } + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" } } }, - "serve-static": { - "version": "https://registry.npmjs.org/serve-static/-/serve-static-1.7.2.tgz", - "integrity": "sha1-MWTOBtTmw0Wb3MnWAY+0+zXoSzk=", - "requires": { - "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "send": "https://registry.npmjs.org/send/-/send-0.10.1.tgz", - "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" - } - }, - "setprototypeof": { - "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - }, - "sha1": { - "version": "https://registry.npmjs.org/sha1/-/sha1-1.1.0.tgz", - "integrity": "sha1-j8IEe+OezrHcVOv+NaUEmxigBAs=", - "requires": { - "charenc": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "crypt": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz" - } - }, "sinon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", - "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.3.0.tgz", + "integrity": "sha512-/flfGfIxIRXSvZBHJzIf3iAyGYkmMQq6SQjA0cx9SOuVuq+4ZPPO4LJtH1Ce0Lznax1KSG1U6Dad85wIcSW19w==", "requires": { + "build": "0.1.4", "diff": "3.2.0", "formatio": "1.2.0", + "lodash.get": "4.4.2", "lolex": "2.1.2", "native-promise-only": "0.8.1", "nise": "1.0.1", "path-to-regexp": "1.7.0", "samsam": "1.2.1", "text-encoding": "0.6.4", - "type-detect": "4.0.3" + "type-detect": "4.0.8" }, "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", "requires": { - "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + "isarray": "0.0.1" } }, "type-detect": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", - "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=" + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" } } }, - "sntp": { - "version": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", - "requires": { - "hoek": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz" - } - }, - "stack-trace": { - "version": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "statuses": { - "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - }, - "string_decoder": { - "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "stringstream": { - "version": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" - }, "superagent": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.6.0.tgz", @@ -1175,33 +1408,20 @@ "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" }, - "tough-cookie": { - "version": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "requires": { - "punycode": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" - } - }, - "tunnel-agent": { - "version": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" - }, - "type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=" + "timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=" }, - "type-is": { - "version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", - "requires": { - "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz" - } + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" }, - "unpipe": { - "version": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "uglify-js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", + "integrity": "sha1-S1v/+Rhu/7qoiOTJ6UvZ/EyUkp0=" }, "util-deprecate": { "version": "1.0.2", @@ -1209,30 +1429,62 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "utils-merge": { - "version": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" - }, - "vary": { - "version": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz", - "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA=" + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.11" + } }, "winston": { - "version": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", "requires": { - "async": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "colors": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "cycle": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "eyes": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "isstream": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "pkginfo": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", - "stack-trace": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" + "async": "0.2.10", + "colors": "0.6.2", + "cycle": "1.0.3", + "eyes": "0.1.8", + "isstream": "0.1.2", + "pkginfo": "0.3.1", + "stack-trace": "0.0.10" }, "dependencies": { "async": { - "version": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=" + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "pkginfo": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", + "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" } } }, @@ -1242,6 +1494,11 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "wrench": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", + "integrity": "sha1-bxPsNRRTF+spLKX2UxORskQRFBE=" + }, "xmldom": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", diff --git a/bbb-webhooks/package.json b/bbb-webhooks/package.json index cbe8a8dc77d2dd5596509a2500fb8d6f188fcd12..b6b938e669c95cd5dd0e6c0463c5897f58996698 100755 --- a/bbb-webhooks/package.json +++ b/bbb-webhooks/package.json @@ -10,11 +10,10 @@ "dependencies": { "async": "0.9.0", "body-parser": "^1.9.2", - "coffee-script": "1.8.0", "express": "4.10.2", "lodash": "2.4.1", "nock": "^9.0.14", - "redis": "0.12.1", + "redis": "^2.8.0", "request": "2.47.0", "sha1": "1.1.0", "sinon": "^3.2.1", diff --git a/bbb-webhooks/test/test.js b/bbb-webhooks/test/test.js index 51b2d0ab2037d24646ddd1efcb6ee854400c66e8..7239b9f16f3327383a2776591c735e1621bd7211 100644 --- a/bbb-webhooks/test/test.js +++ b/bbb-webhooks/test/test.js @@ -9,6 +9,8 @@ const Helpers = require('./helpers.js') const sinon = require('sinon'); const winston = require('winston'); +const sharedSecret = process.env.SHARED_SECRET || sharedSecret; + // Block winston from logging Logger.remove(winston.transports.Console); describe('bbb-webhooks tests', () => { @@ -38,7 +40,7 @@ describe('bbb-webhooks tests', () => { describe('GET /hooks/list permanent', () => { it('should list permanent hook', (done) => { - let getUrl = utils.checksumAPI(Helpers.url + Helpers.listUrl, config.bbb.sharedSecret); + let getUrl = utils.checksumAPI(Helpers.url + Helpers.listUrl, sharedSecret); getUrl = Helpers.listUrl + '?checksum=' + getUrl request(Helpers.url) @@ -62,7 +64,7 @@ describe('bbb-webhooks tests', () => { Hook.removeSubscription(hooks[hooks.length-1].id, () => { done(); }); }); it('should create a hook', (done) => { - let getUrl = utils.checksumAPI(Helpers.url + Helpers.createUrl, config.bbb.sharedSecret); + let getUrl = utils.checksumAPI(Helpers.url + Helpers.createUrl, sharedSecret); getUrl = Helpers.createUrl + '&checksum=' + getUrl request(Helpers.url) @@ -87,7 +89,7 @@ describe('bbb-webhooks tests', () => { it('should destroy a hook', (done) => { const hooks = Hook.allGlobalSync(); const hook = hooks[hooks.length-1].id; - let getUrl = utils.checksumAPI(Helpers.url + Helpers.destroyUrl(hook), config.bbb.sharedSecret); + let getUrl = utils.checksumAPI(Helpers.url + Helpers.destroyUrl(hook), sharedSecret); getUrl = Helpers.destroyUrl(hook) + '&checksum=' + getUrl request(Helpers.url) @@ -103,7 +105,7 @@ describe('bbb-webhooks tests', () => { describe('GET /hooks/destroy permanent hook', () => { it('should not destroy the permanent hook', (done) => { - let getUrl = utils.checksumAPI(Helpers.url + Helpers.destroyPermanent, config.bbb.sharedSecret); + let getUrl = utils.checksumAPI(Helpers.url + Helpers.destroyPermanent, sharedSecret); getUrl = Helpers.destroyPermanent + '&checksum=' + getUrl request(Helpers.url) .get(getUrl) @@ -126,7 +128,7 @@ describe('bbb-webhooks tests', () => { Hook.removeSubscription(hooks[hooks.length-1].id, () => { done(); }); }); it('should create a hook with getRaw=true', (done) => { - let getUrl = utils.checksumAPI(Helpers.url + Helpers.createUrl + Helpers.createRaw, config.bbb.sharedSecret); + let getUrl = utils.checksumAPI(Helpers.url + Helpers.createUrl + Helpers.createRaw, sharedSecret); getUrl = Helpers.createUrl + '&checksum=' + getUrl + Helpers.createRaw request(Helpers.url) diff --git a/bbb-webhooks/web_hooks.js b/bbb-webhooks/web_hooks.js index a91718f1e889e6724f1ec35b095f7011f5c4919c..c00a2cf0b14c5eb2af40d16eeeb399fdd089c266 100644 --- a/bbb-webhooks/web_hooks.js +++ b/bbb-webhooks/web_hooks.js @@ -69,7 +69,7 @@ module.exports = class WebHooks { } } } catch (e) { - Logger.error("[WebHooks] error processing the message:", JSON.stringify(raw), ":", e); + Logger.error("[WebHooks] error processing the message:", JSON.stringify(raw), ":", e.message); } }); diff --git a/bbb-webhooks/web_server.js b/bbb-webhooks/web_server.js index e0f77f0b405a6d7c55e3052ae6fd4d11136137dc..be5a0057836e696141adbd44e51349569678808f 100644 --- a/bbb-webhooks/web_server.js +++ b/bbb-webhooks/web_server.js @@ -144,8 +144,9 @@ module.exports = class WebServer { _validateChecksum(req, res, next) { const urlObj = url.parse(req.url, true); const checksum = urlObj.query["checksum"]; + const sharedSecret = process.env.SHARED_SECRET || config.bbb.sharedSecret; - if (checksum === Utils.checksumAPI(req.url, config.bbb.sharedSecret)) { + if (checksum === Utils.checksumAPI(req.url, sharedSecret)) { next(); } else { Logger.info("[WebServer] checksum check failed, sending a checksumError response"); diff --git a/bigbluebutton-html5/.dockerignore b/bigbluebutton-html5/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..bf9b07fdc25d27e22a5052d1d5801bf882fb2f88 --- /dev/null +++ b/bigbluebutton-html5/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +Dockerfile.dev diff --git a/bigbluebutton-html5/Dockerfile b/bigbluebutton-html5/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..8e4b24cb172a218115b648bd67c6002ab5ed796f --- /dev/null +++ b/bigbluebutton-html5/Dockerfile @@ -0,0 +1,38 @@ +FROM node:8 + +RUN set -x \ + && curl -sL https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh \ + && useradd -m -G users -s /bin/bash meteor + +RUN apt-get update && apt-get -y install jq + +COPY . /source + +RUN cd /source \ + && mv docker-entrypoint.sh /usr/local/bin/ \ + && chown -R meteor:meteor . \ + && mkdir /app \ + && chown -R meteor:meteor /app + +USER meteor + +RUN cd /source \ + && meteor npm install \ + && meteor build --directory /app + +ENV NODE_ENV production + +RUN cd /app/bundle/programs/server \ + && npm install \ + && npm cache clear --force + +WORKDIR /app/bundle + +ENV MONGO_URL=mongodb://mongo:27017/html5client \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 \ + METEOR_SETTINGS_MODIFIER=. + +EXPOSE 3000 + +CMD ["docker-entrypoint.sh"] diff --git a/bigbluebutton-html5/Dockerfile.dev b/bigbluebutton-html5/Dockerfile.dev new file mode 100644 index 0000000000000000000000000000000000000000..692c200be719aca865919535210674ff871c76ee --- /dev/null +++ b/bigbluebutton-html5/Dockerfile.dev @@ -0,0 +1,24 @@ +FROM node:8 + +COPY . /source + +RUN set -x \ + && curl -sL https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh \ + && useradd -m -G users -s /bin/bash meteor \ + && chown -R meteor:meteor /source + +USER meteor + +RUN cd /source \ + && meteor npm install + +WORKDIR /source + +ENV MONGO_URL=mongodb://mongo:27017/html5client \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 + +EXPOSE 3000 + +CMD ["npm", "start"] + diff --git a/bigbluebutton-html5/docker-entrypoint.sh b/bigbluebutton-html5/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..951269c88166e2c753ad2996e39c5711d0685d2f --- /dev/null +++ b/bigbluebutton-html5/docker-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +export METEOR_SETTINGS=` jq "${METEOR_SETTINGS_MODIFIER}" ./programs/server/assets/app/config/settings-production.json ` + +node main.js diff --git a/bigbluebutton-html5/imports/startup/server/redis.js b/bigbluebutton-html5/imports/startup/server/redis.js index a91d2b7bc006c03e09bd35f54d56d003ee88bb9b..470211fab12d232ab008c5bd26e0e7f04bdfb536 100644 --- a/bigbluebutton-html5/imports/startup/server/redis.js +++ b/bigbluebutton-html5/imports/startup/server/redis.js @@ -105,8 +105,9 @@ class RedisPubSub { this.config = config; this.didSendRequestEvent = false; - this.pub = Redis.createClient(); - this.sub = Redis.createClient(); + const redisHost = process.env.REDIS_HOST || Meteor.settings.private.redis.host; + this.pub = Redis.createClient(Meteor.settings.private.redis.port, redisHost); + this.sub = Redis.createClient(Meteor.settings.private.redis.port, redisHost); this.emitter = new EventEmitter2(); this.mettingsQueues = {}; diff --git a/bigbluebutton-web/.dockerignore b/bigbluebutton-web/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..94143827ed065ca0d7d5be1b765d255c5c32cd9a --- /dev/null +++ b/bigbluebutton-web/.dockerignore @@ -0,0 +1 @@ +Dockerfile diff --git a/bigbluebutton-web/Dockerfile b/bigbluebutton-web/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..a980f59723ee51b198144ccc7e16ca46f36322f3 --- /dev/null +++ b/bigbluebutton-web/Dockerfile @@ -0,0 +1,64 @@ +FROM bbb-common-web AS builder + +RUN mkdir -p /root/tools \ + && cd /root/tools \ + && wget http://services.gradle.org/distributions/gradle-2.12-bin.zip \ + && unzip gradle-2.12-bin.zip \ + && ln -s gradle-2.12 gradle + +RUN mkdir -p /root/tools \ + && cd /root/tools \ + && wget https://github.com/grails/grails-core/releases/download/v2.5.2/grails-2.5.2.zip \ + && unzip grails-2.5.2.zip \ + && ln -s grails-2.5.2 grails + +ENV PATH="/root/tools/gradle/bin:/root/tools/grails/bin:${PATH}" + +ARG COMMON_VERSION=0.0.1-SNAPSHOT + +COPY . /source + +RUN cd /source \ + && find -name build.gradle -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-message[^:]*\):.*|\1:$COMMON_VERSION'|g" {} \; \ + && find -name build.gradle -exec sed -i "s|\(.*org.bigbluebutton.*bbb-common-web[^:]*\):.*|\1:$COMMON_VERSION'|g" {} \; + +RUN cd /source \ + && gradle resolveDeps \ + && grails war + +FROM tomcat:7-jre8 + +WORKDIR $CATALINA_HOME + +ENV DOCKERIZE_VERSION v0.6.1 +RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update \ + && apt-get -y install imagemagick xpdf-utils netcat libreoffice ttf-liberation fonts-crosextra-carlito fonts-crosextra-caladea unzip procps \ + && wget http://ftp.us.debian.org/debian/pool/main/libj/libjpeg8/libjpeg8_8d-1+deb7u1_amd64.deb \ + && dpkg -i libjpeg8*.deb \ + && rm libjpeg8*.deb + +RUN echo "deb http://ubuntu.bigbluebutton.org/xenial-200-dev bigbluebutton-xenial main " | tee /etc/apt/sources.list.d/bigbluebutton.list \ + && wget http://ubuntu.bigbluebutton.org/repo/bigbluebutton.asc -O- | apt-key add - \ + && apt-get update \ + && apt-get -y install bbb-swftools + +# clean default webapps +RUN rm -r webapps/* + +COPY --from=builder /source/target/bigbluebutton-0.9.0.war webapps/bigbluebutton.war + +RUN unzip -q webapps/bigbluebutton.war -d webapps/bigbluebutton \ + && rm webapps/bigbluebutton.war + +COPY turn-stun-servers.xml.tmpl turn-stun-servers.xml.tmpl + +COPY docker-entrypoint.sh /usr/local/bin/ + +CMD [ "dockerize", \ + "-template", "turn-stun-servers.xml.tmpl:webapps/bigbluebutton/WEB-INF/spring/turn-stun-servers.xml", \ + "docker-entrypoint.sh" ] diff --git a/bigbluebutton-web/docker-entrypoint.sh b/bigbluebutton-web/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..460ef6c5197aac1d08440c500359895ac7325d55 --- /dev/null +++ b/bigbluebutton-web/docker-entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/bash -xe + +mkdir -p /var/bigbluebutton/recording/raw +mkdir -p /var/bigbluebutton/recording/process +mkdir -p /var/bigbluebutton/recording/publish +mkdir -p /var/bigbluebutton/recording/status/recorded +mkdir -p /var/bigbluebutton/recording/status/archived +mkdir -p /var/bigbluebutton/recording/status/processed +mkdir -p /var/bigbluebutton/recording/status/sanity +mkdir -p /var/bigbluebutton/published +mkdir -p /var/bigbluebutton/deleted +mkdir -p /var/bigbluebutton/unpublished + +export JAVA_OPTS="${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -DsecuritySalt=${SHARED_SECRET} -Dredis.host=redis -DredisHost=redis -Dbigbluebutton.web.serverURL=https://${SERVER_DOMAIN} -DattendeesJoinViaHTML5Client=true -DmoderatorsJoinViaHTML5Client=true -DsvgImagesRequired=true" +sed -i "s|^securerandom\.source=.*|securerandom.source=file:/dev/urandom|g" ${JAVA_HOME}/lib/security/java.security + +catalina.sh run diff --git a/bigbluebutton-web/grails-app/conf/Config.groovy b/bigbluebutton-web/grails-app/conf/Config.groovy index cd9d36a9d343d06031c92165dfa34f6729eeaa8a..230e3f8feb790666eb17745f327a5065cce133a6 100755 --- a/bigbluebutton-web/grails-app/conf/Config.groovy +++ b/bigbluebutton-web/grails-app/conf/Config.groovy @@ -130,5 +130,7 @@ log4j = { 'org.hibernate', 'net.sf.ehcache.hibernate' - debug 'org.bigbluebutton' + debug 'org.bigbluebutton', + 'grails.app.controllers', + 'grails.app.services' } diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index 3fc7319b825cd577f15ebc72f422f3db282bcab2..59dadbe41c25e64abc0378480a61eeb513168ba3 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -419,28 +419,11 @@ class ApiController { } } else { Config conf = meeting.getDefaultConfig(); - if (conf == null) { - // BEGIN - backward compatibility - invalid("noConfigFound","We could not find a config for this request.", REDIRECT_RESPONSE); - return - // END - backward compatibility - - errors.noConfigFound(); - respondWithErrors(errors); - } else { - configxml = conf.config; - } + configxml = conf.config; } - if (StringUtils.isEmpty(configxml)) { - // BEGIN - backward compatibility - invalid("noConfigFound","We could not find a config for this request.", REDIRECT_RESPONSE); - return - // END - backward compatibility + // Do not fail if there's no default config.xml, needed for an HTML5 client only scenario - errors.noConfigFound(); - respondWithErrors(errors); - } UserSession us = new UserSession(); us.authToken = authToken; us.internalUserId = internalUserID @@ -1217,6 +1200,16 @@ class ApiController { String defConfigXML = paramsProcessorUtil.getDefaultConfigXML(); + if (StringUtils.isEmpty(defConfigXML)) { + // BEGIN - backward compatibility + invalid("noConfigFound","We could not find a config for this request.", REDIRECT_RESPONSE); + return + // END - backward compatibility + + errors.noConfigFound(); + respondWithErrors(errors); + } + response.addHeader("Cache-Control", "no-cache") render text: defConfigXML, contentType: 'text/xml' } @@ -1258,6 +1251,16 @@ class ApiController { } } } else { + if (StringUtils.isEmpty(us.configXML)) { + // BEGIN - backward compatibility + invalid("noConfigFound","We could not find a config for this request.", REDIRECT_RESPONSE); + return + // END - backward compatibility + + errors.noConfigFound(); + respondWithErrors(errors); + } + Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", us.meetingID); logData.put("externalMeetingId", us.externMeetingID); diff --git a/bigbluebutton-web/turn-stun-servers.xml.tmpl b/bigbluebutton-web/turn-stun-servers.xml.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..534aff29501418b0e92c77d58c4ba5616a9cd93f --- /dev/null +++ b/bigbluebutton-web/turn-stun-servers.xml.tmpl @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + +BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + +Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below). + +This program is free software; you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free Software +Foundation; either version 3.0 of the License, or (at your option) any later +version. + +BigBlueButton 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd + "> + + <bean id="stun1" class="org.bigbluebutton.web.services.turn.StunServer"> + <constructor-arg index="0" value="stun:{{ .Env.TURN_DOMAIN }}:3478"/> + </bean> + + <bean id="turn1" class="org.bigbluebutton.web.services.turn.TurnServer"> + <constructor-arg index="0" value="{{ .Env.TURN_SECRET }}"/> + <constructor-arg index="1" value="turn:{{ .Env.TURN_DOMAIN }}:3478"/> + <constructor-arg index="2" value="86400"/> + </bean> + + <bean id="turn2" class="org.bigbluebutton.web.services.turn.TurnServer"> + <constructor-arg index="0" value="{{ .Env.TURN_SECRET }}"/> + <constructor-arg index="1" value="turn:{{ .Env.TURN_DOMAIN }}:3478?transport=tcp"/> + <constructor-arg index="2" value="86400"/> + </bean> + + <bean id="stunTurnService" class="org.bigbluebutton.web.services.turn.StunTurnService"> + <property name="stunServers"> + <set> + <ref bean="stun1" /> + </set> + </property> + <property name="turnServers"> + <set> + <ref bean="turn1" /> + <ref bean="turn2" /> + </set> + </property> + <property name="remoteIceCandidates"> + <set/> + </property> + </bean> +</beans> diff --git a/labs/bbb-webrtc-sfu/Dockerfile b/labs/bbb-webrtc-sfu/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..ebba290ee6887c5df9ec7f5424a8fe6deb40fb77 --- /dev/null +++ b/labs/bbb-webrtc-sfu/Dockerfile @@ -0,0 +1,17 @@ +FROM node:8 + +ADD . /source +RUN cp /source/config/default.example.yml /source/config/production.yml + +ENV NODE_ENV production + +RUN cd /source \ + && mv docker-entrypoint.sh /usr/local/bin/ \ + && npm install \ + && npm cache clear --force + +WORKDIR /source + +EXPOSE 3008 + +CMD [ "docker-entrypoint.sh" ] diff --git a/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml b/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml new file mode 100644 index 0000000000000000000000000000000000000000..074de09626d59cbb357795d1c39eb81d35f51044 --- /dev/null +++ b/labs/bbb-webrtc-sfu/config/custom-environment-variables.yml @@ -0,0 +1,7 @@ +kurentoUrl: KURENTO_URL +kurentoIp: KURENTO_IP +redisHost: REDIS_HOST +freeswitch: + ip: FREESWITCH_IP +log: + level: LOG_LEVEL diff --git a/labs/bbb-webrtc-sfu/docker-entrypoint.sh b/labs/bbb-webrtc-sfu/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..d424e511a15e8814d6dbb9fad53b62c07729b2d6 --- /dev/null +++ b/labs/bbb-webrtc-sfu/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash -e + +CONTAINER_IP=$(hostname -I | awk '{print $1}') + +sed -i "s|^\(localIpAddress\):.*|\1: \"$CONTAINER_IP\"|g" config/production.yml + +if [ ! -z "$KURENTO_NAME" ]; then + export KURENTO_IP=$(getent hosts $KURENTO_NAME | awk '{ print $1 }') +fi + +npm start diff --git a/labs/docker/Makefile b/labs/docker/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..63d7fb33b4acdddd21284585f94c651199b5ecf5 --- /dev/null +++ b/labs/docker/Makefile @@ -0,0 +1,57 @@ +SHELL=/bin/bash + +# in order to build images for bigbluebutton/bigbluebutton-docker, run: +# IMAGE_ACCOUNT=bigbluebutton IMAGE_REPO=bigbluebutton-docker make release + +# build options +BUILD_REVISION=`git rev-parse --short HEAD` +BUILD_DIR_BASE=`git rev-parse --git-dir`/.. +BUILD_VERSION?= +BUILD_IMAGE=0 +IMAGE_ACCOUNT?= +IMAGE_REPO?= +IMAGE_TAG=latest +TAG_REVISION?=0 + +all: release + +image: + -cd $(DIR) && docker build -t $(IMAGE_NAME):$(IMAGE_TAG) $(BUILD_ARGS) . + if [ "$(BUILD_IMAGE)" == "0" ]; then \ + if [ "$(IMAGE_ACCOUNT)" != "" ]; then \ + if [ "$(IMAGE_REPO)" != "" ]; then \ + docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(IMAGE_ACCOUNT)/$(IMAGE_REPO):$(IMAGE_NAME); \ + if [ "$(TAG_REVISION)" == "1" ]; then \ + docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(IMAGE_ACCOUNT)/$(IMAGE_REPO):$(IMAGE_NAME)-$(BUILD_REVISION); \ + fi \ + fi \ + else \ + if [ "$(IMAGE_REPO)" != "" ]; then \ + docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(IMAGE_REPO):$(IMAGE_NAME); \ + if [ "$(TAG_REVISION)" == "1" ]; then \ + docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(IMAGE_REPO):$(IMAGE_NAME)-$(BUILD_REVISION); \ + fi \ + else \ + if [ "$(TAG_REVISION)" == "1" ]; then \ + docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(IMAGE_NAME):$(BUILD_REVISION); \ + fi \ + fi \ + fi \ + fi + +release: + make image DIR=$(BUILD_DIR_BASE)/labs/docker/sbt IMAGE_NAME=sbt IMAGE_TAG=0.13.8 BUILD_IMAGE=1 + make image DIR=$(BUILD_DIR_BASE)/bbb-common-message IMAGE_NAME=bbb-common-message BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" BUILD_IMAGE=1 + make image DIR=$(BUILD_DIR_BASE)/bbb-common-web IMAGE_NAME=bbb-common-web BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" BUILD_IMAGE=1 + make image DIR=$(BUILD_DIR_BASE)/bbb-fsesl-client IMAGE_NAME=bbb-fsesl-client BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" BUILD_IMAGE=1 + make image DIR=$(BUILD_DIR_BASE)/akka-bbb-apps IMAGE_NAME=bbb-apps-akka BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" + make image DIR=$(BUILD_DIR_BASE)/akka-bbb-fsesl IMAGE_NAME=bbb-fsesl-akka BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" + make image DIR=$(BUILD_DIR_BASE)/bigbluebutton-web IMAGE_NAME=bbb-web BUILD_ARGS="--build-arg COMMON_VERSION=0.0.1-SNAPSHOT" + make image DIR=$(BUILD_DIR_BASE)/bigbluebutton-html5 IMAGE_NAME=bbb-html5 + make image DIR=$(BUILD_DIR_BASE)/labs/bbb-webrtc-sfu IMAGE_NAME=bbb-webrtc-sfu + make image DIR=$(BUILD_DIR_BASE)/bbb-webhooks IMAGE_NAME=bbb-webhooks + make image DIR=$(BUILD_DIR_BASE)/labs/docker/kurento IMAGE_NAME=bbb-kurento + make image DIR=$(BUILD_DIR_BASE)/labs/docker/freeswitch IMAGE_NAME=bbb-freeswitch + make image DIR=$(BUILD_DIR_BASE)/labs/docker/nginx IMAGE_NAME=bbb-nginx + make image DIR=$(BUILD_DIR_BASE)/labs/docker/coturn IMAGE_NAME=bbb-coturn + make image DIR=$(BUILD_DIR_BASE)/bbb-lti IMAGE_NAME=bbb-lti diff --git a/labs/docker/README.md b/labs/docker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..654d2201a6633e6810e84b566893f62e4d4db29b --- /dev/null +++ b/labs/docker/README.md @@ -0,0 +1,274 @@ +IMPORTANT: this is a work in progress! + +# Purpose + +The purpose of this repo is to get BigBlueButton working in a multi-container Docker configuration over a single port, then to deploy and scale it using Kubernetes + +# Launching BBB via Docker + +## Prerequisites + +#### Ensure you have the latest version of Docker-CE by following the install steps + +Ubuntu: https://docs.docker.com/install/linux/docker-ce/ubuntu/ + +Fedora: https://docs.docker.com/install/linux/docker-ce/fedora/ + +#### Make sure to also do the post install steps + +https://docs.docker.com/install/linux/linux-postinstall/ + +#### Install docker-compose + +Ubuntu: +``` +sudo apt-get install docker-compose +``` + +Fedora: +``` +sudo dnf install docker-compose +``` + +## Build all docker images + +#### Build all docker images with one command +``` +cd labs/docker/ +make release +``` + +#### Verify that you have all the necessary images +``` +docker images +``` + +You should see: +* sbt +* bbb-common-message +* bbb-common-web +* bbb-fsesl-client +* bbb-apps-akka +* bbb-fsesl-akka +* bbb-web +* bbb-html5 +* bbb-webrtc-sfu +* bbb-webhooks +* bbb-kurento +* bbb-freeswitch +* bbb-nginx +* bbb-coturn +* bbb-lti + + +In the event that any of the above images are missing, you'll need to build them individually + +## Build images individually + +sbt is needed to build the Scala components +``` +cd labs/docker/sbt/ +docker build -t 'sbt:0.13.8' . +``` + +Build libraries +``` +cd bbb-common-message/ +docker build -t 'bbb-common-message' --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . + +cd bbb-common-web/ +docker build -t 'bbb-common-web' --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . + +cd bbb-fsesl-client/ +docker build -t 'bbb-fsesl-client' --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . +``` + +Build akka components +``` +cd akka-bbb-apps/ +docker build -t bbb-apps-akka --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . + +# Not needed since we're setting up HTML5 only +cd akka-bbb-transcode/ +docker build -t bbb-transcode --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . + +cd akka-bbb-fsesl/ +docker build -t bbb-fsesl-akka --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . +``` + +Build bbb-web +``` +cd bigbluebutton-web/ +docker build -t bbb-web --build-arg COMMON_VERSION=0.0.1-SNAPSHOT . +``` + +Build bbb-html5 +``` +cd bigbluebutton-html5/ +docker build -t bbb-html5 . +``` + +Build bbb-webrtc-sfu +``` +cd labs/bbb-webrtc-sfu/ +docker build -t bbb-webrtc-sfu . +``` + +Build bbb-webhooks +``` +cd bbb-webhooks/ +docker build -t bbb-webhooks . +``` + +Build Kurento Media Server +``` +cd labs/docker/kurento/ +docker build -t bbb-kurento . +``` + +Build FreeSWITCH +``` +cd labs/docker/freeswitch/ +docker build -t bbb-freeswitch . +``` + +Build nginx +``` +cd labs/docker/nginx/ +docker build -t bbb-nginx . +``` + +Build coturn +``` +cd labs/docker/coturn +docker build -t bbb-coturn . +``` + +(Optional) Build bbb-lti +``` +cd bbb-lti/ +docker build -t bbb-lti . +``` + +## Setup + +#### Export your configuration as environment variables +NOTE: replace the example SERVER_DOMAIN's value with your own FQDN +``` +export SERVER_DOMAIN=docker.bigbluebutton.org +export EXTERNAL_IP=$(dig +short $SERVER_DOMAIN | grep '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$' | head -n 1) +export SHARED_SECRET=`openssl rand -hex 16` +export COTURN_REST_SECRET=`openssl rand -hex 16` +export SECRET_KEY_BASE=`openssl rand -hex 64` +export SCREENSHARE_EXTENSION_KEY=akgoaoikmbmhcopjgakkcepdgdgkjfbc +export SCREENSHARE_EXTENSION_LINK=https://chrome.google.com/webstore/detail/bigbluebutton-screenshare/akgoaoikmbmhcopjgakkcepdgdgkjfbc +export TAG_PREFIX= +export TAG_SUFFIX= +``` + +#### Create a volume for the SSL certs +``` +docker volume create docker_ssl-conf +``` + +#### Generate SSL certs +``` +docker run --rm -p 80:80 -v docker_ssl-conf:/etc/letsencrypt -it certbot/certbot certonly --non-interactive --register-unsafely-without-email --agree-tos --expand --domain $SERVER_DOMAIN --standalone + +# certificate path: docker_ssl-conf/live/$SERVER_DOMAIN/fullchain.pem +# key path: docker_ssl-conf/live/$SERVER_DOMAIN/privkey.pem +``` +NOTE: If running on AWS, you won't be able to use the default Public DNS for your SERVER_DOMAIN as Let's Encrypt doesn't allow generating SSL certs from any *.amazonaws.com domain. Alternatively, you can create a PTR record that goes from a non-AWS FQDN to the AWS FQDN. + +#### Create a volume for the static files (optional) +``` +docker volume create docker_static +cd bigbluebutton-config/web/ +docker run -d --rm --name nginx -v docker_static:/var/www/bigbluebutton-default nginx tail -f /dev/null +docker cp . nginx:/var/www/bigbluebutton-default +docker exec -it nginx chown -R www-data:www-data /var/www/bigbluebutton-default +docker stop nginx +``` + +#### Ensure the following ports are open +* TCP/UDP 3478 +* TCP 80 +* TCP 443 + +## Run + +#### Launch everything with docker compose +``` +cd labs/docker/ +docker-compose up +``` + +#### Access your server via greenlight and create meetings + +https://<your_fqdn_here>/b + +#### To shut down and exit gracefully +``` +CTRL+C +``` + + +# Setting up a Kubernetes Cluster + +## Prerequisites + +#### Install kubeadm, kubelet, and kubectl + +https://kubernetes.io/docs/setup/independent/install-kubeadm/ + +#### Disable swap by commenting out the "swap" line in /etc/fstab, then do a reboot +``` +sudo vi /etc/fstab +sudo systemctl reboot +``` + +#### Verify swap is disabled +``` +sudo free -h +``` + +#### Install Minikube + +https://kubernetes.io/docs/tasks/tools/install-minikube/ + +#### Install VirtualBox Manager + +Ubuntu: +``` +sudo apt-get install virtualbox +``` + +Fedora: +``` +sudo dnf install virtualbox +``` + +## Setup + +#### The following kernel modules are required to avoid preflight errors and warnings during cluster setup +* ip_vs +* ip_vs_rr +* ip_vs_wrr +* ip_vs_sh + +#### Check if kernel modules are already loaded +``` +lsmod | grep ip_vs +``` + +#### Add the kernel modules (if not already loaded) +``` +sudo modprobe ip_vs +sudo modprobe ip_vs_rr +sudo modprobe ip_vs_wrr +sudo modprobe ip_vs_sh +``` + +#### Create a single master cluster with kubeadm + +https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ diff --git a/labs/docker/coturn/Dockerfile b/labs/docker/coturn/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..aa4912ae026922b53caff6ecbef5e988f5606b1b --- /dev/null +++ b/labs/docker/coturn/Dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y coturn wget + +ENV DOCKERIZE_VERSION v0.6.1 +RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz + +COPY ./turnserver.conf.tmpl /etc/turnserver.conf.tmpl + +CMD [ "dockerize", \ + "-template", "/etc/turnserver.conf.tmpl:/etc/turnserver.conf", \ + "turnserver", "--syslog" ] diff --git a/labs/docker/coturn/turnserver.conf.tmpl b/labs/docker/coturn/turnserver.conf.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..c9810fb8229d2ab440e91ffea1f56cfd73dc0fee --- /dev/null +++ b/labs/docker/coturn/turnserver.conf.tmpl @@ -0,0 +1,14 @@ +listening-port={{ .Env.PORT }} +min-port=49152 +max-port=65535 +fingerprint +lt-cred-mech +realm={{ .Env.SERVER_DOMAIN }} +external-ip={{ .Env.EXTERNAL_IP }} + +{{ if isTrue .Env.ENABLE_REST_API }} +use-auth-secret +static-auth-secret={{ .Env.SECRET }} +{{ else }} +user={{ .Env.LT_USER }}:{{ .Env.LT_SECRET }} +{{ end }} diff --git a/labs/docker/docker-compose.yml b/labs/docker/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..08d4ecb6644d5a3561dfcd465481a320e3cea6ab --- /dev/null +++ b/labs/docker/docker-compose.yml @@ -0,0 +1,183 @@ +version: '2' + +services: + mongo: + image: mongo:3.4 + restart: unless-stopped + + redis: + image: redis + restart: unless-stopped + + bbb-html5: + image: ${TAG_PREFIX}bbb-html5${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - mongo + - redis + environment: + MONGO_URL: mongodb://mongo/bbbhtml5 + METEOR_SETTINGS_MODIFIER: ".public.kurento.wsUrl = \"wss://${SERVER_DOMAIN}/bbb-webrtc-sfu\" | .public.kurento.enableVideo = true | .public.kurento.enableScreensharing = true | .public.kurento.chromeDefaultExtensionKey = \"${SCREENSHARE_EXTENSION_KEY}\" | .public.kurento.chromeDefaultExtensionLink = \"${SCREENSHARE_EXTENSION_LINK}\" | .public.kurento.enableVideoStats = true | .public.kurento.enableListenOnly = true" + REDIS_HOST: redis + ROOT_URL: http://127.0.0.1/html5client + labels: + - "traefik.backend=bbb-html5" + - "traefik.frontend.rule=PathPrefix: /html5client,/_timesync" + + bbb-webhooks: + image: ${TAG_PREFIX}bbb-webhooks${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - redis + environment: + REDIS_HOST: redis + SHARED_SECRET: ${SHARED_SECRET} + BEARER_AUTH: 1 + SERVER_DOMAIN: ${SERVER_DOMAIN} + labels: + - "traefik.backend=bbb-webhooks" + - "traefik.frontend.rule=PathPrefix: /bigbluebutton/api/hooks" + + bbb-freeswitch: + image: ${TAG_PREFIX}bbb-freeswitch${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - coturn + volumes: + - media-audio:/var/freeswitch/meetings + + bbb-webrtc-sfu: + image: ${TAG_PREFIX}bbb-webrtc-sfu${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - redis + - kurento + - bbb-freeswitch + environment: + KURENTO_NAME: kurento + KURENTO_URL: ws://kurento:8888/kurento + REDIS_HOST: redis + FREESWITCH_IP: bbb-freeswitch + LOG_LEVEL: debug + labels: + - "traefik.backend=bbb-webrtc-sfu" + - "traefik.frontend.rule=PathPrefix: /bbb-webrtc-sfu" + + coturn: + image: ${TAG_PREFIX}bbb-coturn${TAG_SUFFIX} + restart: unless-stopped + environment: + TURN_DOMAIN: ${SERVER_DOMAIN} + SECRET: ${COTURN_REST_SECRET} + EXTERNAL_IP: ${EXTERNAL_IP} + ENABLE_REST_API: 1 + PORT: 3478 + ports: + - 3478:3478/udp + - 3478:3478/tcp + + kurento: + image: ${TAG_PREFIX}bbb-kurento${TAG_SUFFIX} + restart: unless-stopped + volumes: + - media-video:/var/kurento/recordings + - media-screenshare:/var/kurento/screenshare + environment: + KMS_STUN_IP: ${EXTERNAL_IP} + KMS_STUN_PORT: 3478 + + bbb-apps-akka: + image: ${TAG_PREFIX}bbb-apps-akka${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - redis + environment: + JAVA_OPTS: -Dredis.host=redis + + bbb-fsesl-akka: + image: ${TAG_PREFIX}bbb-fsesl-akka${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - bbb-freeswitch + - redis + command: ["wait-for-it.sh", "bbb-freeswitch:8021", "--timeout=60", "--strict", "--", "/usr/share/bbb-fsesl-akka/bin/bbb-fsesl-akka"] + environment: + JAVA_OPTS: -Dredis.host=redis -Dfreeswitch.esl.host=bbb-freeswitch + + bbb-web: + image: ${TAG_PREFIX}bbb-web${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - redis + volumes: + - bigbluebutton:/var/bigbluebutton + environment: + SERVER_DOMAIN: ${SERVER_DOMAIN} + SHARED_SECRET: ${SHARED_SECRET} + TURN_DOMAIN: ${SERVER_DOMAIN} + TURN_SECRET: ${COTURN_REST_SECRET} + labels: + - "traefik.backend=bbb-web" + - "traefik.frontend.rule=PathPrefix: /bigbluebutton" + + bbb-greenlight: + image: bigbluebutton/greenlight:v2 + restart: unless-stopped + volumes: + - greenlight_db:/usr/src/app/db/production + - greenlight_logs:/usr/src/app/log + environment: + BIGBLUEBUTTON_ENDPOINT: https://${SERVER_DOMAIN}/bigbluebutton/ + BIGBLUEBUTTON_SECRET: ${SHARED_SECRET} + SECRET_KEY_BASE: ${SECRET_KEY_BASE} + ALLOW_GREENLIGHT_ACCOUNTS: "true" + labels: + - "traefik.backend=bbb-greenlight" + - "traefik.frontend.rule=PathPrefix: /b" + + # when we're able to setup traefik properly for wss, nginx is no longer needed + nginx: + image: ${TAG_PREFIX}bbb-nginx${TAG_SUFFIX} + restart: unless-stopped + depends_on: + - bbb-freeswitch + environment: + SERVER_DOMAIN: ${SERVER_DOMAIN} + labels: + - "traefik.backend=bbb-freeswitch" + - "traefik.frontend.rule=PathPrefix: /ws" + + traefik: + image: traefik + restart: unless-stopped + ports: + - 80:80 + - 8080:8080 + - 443:443 + command: traefik + - --docker + - --logLevel=INFO + - --acme + - --acme.httpchallenge + - --acme.httpchallenge.entrypoint=http + - --acme.acmelogging + - --acme.storage=/etc/traefik/acme/acme.json + - --acme.email=felipe@mconf.com + - --acme.entrypoint=https + - --acme.domains=${SERVER_DOMAIN} + - --defaultentrypoints=http,https + - --entryPoints='Name:http Address::80 Redirect.EntryPoint:https' + - --entryPoints='Name:https Address::443 TLS' + volumes: + - traefik-acme:/etc/traefik/acme/ + - /var/run/docker.sock:/var/run/docker.sock + +volumes: + traefik-acme: + static: + bigbluebutton: + media-audio: + media-video: + media-screenshare: + greenlight_db: + greenlight_logs: diff --git a/labs/docker/freeswitch/Dockerfile b/labs/docker/freeswitch/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..86865a8fb847ec0af679b46ce674cd386697d596 --- /dev/null +++ b/labs/docker/freeswitch/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:16.04 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update \ + && apt-get -y install wget libedit-dev xmlstarlet + +RUN echo "deb http://ubuntu.bigbluebutton.org/xenial-200-dev bigbluebutton-xenial main " | tee /etc/apt/sources.list.d/bigbluebutton.list \ + && wget http://ubuntu.bigbluebutton.org/repo/bigbluebutton.asc -O- | apt-key add - \ + && apt-get update \ + && apt-get -y install bbb-freeswitch-core \ + && find /opt/freeswitch/conf/sip_profiles/ -name "*ipv6*" -prune -exec rm -rf "{}" \; + +EXPOSE 7443 + +COPY docker-entrypoint.sh /usr/local/bin/ +COPY event_socket_conf.xml /opt/freeswitch/conf/autoload_configs/event_socket.conf.xml + +RUN wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 \ + && chmod +x /usr/local/bin/dumb-init + +ENTRYPOINT ["/usr/local/bin/dumb-init", "--"] + +CMD [ "docker-entrypoint.sh" ] diff --git a/labs/docker/freeswitch/docker-entrypoint.sh b/labs/docker/freeswitch/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..90e82ba379894259f46797fe6e166406a4ad0bfb --- /dev/null +++ b/labs/docker/freeswitch/docker-entrypoint.sh @@ -0,0 +1,14 @@ +#!/bin/bash -xe + +IP=$(hostname -I | cut -d' ' -f1) + +xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_rtp_ip=")]/@data' --value "stun:coturn" /opt/freeswitch/conf/vars.xml +xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "external_sip_ip=")]/@data' --value "stun:coturn" /opt/freeswitch/conf/vars.xml +xmlstarlet edit --inplace --update '//X-PRE-PROCESS[@cmd="set" and starts-with(@data, "local_ip_v4=")]/@data' --value "${IP}" /opt/freeswitch/conf/vars.xml +# add wss-binding element +xmlstarlet edit --inplace --subnode '//settings' --type elem --name 'newsubnode' --value '' /opt/freeswitch/conf/sip_profiles/external.xml +xmlstarlet edit --inplace --insert '//newsubnode' --type attr --name 'name' --value 'wss-binding' /opt/freeswitch/conf/sip_profiles/external.xml +xmlstarlet edit --inplace --insert '//newsubnode' --type attr --name 'value' --value ':7443' /opt/freeswitch/conf/sip_profiles/external.xml +xmlstarlet edit --inplace --rename '//newsubnode' --value 'param' /opt/freeswitch/conf/sip_profiles/external.xml + +/opt/freeswitch/bin/freeswitch diff --git a/labs/docker/freeswitch/event_socket_conf.xml b/labs/docker/freeswitch/event_socket_conf.xml new file mode 100644 index 0000000000000000000000000000000000000000..c10b16fb1ba4d1ecc42921913373ac049a9347b1 --- /dev/null +++ b/labs/docker/freeswitch/event_socket_conf.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<configuration name="event_socket.conf" description="Socket Client"> + <settings> + <param name="nat-map" value="false"/> + <param name="listen-ip" value="0.0.0.0"/> + <param name="listen-port" value="8021"/> + <param name="password" value="ClueCon"/> + <param name="apply-inbound-acl" value="localnet.auto"/> + </settings> +</configuration> diff --git a/labs/docker/k8s/bbb-apps-akka.yaml b/labs/docker/k8s/bbb-apps-akka.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d21e1d44abe6651aac809d3f5b4040e2bc5237e4 --- /dev/null +++ b/labs/docker/k8s/bbb-apps-akka.yaml @@ -0,0 +1,45 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-apps-akka + version: latest + name: bbb-apps-akka + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-apps-akka + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-apps-akka + version: latest + name: bbb-apps-akka + spec: + containers: + - env: + - name: JAVA_OPTS + value: -Dredis.host=redis + image: fcecagno/bigbluebutton:bbb-apps-akka + imagePullPolicy: Always + name: bbb-apps-akka + ports: + - containerPort: 8080 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule diff --git a/labs/docker/k8s/bbb-coturn.yaml b/labs/docker/k8s/bbb-coturn.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f68eb0cca329a7de723b63db8ce773c79ef93fea --- /dev/null +++ b/labs/docker/k8s/bbb-coturn.yaml @@ -0,0 +1,71 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-coturn + version: latest + name: bbb-coturn + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-coturn + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-coturn + version: latest + name: bbb-coturn + spec: + containers: + - env: + - name: PORT + value: "3478" + - name: SERVER_DOMAIN + value: bigbluebutton.rocket.chat + - name: SECRET + value: "54321" + - name: EXTERNAL_IP + value: "35.185.19.180" + - name: ENABLE_REST_API + value: "1" + image: fcecagno/bigbluebutton:bbb-coturn + imagePullPolicy: Always + name: bbb-coturn + ports: + - containerPort: 3478 + protocol: TCP + - containerPort: 3478 + protocol: UDP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-coturn + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 3478 + port: 3478 + selector: + app: bbb-coturn diff --git a/labs/docker/k8s/bbb-freeswitch-nginx.yaml b/labs/docker/k8s/bbb-freeswitch-nginx.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d550783745d6b122972de76f1b4ef0bf9da861f0 --- /dev/null +++ b/labs/docker/k8s/bbb-freeswitch-nginx.yaml @@ -0,0 +1,79 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-freeswitch-nginx + version: latest + name: bbb-freeswitch-nginx + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-freeswitch-nginx + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-freeswitch-nginx + version: latest + name: bbb-freeswitch-nginx + spec: + containers: + - env: + - name: SERVER_DOMAIN + value: bigbluebutton.rocket.chat + image: fcecagno/bigbluebutton:bbb-nginx + imagePullPolicy: Always + name: bbb-freeswitch-nginx + ports: + - containerPort: 80 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-freeswitch-nginx + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 80 + port: 80 + selector: + app: bbb-freeswitch-nginx + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: bbb-freeswitch-nginx + namespace: bigbluebutton + annotations: + kubernetes.io/ingress.class: "traefik" +spec: + rules: + - host: bigbluebutton.rocket.chat + http: + paths: + - path: /ws + backend: + serviceName: bbb-freeswitch-nginx + servicePort: 80 diff --git a/labs/docker/k8s/bbb-freeswitch.yaml b/labs/docker/k8s/bbb-freeswitch.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6c78e391a0217f34ef3b9385374e06e9851b4282 --- /dev/null +++ b/labs/docker/k8s/bbb-freeswitch.yaml @@ -0,0 +1,58 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-freeswitch + version: latest + name: bbb-freeswitch + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-freeswitch + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-freeswitch + version: latest + name: bbb-freeswitch + spec: + containers: + - image: fcecagno/bigbluebutton:bbb-freeswitch + imagePullPolicy: Always + name: bbb-freeswitch + ports: + - containerPort: 7443 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-freeswitch + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 7443 + port: 7443 + selector: + app: bbb-freeswitch diff --git a/labs/docker/k8s/bbb-fsesl-akka.yaml b/labs/docker/k8s/bbb-fsesl-akka.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b37ba7d94fee4c938cc732ce01e8c7cb93441712 --- /dev/null +++ b/labs/docker/k8s/bbb-fsesl-akka.yaml @@ -0,0 +1,43 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-fsesl-akka + version: latest + name: bbb-fsesl-akka + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-fsesl-akka + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-fsesl-akka + version: latest + name: bbb-fsesl-akka + spec: + containers: + - env: + - name: JAVA_OPTS + value: -Dredis.host=redis -Dfreeswitch.esl.host=bbb-freeswitch + image: fcecagno/bigbluebutton:bbb-fsesl-akka + imagePullPolicy: Always + name: bbb-fsesl-akka + command: ["wait-for-it.sh", "bbb-freeswitch:8021", "--timeout=60", "--strict", "--", "/usr/share/bbb-fsesl-akka/bin/bbb-fsesl-akka"] + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule diff --git a/labs/docker/k8s/bbb-html5.yaml b/labs/docker/k8s/bbb-html5.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cf8fdafcf3b0c3977909121d5de4c1ba2db5f141 --- /dev/null +++ b/labs/docker/k8s/bbb-html5.yaml @@ -0,0 +1,91 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-html5 + version: latest + name: bbb-html5 + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-html5 + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-html5 + version: latest + name: bbb-html5 + spec: + containers: + - env: + - name: MONGO_URL + value: mongodb://mongo:27017/ + - name: MONGO_DB + value: bbbhtml5 + - name: METEOR_SETTINGS_MODIFIER + value: ".public.kurento.wsUrl = \"wss://bigbluebutton.rocket.chat/bbb-webrtc-sfu\" | .public.kurento.enableVideo = true | .public.kurento.enableScreensharing = true | .public.kurento.enableVideoStats = true | .public.kurento.enableListenOnly = true" + - name: REDIS_HOST + value: redis + - name: ROOT_URL + value: http://127.0.0.1/html5client + image: fcecagno/bigbluebutton:bbb-html5 + imagePullPolicy: Always + name: bbb-html5 + ports: + - containerPort: 3000 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-html5 + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 3000 + port: 3000 + selector: + app: bbb-html5 + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: bbb-html5 + namespace: bigbluebutton + annotations: + kubernetes.io/ingress.class: "traefik" +spec: + rules: + - host: bigbluebutton.rocket.chat + http: + paths: + - path: /html5client + backend: + serviceName: bbb-html5 + servicePort: 3000 + - path: /_timesync + backend: + serviceName: bbb-html5 + servicePort: 3000 diff --git a/labs/docker/k8s/bbb-kurento.yaml b/labs/docker/k8s/bbb-kurento.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3c2a0ac6e9fb64b43f7ef32be6a580ecdd5f6607 --- /dev/null +++ b/labs/docker/k8s/bbb-kurento.yaml @@ -0,0 +1,69 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-kurento + version: latest + name: bbb-kurento + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-kurento + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-kurento + version: latest + name: bbb-kurento + spec: + containers: + - env: + - name: KMS_STUN_IP + # TODO: how to get this IP? + value: "35.185.19.180" + - name: KMS_STUN_PORT + value: "3478" + image: fcecagno/bigbluebutton:bbb-kurento + imagePullPolicy: Always + name: bbb-kurento + ports: + - containerPort: 8888 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-kurento + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 8888 + port: 8888 + selector: + app: bbb-kurento + + + # volumes: + # - media-video:/var/kurento/recordings + # - media-screenshare:/var/kurento/screenshare diff --git a/labs/docker/k8s/bbb-web.yaml b/labs/docker/k8s/bbb-web.yaml new file mode 100644 index 0000000000000000000000000000000000000000..784ae337eb475c6f17da7844160ad063166cb394 --- /dev/null +++ b/labs/docker/k8s/bbb-web.yaml @@ -0,0 +1,83 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-web + version: latest + name: bbb-web + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-web + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-web + version: latest + name: bbb-web + spec: + containers: + - env: + - name: SERVER_DOMAIN + value: bigbluebutton.rocket.chat + - name: SHARED_SECRET + value: "12345" + - name: TURN_SECRET + value: "54321" + image: fcecagno/bigbluebutton:bbb-web + imagePullPolicy: Always + name: bbb-web + ports: + - containerPort: 8080 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-web + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 8080 + port: 8080 + selector: + app: bbb-web + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: bbb-web + namespace: bigbluebutton + annotations: + kubernetes.io/ingress.class: "traefik" +spec: + rules: + - host: bigbluebutton.rocket.chat + http: + paths: + - path: /bigbluebutton + backend: + serviceName: bbb-web + servicePort: 8080 diff --git a/labs/docker/k8s/bbb-webhooks.yaml b/labs/docker/k8s/bbb-webhooks.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9239ce01e43844f471ce19b3c8657df49b0d3111 --- /dev/null +++ b/labs/docker/k8s/bbb-webhooks.yaml @@ -0,0 +1,81 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-webhooks + version: latest + name: bbb-webhooks + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-webhooks + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-webhooks + version: latest + name: bbb-webhooks + spec: + containers: + - env: + - name: REDIS_HOST + value: redis + - name: SHARED_SECRET + value: "12345" + image: fcecagno/bigbluebutton:bbb-webhooks + imagePullPolicy: Always + name: bbb-webhooks + ports: + - containerPort: 3005 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-webhooks + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 3005 + port: 3005 + selector: + app: bbb-webhooks + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: bbb-webhooks + namespace: bigbluebutton + annotations: + kubernetes.io/ingress.class: "traefik" +spec: + rules: + - host: bigbluebutton.rocket.chat + http: + paths: + - path: /bigbluebutton/api/hooks + backend: + serviceName: bbb-webhooks + servicePort: 3005 diff --git a/labs/docker/k8s/bbb-webrtc-sfu.yaml b/labs/docker/k8s/bbb-webrtc-sfu.yaml new file mode 100644 index 0000000000000000000000000000000000000000..323622f023a8e7137a6eb53e0abafb1fb39481e3 --- /dev/null +++ b/labs/docker/k8s/bbb-webrtc-sfu.yaml @@ -0,0 +1,87 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: bbb-webrtc-sfu + version: latest + name: bbb-webrtc-sfu + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: bbb-webrtc-sfu + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: bbb-webrtc-sfu + version: latest + name: bbb-webrtc-sfu + spec: + containers: + - env: + - name: KURENTO_NAME + value: kurento + - name: KURENTO_URL + value: ws://kurento:8888/kurento + - name: REDIS_HOST + value: redis + - name: FREESWITCH_IP + value: bbb-freeswitch + - name: LOG_LEVEL + value: debug + image: fcecagno/bigbluebutton:bbb-webrtc-sfu + imagePullPolicy: Always + name: bbb-webrtc-sfu + ports: + - containerPort: 3008 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: bbb-webrtc-sfu + namespace: bigbluebutton + annotations: + traefik.backend.circuitbreaker: "NetworkErrorRatio() > 0.5" +spec: + ports: + - name: http + targetPort: 3008 + port: 3008 + selector: + app: bbb-webrtc-sfu + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: bbb-webrtc-sfu + namespace: bigbluebutton + annotations: + kubernetes.io/ingress.class: "traefik" +spec: + rules: + - host: bigbluebutton.rocket.chat + http: + paths: + - path: /bbb-webrtc-sfu + backend: + serviceName: bbb-webrtc-sfu + servicePort: 3008 diff --git a/labs/docker/k8s/bigbluebutton-ns.yaml b/labs/docker/k8s/bigbluebutton-ns.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d66b7579ed4aae4a45759e7f1ecb3fa3a7d4df8b --- /dev/null +++ b/labs/docker/k8s/bigbluebutton-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bigbluebutton diff --git a/labs/docker/k8s/mongo.yaml b/labs/docker/k8s/mongo.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5a09cdd532b9a840e16bb612914a7cd8f2650933 --- /dev/null +++ b/labs/docker/k8s/mongo.yaml @@ -0,0 +1,55 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: mongo + version: latest + name: mongo + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: mongo + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: mongo + version: latest + name: mongo + spec: + containers: + - image: mongo:3.6 + imagePullPolicy: Always + name: mongo + ports: + - containerPort: 27017 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: mongo + namespace: bigbluebutton +spec: + ports: + - targetPort: 27017 + port: 27017 + selector: + app: mongo diff --git a/labs/docker/k8s/redis.yaml b/labs/docker/k8s/redis.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fe12f4eb193aed1043b39c905d0539f7af0709c2 --- /dev/null +++ b/labs/docker/k8s/redis.yaml @@ -0,0 +1,55 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: redis + version: latest + name: redis + namespace: bigbluebutton +spec: + replicas: 1 + selector: + matchLabels: + app: redis + version: latest + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app: redis + version: latest + name: redis + spec: + containers: + - image: redis:latest + imagePullPolicy: Always + name: redis + ports: + - containerPort: 6379 + protocol: TCP + restartPolicy: Always + terminationGracePeriodSeconds: 30 + nodeSelector: + role: 'bigbluebutton' + tolerations: + - key: role + operator: Equal + value: 'bigbluebutton' + effect: NoSchedule + +--- +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: bigbluebutton +spec: + ports: + - targetPort: 6379 + port: 6379 + selector: + app: redis diff --git a/labs/docker/kurento/Dockerfile b/labs/docker/kurento/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..97dbf889259eeca09b76fdb364bd280d9b317c37 --- /dev/null +++ b/labs/docker/kurento/Dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:16.04 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update \ + && apt-get -y dist-upgrade \ + && apt-get install -y software-properties-common curl wget apt-transport-https + +RUN wget https://ubuntu.bigbluebutton.org/repo/bigbluebutton.asc -O- | apt-key add - \ + && add-apt-repository "deb https://ubuntu.bigbluebutton.org/xenial-200-dev bigbluebutton-xenial main" \ + && apt-get update \ + && apt-get -y install kurento-media-server bzip2 jq \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN apt-get update \ + && apt-get install -y --download-only openh264-gst-plugins-bad-1.5 + +COPY ./docker-entrypoint.sh /usr/local/bin/ +COPY ./healthchecker.sh /healthchecker.sh + +HEALTHCHECK --start-period=15s --interval=30s --timeout=3s --retries=1 CMD /healthchecker.sh + +ENV GST_DEBUG=Kurento*:5 +ENV PORT=8888 + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["/usr/bin/kurento-media-server"] diff --git a/labs/docker/kurento/docker-entrypoint.sh b/labs/docker/kurento/docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..4d1d3a444ebd238994df8c48195f5027b68f6d4e --- /dev/null +++ b/labs/docker/kurento/docker-entrypoint.sh @@ -0,0 +1,24 @@ +#!/bin/bash -e + +apt-get install -y openh264-gst-plugins-bad-1.5 + +rm -f /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini +touch /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini + +if [ -n "$KMS_TURN_URL" ]; then + echo "turnURL=$KMS_TURN_URL" >> /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini +fi + +if [ -n "$KMS_STUN_IP" -a -n "$KMS_STUN_PORT" ]; then + # Generate WebRtcEndpoint configuration + echo "stunServerAddress=$KMS_STUN_IP" >> /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini + echo "stunServerPort=$KMS_STUN_PORT" >> /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini +fi + +KMS_CONFIG=$(cat /etc/kurento/kurento.conf.json | sed '/^[ ]*\/\//d' | jq ".mediaServer.net.websocket.port = $PORT") +echo $KMS_CONFIG > /etc/kurento/kurento.conf.json + +# Remove ipv6 local loop until ipv6 is supported +cat /etc/hosts | sed '/::1/d' | tee /etc/hosts > /dev/null + +exec "$@" diff --git a/labs/docker/kurento/healthchecker.sh b/labs/docker/kurento/healthchecker.sh new file mode 100755 index 0000000000000000000000000000000000000000..c7f6ce82faf2c3667e2ce65030963ab02bff83c9 --- /dev/null +++ b/labs/docker/kurento/healthchecker.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +[[ "$(curl -w '%{http_code}' -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: 127.0.0.1:8888" -H "Origin: 127.0.0.1" http://127.0.0.1:8888/kurento)" == 500 ]] && exit 0 || exit 1 diff --git a/labs/docker/nginx/Dockerfile b/labs/docker/nginx/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..56fc11c4192341c49542f0584f8c8273db0e870a --- /dev/null +++ b/labs/docker/nginx/Dockerfile @@ -0,0 +1,14 @@ +FROM nginx + +RUN apt-get update && apt-get install -y wget + +ENV DOCKERIZE_VERSION v0.6.1 +RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ + && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz + +COPY ./nginx.conf.tmpl /etc/nginx/nginx.conf.tmpl + +CMD [ "dockerize", \ + "-template", "/etc/nginx/nginx.conf.tmpl:/etc/nginx/nginx.conf", \ + "nginx", "-g", "daemon off;" ] diff --git a/labs/docker/nginx/nginx.conf.tmpl b/labs/docker/nginx/nginx.conf.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..0210fc399b1ed6e9d5bb3a30173982f30961a688 --- /dev/null +++ b/labs/docker/nginx/nginx.conf.tmpl @@ -0,0 +1,66 @@ +user www-data; +worker_processes auto; +pid /run/nginx.pid; + +events { + worker_connections 768; +} + +http { + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # Logging Settings + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + ## + # Virtual Host Configs + ## + + server { + listen 80; + listen [::]:80; + server_name {{ .Env.SERVER_DOMAIN }}; + + access_log /var/log/nginx/bigbluebutton.access.log; + + location /ws { + proxy_pass https://bbb-freeswitch:7443; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_read_timeout 6h; + proxy_send_timeout 6h; + client_body_timeout 6h; + send_timeout 6h; + } + } +} diff --git a/labs/docker/sbt/Dockerfile b/labs/docker/sbt/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..99e285c61de4892f93bc2a40fa267d28da9e737b --- /dev/null +++ b/labs/docker/sbt/Dockerfile @@ -0,0 +1,14 @@ +FROM openjdk:8 + +ARG SBT_VERSION=0.13.8 + +RUN curl -L -o sbt-$SBT_VERSION.deb https://dl.bintray.com/sbt/debian/sbt-$SBT_VERSION.deb \ + && dpkg -i sbt-$SBT_VERSION.deb \ + && rm sbt-$SBT_VERSION.deb \ + && apt-get update \ + && apt-get install sbt \ + && sbt sbtVersion + +RUN echo 'resolvers += "Artima Maven Repository" at "http://repo.artima.com/releases"' | tee -a ~/.sbt/0.13/global.sbt + +WORKDIR /root