diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000000..55c71b9fd7eb --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,424 @@ +defaults: &defaults + working_directory: ~/repo + +version: 2 +jobs: + build: + <<: *defaults + docker: + - image: circleci/node:8.9 + + steps: + - checkout + + # - restore_cache: + # keys: + # - node-modules-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "package.json" }} + + # - restore_cache: + # keys: + # - meteor-{{ checksum ".circleci/config.yml" }}-{{ checksum ".meteor/release" }} + + - run: + name: Install Meteor + command: | + # Restore bin from cache + set +e + METEOR_SYMLINK_TARGET=$(readlink ~/.meteor/meteor) + METEOR_TOOL_DIRECTORY=$(dirname "$METEOR_SYMLINK_TARGET") + set -e + LAUNCHER=$HOME/.meteor/$METEOR_TOOL_DIRECTORY/scripts/admin/launch-meteor + if [ -e $LAUNCHER ] + then + echo "Cached Meteor bin found, restoring it" + sudo cp "$LAUNCHER" "/usr/local/bin/meteor" + else + echo "No cached Meteor bin found." + fi + + # only install meteor if bin isn't found + command -v meteor >/dev/null 2>&1 || curl https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh + + - run: + name: Versions + command: | + npm --versions + node -v + meteor --version + meteor npm --versions + meteor node -v + git version + + - run: + name: Meteor npm install + command: | + # rm -rf node_modules + # rm -f package-lock.json + meteor npm install + + - run: + name: Lint + command: | + meteor npm run lint + meteor npm run stylelint + + - run: + name: Unit Test + command: | + meteor npm run testunit + + # - restore_cache: + # keys: + # - meteor-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum ".meteor/versions" }} + + # - restore_cache: + # keys: + # - livechat-meteor-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "packages/rocketchat-livechat/app/.meteor/versions" }} + + # - restore_cache: + # keys: + # - livechat-node-modules-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "packages/rocketchat-livechat/app/package.json" }} + + - run: + name: Build Rocket.Chat + command: | + if [[ $CIRCLE_TAG ]]; then meteor reset; fi + set +e + meteor add rocketchat:lib + set -e + meteor build --server-only --directory /tmp/build-test + + - run: + name: Prepare build + command: | + mkdir /tmp/build/ + cd /tmp/build-test + tar czf /tmp/build/Rocket.Chat.tar.gz bundle + cd /tmp/build-test/bundle/programs/server + npm install + + # - save_cache: + # key: node-modules-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "package.json" }} + # paths: + # - ./node_modules + + # - save_cache: + # key: meteor-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum ".meteor/versions" }} + # paths: + # - ./.meteor/local + + # - save_cache: + # key: livechat-node-modules-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "packages/rocketchat-livechat/app/package.json" }} + # paths: + # - ./packages/rocketchat-livechat/app/node_modules + + # - save_cache: + # key: livechat-meteor-cache-{{ checksum ".circleci/config.yml" }}-{{ checksum "packages/rocketchat-livechat/app/.meteor/versions" }} + # paths: + # - ./packages/rocketchat-livechat/app/.meteor/local + + # - save_cache: + # key: meteor-{{ checksum ".circleci/config.yml" }}-{{ checksum ".meteor/release" }} + # paths: + # - ~/.meteor + + - persist_to_workspace: + root: /tmp/ + paths: + - build-test + - build + + - store_artifacts: + path: /tmp/build + + test-with-oplog: + <<: *defaults + docker: + - image: circleci/node:8.9-browsers + - image: mongo:3.4 + command: [mongod, --nojournal, --noprealloc, --smallfiles, --replSet=rs0] + + environment: + TEST_MODE: "true" + MONGO_URL: mongodb://localhost:27017/testwithoplog + MONGO_OPLOG_URL: mongodb://localhost:27017/local + + steps: + - attach_workspace: + at: /tmp + + - checkout + + - run: + name: Install dependencies + command: | + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 + echo "deb [ arch=amd64 ] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google.list + echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list + sudo apt-get update + sudo apt-get install -y mongodb-org-shell google-chrome-stable + + - run: + name: Configure Replica Set + command: | + mongo --eval 'rs.initiate({_id:"rs0", members: [{"_id":1, "host":"localhost:27017"}]})' + mongo --eval 'rs.status()' + + - run: + name: NPM install + command: | + npm install + + - run: + name: Run Tests + command: | + for i in $(seq 1 5); do npm test && s=0 && break || s=$? && sleep 1; done; (exit $s) + + - store_artifacts: + path: .screenshots/ + + test-without-oplog: + <<: *defaults + docker: + - image: circleci/node:8.9-browsers + - image: circleci/mongo:3.4 + + environment: + TEST_MODE: "true" + MONGO_URL: mongodb://localhost:27017/testwithoplog + + steps: + - attach_workspace: + at: /tmp + + - checkout + + - run: + name: Install dependencies + command: | + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - + echo "deb [ arch=amd64 ] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google.list + sudo apt-get update + sudo apt-get install -y google-chrome-stable + + - run: + name: NPM install + command: | + npm install + + - run: + name: Run Tests + command: | + for i in $(seq 1 5); do npm test && s=0 && break || s=$? && sleep 1; done; (exit $s) + + - store_artifacts: + path: .screenshots/ + + deploy: + <<: *defaults + docker: + - image: circleci/node:8.9 + + steps: + - attach_workspace: + at: /tmp + + - checkout + + - run: + name: Install AWS cli + command: | + if [[ $CIRCLE_PULL_REQUESTS ]]; then exit 0; fi; + + sudo apt-get -y -qq update + sudo apt-get -y -qq install python3.4-dev + curl -O https://bootstrap.pypa.io/get-pip.py + python3.4 get-pip.py --user + export PATH=~/.local/bin:$PATH + pip install awscli --upgrade --user + + - run: + name: Publish assets + command: | + if [[ $CIRCLE_PULL_REQUESTS ]]; then exit 0; fi; + + export PATH=~/.local/bin:$PATH + export CIRCLE_TAG=${CIRCLE_TAG:=} + + source .circleci/setartname.sh + source .circleci/setdeploydir.sh + bash .circleci/setupsig.sh + bash .circleci/namefiles.sh + # echo ".circleci/sandstorm.sh" + + aws s3 cp $ROCKET_DEPLOY_DIR/ s3://download.rocket.chat/build/ --recursive + + bash .circleci/update-releases.sh + bash .circleci/snap.sh + bash .circleci/redhat-registry.sh + + image-build: + <<: *defaults + + docker: + - image: docker:17.05.0-ce-git + + steps: + - attach_workspace: + at: /tmp + + - checkout + + - setup_remote_docker + + - run: + name: Build Docker image + command: | + cd /tmp/build + tar xzf Rocket.Chat.tar.gz + rm Rocket.Chat.tar.gz + + export CIRCLE_TAG=${CIRCLE_TAG:=} + if [[ $CIRCLE_TAG ]]; then + docker login -u $DOCKER_USER -p $DOCKER_PASS + + echo "Build official Docker image" + cp ~/repo/.docker/Dockerfile . + docker build -t rocketchat/rocket.chat:$CIRCLE_TAG . + docker push rocketchat/rocket.chat:$CIRCLE_TAG + + echo "Build preview Docker image" + cp ~/repo/.docker-mongo/Dockerfile . + cp ~/repo/.docker-mongo/entrypoint.sh . + docker build -t rocketchat/rocket.chat.preview:$CIRCLE_TAG . + docker push rocketchat/rocket.chat.preview:$CIRCLE_TAG + + if echo "$CIRCLE_TAG" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' ; then + docker tag rocketchat/rocket.chat:$CIRCLE_TAG rocketchat/rocket.chat:latest + docker push rocketchat/rocket.chat:latest + + docker tag rocketchat/rocket.chat.preview:$CIRCLE_TAG rocketchat/rocket.chat.preview:latest + docker push rocketchat/rocket.chat.preview:latest + elif echo "$CIRCLE_TAG" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' ; then + docker tag rocketchat/rocket.chat:$CIRCLE_TAG rocketchat/rocket.chat:release-candidate + docker push rocketchat/rocket.chat:release-candidate + + docker tag rocketchat/rocket.chat.preview:$CIRCLE_TAG rocketchat/rocket.chat.preview:release-candidate + docker push rocketchat/rocket.chat.preview:release-candidate + fi + + exit 0 + fi; + + if [[ $CIRCLE_BRANCH == 'develop' ]]; then + docker login -u $DOCKER_USER -p $DOCKER_PASS + + echo "Build official Docker image" + cp ~/repo/.docker/Dockerfile . + docker build -t rocketchat/rocket.chat:develop . + docker push rocketchat/rocket.chat:develop + + echo "Build preview Docker image" + cp ~/repo/.docker-mongo/Dockerfile . + cp ~/repo/.docker-mongo/entrypoint.sh . + docker build -t rocketchat/rocket.chat.preview:develop . + docker push rocketchat/rocket.chat.preview:develop + + exit 0 + fi; + + pr-image-build: + <<: *defaults + + docker: + - image: docker:17.05.0-ce-git + + steps: + - attach_workspace: + at: /tmp + + - checkout + + - setup_remote_docker + + - run: + name: Build Docker image for PRs + command: | + export CIRCLE_PR_NUMBER="${CIRCLE_PR_NUMBER:-${CIRCLE_PULL_REQUEST##*/}}" + if [[ -z $CIRCLE_PR_NUMBER ]]; then + exit 0 + fi; + + cd /tmp/build + tar xzf Rocket.Chat.tar.gz + rm Rocket.Chat.tar.gz + + docker login -u $DOCKER_USER -p $DOCKER_PASS + + echo "Build official Docker image" + cp ~/repo/.docker/Dockerfile . + docker build -t rocketchat/rocket.chat:pr-$CIRCLE_PR_NUMBER . + docker push rocketchat/rocket.chat:pr-$CIRCLE_PR_NUMBER + + echo "Build preview Docker image" + cp ~/repo/.docker-mongo/Dockerfile . + cp ~/repo/.docker-mongo/entrypoint.sh . + docker build -t rocketchat/rocket.chat.preview:pr-$CIRCLE_PR_NUMBER . + docker push rocketchat/rocket.chat.preview:pr-$CIRCLE_PR_NUMBER + +workflows: + version: 2 + build-and-test: + jobs: + - build: + filters: + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - test-with-oplog: + requires: + - build + filters: + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - test-without-oplog: + requires: + - build + filters: + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - deploy: + requires: + - test-with-oplog + - test-without-oplog + filters: + branches: + only: develop + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - image-build: + requires: + - deploy + filters: + branches: + only: develop + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - hold: + type: approval + requires: + - build + filters: + branches: + ignore: develop + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + - pr-image-build: + requires: + - hold + filters: + branches: + ignore: develop + tags: + only: /^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$/ + diff --git a/.circleci/docker.sh b/.circleci/docker.sh new file mode 100644 index 000000000000..4edf27c21775 --- /dev/null +++ b/.circleci/docker.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +CURL_URL="https://registry.hub.docker.com/u/rocketchat/rocket.chat/trigger/$DOCKER_TRIGGER_TOKEN/" + +if [[ $CIRCLE_TAG ]]; then + CURL_DATA='{"source_type":"Tag","source_name":"'"$CIRCLE_TAG"'"}'; +else + CURL_DATA='{"source_type":"Branch","source_name":"'"$CIRCLE_BRANCH"'"}'; +fi + +curl -H "Content-Type: application/json" --data "$CURL_DATA" -X POST "$CURL_URL" diff --git a/.circleci/namefiles.sh b/.circleci/namefiles.sh new file mode 100644 index 000000000000..f2fd572105f3 --- /dev/null +++ b/.circleci/namefiles.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +FILENAME="$ROCKET_DEPLOY_DIR/rocket.chat-$ARTIFACT_NAME.tgz"; + +ln -s /tmp/build/Rocket.Chat.tar.gz "$FILENAME" +gpg --armor --detach-sign "$FILENAME" diff --git a/.circleci/redhat-registry.sh b/.circleci/redhat-registry.sh new file mode 100755 index 000000000000..a206af991c19 --- /dev/null +++ b/.circleci/redhat-registry.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +if [[ $CIRCLE_TAG ]]; then + curl -X POST \ + https://connect.redhat.com/api/v2/projects/$REDHAT_REGISTRY_PID/build \ + -H "Authorization: Bearer $REDHAT_REGISTRY_KEY" \ + -H 'Cache-Control: no-cache' \ + -H 'Content-Type: application/json' \ + -d '{"tag":"'$CIRCLE_TAG'"}' +fi diff --git a/.circleci/setartname.sh b/.circleci/setartname.sh new file mode 100644 index 000000000000..e61fd52f1a41 --- /dev/null +++ b/.circleci/setartname.sh @@ -0,0 +1,23 @@ +if [[ $CIRCLE_TAG ]]; then + export ARTIFACT_NAME="$(npm run version --silent)" +else + export ARTIFACT_NAME="$(npm run version --silent).$CIRCLE_BUILD_NUM" +fi + +if [[ $CIRCLE_TAG =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+ ]]; then + SNAP_CHANNEL=candidate + RC_RELEASE=candidate + RC_VERSION=$CIRCLE_TAG +elif [[ $CIRCLE_TAG =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + SNAP_CHANNEL=stable + RC_RELEASE=stable + RC_VERSION=$CIRCLE_TAG +else + SNAP_CHANNEL=edge + RC_RELEASE=develop + RC_VERSION=0.66.0-develop +fi + +export SNAP_CHANNEL +export RC_RELEASE +export RC_VERSION diff --git a/.circleci/setdeploydir.sh b/.circleci/setdeploydir.sh new file mode 100644 index 000000000000..2c49e4a7027a --- /dev/null +++ b/.circleci/setdeploydir.sh @@ -0,0 +1,2 @@ +export ROCKET_DEPLOY_DIR="/tmp/deploy" +mkdir -p $ROCKET_DEPLOY_DIR diff --git a/.circleci/setupsig.sh b/.circleci/setupsig.sh new file mode 100644 index 000000000000..7b8f3820d745 --- /dev/null +++ b/.circleci/setupsig.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +cp .circleci/sign.key.gpg /tmp +gpg --yes --batch --passphrase=$GPG_PASSWORD /tmp/sign.key.gpg +gpg --allow-secret-key-import --import /tmp/sign.key +rm /tmp/sign.key diff --git a/.circleci/sign.key.gpg b/.circleci/sign.key.gpg new file mode 100644 index 000000000000..488e275998d5 Binary files /dev/null and b/.circleci/sign.key.gpg differ diff --git a/.circleci/snap.sh b/.circleci/snap.sh new file mode 100644 index 000000000000..38850daa1938 --- /dev/null +++ b/.circleci/snap.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +# Add launchpad to known hosts +ssh-keyscan -t rsa -H git.launchpad.net > ~/.ssh/known_hosts + +echo "Preparing to trigger a snap release for $SNAP_CHANNEL channel" + +cd $PWD/.snapcraft + +# We need some meta data so it'll actually commit. This could be useful to have for debugging later. +echo -e "Tag: $CIRCLE_TAG\r\nBranch: $CIRCLE_BRANCH\r\nBuild: $CIRCLE_BUILD_NUM\r\nCommit: $CIRCLE_SHA1" > buildinfo + +# Clone launchpad repo for the channel down. +git clone -b $SNAP_CHANNEL git+ssh://rocket.chat.buildmaster@git.launchpad.net/rocket.chat launchpad + +# Rarely will change, but just incase we copy it all +cp -r resources buildinfo launchpad/ +sed s/#{RC_VERSION}/$RC_VERSION/ snapcraft.yaml > launchpad/snapcraft.yaml +sed s/#{RC_VERSION}/$RC_VERSION/ resources/prepareRocketChat > launchpad/resources/prepareRocketChat + +cd launchpad +git add resources snapcraft.yaml buildinfo + +# Set commit author details +git config user.email "buildmaster@rocket.chat" +git config user.name "CircleCI" + +# Another place where basic meta data will live for at a glance info +git commit -m "CircleCI Build: $CIRCLE_BUILD_NUM CircleCI Commit: $CIRCLE_SHA1" + +# Push up up to the branch of choice. +git push origin $SNAP_CHANNEL + +# Clean up +cd .. +rm -rf launchpad diff --git a/.circleci/update-releases.sh b/.circleci/update-releases.sh new file mode 100644 index 000000000000..4e133c304fed --- /dev/null +++ b/.circleci/update-releases.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euvo pipefail +IFS=$'\n\t' + +curl -X POST \ +-H "X-Update-Token: ${UPDATE_TOKEN}" \ +https://releases.rocket.chat/update diff --git a/.docker-mongo/Dockerfile b/.docker-mongo/Dockerfile new file mode 100644 index 000000000000..8a5faf28da37 --- /dev/null +++ b/.docker-mongo/Dockerfile @@ -0,0 +1,40 @@ +FROM rocketchat/base:8 + +ADD . /app +ADD entrypoint.sh /app/bundle/ + +MAINTAINER buildmaster@rocket.chat + +RUN set -x \ + && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5 \ + && echo "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/3.6 main" | tee /etc/apt/sources.list.d/mongodb-org-3.6.list \ + && apt-get update \ + && apt-get install -y --force-yes pwgen mongodb-org \ + && echo "mongodb-org hold" | dpkg --set-selections \ + && echo "mongodb-org-server hold" | dpkg --set-selections \ + && echo "mongodb-org-shell hold" | dpkg --set-selections \ + && echo "mongodb-org-mongos hold" | dpkg --set-selections \ + && echo "mongodb-org-tools hold" | dpkg --set-selections \ + && cd /app/bundle/programs/server \ + && npm install \ + && npm cache clear --force \ + && rm -rf /var/lib/apt/lists/* + +VOLUME /app/uploads + +WORKDIR /app/bundle + +# needs a mongoinstance - defaults to container linking with alias 'mongo' +ENV DEPLOY_METHOD=docker-preview \ + NODE_ENV=production \ + MONGO_URL=mongodb://localhost:27017/rocketchat \ + HOME=/tmp \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 \ + Accounts_AvatarStorePath=/app/uploads + +EXPOSE 3000 + +RUN chmod +x /app/bundle/entrypoint.sh + +ENTRYPOINT /app/bundle/entrypoint.sh diff --git a/.docker-mongo/entrypoint.sh b/.docker-mongo/entrypoint.sh new file mode 100644 index 000000000000..f86035acba54 --- /dev/null +++ b/.docker-mongo/entrypoint.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +echo """ + +  +  +  +    +       +         +            +            +            +          +          +           +           +           +        +              +            +         +         +     +        +   + + + + +""" + +echo """ +██████╗ ██████╗ ██████╗██╗ ██╗███████╗████████╗ ██████╗██╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗██╗ ██╗██╗███████╗██╗ ██╗ +██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔════╝██║ ██║██╔══██╗╚══██╔══╝ ██╔══██╗██╔══██╗██╔════╝██║ ██║██║██╔════╝██║ ██║ +██████╔╝██║ ██║██║ █████╔╝ █████╗ ██║ ██║ ███████║███████║ ██║ ██████╔╝██████╔╝█████╗ ██║ ██║██║█████╗ ██║ █╗ ██║ +██╔══██╗██║ ██║██║ ██╔═██╗ ██╔══╝ ██║ ██║ ██╔══██║██╔══██║ ██║ ██╔═══╝ ██╔══██╗██╔══╝ ╚██╗ ██╔╝██║██╔══╝ ██║███╗██║ +██║ ██║╚██████╔╝╚██████╗██║ ██╗███████╗ ██║██╗╚██████╗██║ ██║██║ ██║ ██║ ██║ ██║ ██║███████╗ ╚████╔╝ ██║███████╗╚███╔███╔╝ +╚═╝ ╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═══╝ ╚═╝╚══════╝ ╚══╝╚══╝ +""" + +mongod --smallfiles --storageEngine=mmapv1 --fork --config /etc/mongod.conf + +until mongo --eval "db" &> /dev/null; do + echo "MongoDB still not ready, sleeping" + sleep 1 +done + +node main.js diff --git a/.docker-mongo/licenses/LICENSE b/.docker-mongo/licenses/LICENSE new file mode 100644 index 000000000000..b3435a104885 --- /dev/null +++ b/.docker-mongo/licenses/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015-2017 Rocket.Chat Technologies Corp. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/.docker/Dockerfile b/.docker/Dockerfile new file mode 100644 index 000000000000..885051510ae2 --- /dev/null +++ b/.docker/Dockerfile @@ -0,0 +1,30 @@ +FROM rocketchat/base:8 + +ADD . /app + +MAINTAINER buildmaster@rocket.chat + +RUN set -x \ + && cd /app/bundle/programs/server \ + && npm install \ + && npm cache clear --force \ + && chown -R rocketchat:rocketchat /app + +USER rocketchat + +VOLUME /app/uploads + +WORKDIR /app/bundle + +# needs a mongoinstance - defaults to container linking with alias 'mongo' +ENV DEPLOY_METHOD=docker \ + NODE_ENV=production \ + MONGO_URL=mongodb://mongo:27017/rocketchat \ + HOME=/tmp \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 \ + Accounts_AvatarStorePath=/app/uploads + +EXPOSE 3000 + +CMD ["node", "main.js"] diff --git a/.docker/Dockerfile.local b/.docker/Dockerfile.local new file mode 100644 index 000000000000..9fc3eb43797b --- /dev/null +++ b/.docker/Dockerfile.local @@ -0,0 +1,20 @@ +FROM node:8 + +ADD . /app + +ENV RC_VERSION=0.57.0-designpreview \ + DEPLOY_METHOD=docker \ + NODE_ENV=production \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 + +RUN set -x \ + && cd /app/bundle/programs/server \ + && npm install \ + && npm cache clear --force + +WORKDIR /app/bundle + +EXPOSE 3000 + +CMD ["node", "main.js"] diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel new file mode 100644 index 000000000000..264b70bd007a --- /dev/null +++ b/.docker/Dockerfile.rhel @@ -0,0 +1,48 @@ +FROM registry.access.redhat.com/rhscl/nodejs-8-rhel7 + +ENV RC_VERSION 0.70.0-develop + +MAINTAINER buildmaster@rocket.chat + +LABEL name="Rocket.Chat" \ + vendor="Rocket.Chat" \ + version="${RC_VERSION}" \ + release="1" \ + url="https://rocket.chat" \ + summary="The Ultimate Open Source Web Chat Platform" \ + description="The Ultimate Open Source Web Chat Platform" \ + run="docker run -d --name ${NAME} ${IMAGE}" + + +# This is ugly... But for some reason npm and node aren't available at this stage. +ENV PATH /opt/rh/rh-nodejs8/root/usr/bin:/opt/app-root/src/node_modules/.bin/:/opt/app-root/src/.npm-global/bin/:/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +RUN set -x \ + && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EBE9FD7F9D0414FD08104 \ + && curl -SLf "https://releases.rocket.chat/${RC_VERSION}/download" -o rocket.chat.tgz \ + && curl -SLf "https://releases.rocket.chat/${RC_VERSION}/asc" -o rocket.chat.tgz.asc \ + && gpg --verify rocket.chat.tgz.asc \ + && tar -zxf rocket.chat.tgz -C /opt/app-root/src/ \ + && cd /opt/app-root/src/bundle/programs/server \ + && npm install + +COPY licenses /licenses + +VOLUME /opt/app-root/src/uploads + +WORKDIR /opt/app-root/src/bundle + +# Hack needed to force use of bundled library instead of system level outdated library +# https://github.com/lovell/sharp/issues/892 +ENV LD_PRELOAD=/opt/app-root/src/bundle/programs/server/npm/node_modules/sharp/vendor/lib/libz.so + +ENV DEPLOY_METHOD=docker-redhat \ + NODE_ENV=production \ + MONGO_URL=mongodb://mongo:27017/rocketchat \ + HOME=/tmp \ + PORT=3000 \ + ROOT_URL=http://localhost:3000 + +EXPOSE 3000 + +CMD ["node", "main.js"] diff --git a/.docker/licenses/LICENSE b/.docker/licenses/LICENSE new file mode 100644 index 000000000000..b3435a104885 --- /dev/null +++ b/.docker/licenses/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015-2017 Rocket.Chat Technologies Corp. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 000000000000..b43c20e9a5fb --- /dev/null +++ b/.drone.yml @@ -0,0 +1,44 @@ +pipeline: + restore-cache: + image: drillster/drone-volume-cache + restore: true + mount: + - /drone/.meteor/ + - ./node_modules + - ./.meteor/local + volumes: + - /tmp/cache/Rocket.Chat:/cache + build: + image: ubuntu:16.04 + environment: + - METEOR_ALLOW_SUPERUSER=true + commands: + - apt update && apt install curl git python g++ build-essential bzip2 -y + - export HOME=/drone + - export PATH="/drone/.meteor:$PATH" + - if [ ! -e "/drone/.meteor/meteor" ]; then export HOME=/drone; curl https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh; fi + - which meteor + - meteor npm install + - set +e + - meteor add rocketchat:lib + - set -e + - mkdir /drone/build + - meteor build --allow-superuser --server-only --directory /drone/build + - cp .docker/Dockerfile.local /drone/build/Dockerfile + rebuild-cache: + image: drillster/drone-volume-cache + rebuild: true + mount: + - /drone/.meteor/ + - ./node_modules + - ./.meteor/local + volumes: + - /tmp/cache/Rocket.Chat:/cache + docker: + image: plugins/docker + repo: rocketchat/rocket.chat + dockerfile: /drone/build/Dockerfile + storage_driver: overlay + context: /drone/build + secrets: [ docker_username, docker_password ] + tag: designpreview diff --git a/.drone.yml.sig b/.drone.yml.sig new file mode 100644 index 000000000000..064d2264dee3 --- /dev/null +++ b/.drone.yml.sig @@ -0,0 +1 @@ +eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgcmVzdG9yZS1jYWNoZToKICAgIGltYWdlOiBkcmlsbHN0ZXIvZHJvbmUtdm9sdW1lLWNhY2hlCiAgICByZXN0b3JlOiB0cnVlCiAgICBtb3VudDoKICAgICAgLSAvZHJvbmUvLm1ldGVvci8KICAgICAgLSAuL25vZGVfbW9kdWxlcwogICAgICAtIC4vLm1ldGVvci9sb2NhbAogICAgdm9sdW1lczoKICAgICAgLSAvdG1wL2NhY2hlL1JvY2tldC5DaGF0Oi9jYWNoZQogIGJ1aWxkOgogICAgaW1hZ2U6IHVidW50dToxNi4wNAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTUVURU9SX0FMTE9XX1NVUEVSVVNFUj10cnVlCiAgICBjb21tYW5kczoKICAgICAgLSBhcHQgdXBkYXRlICYmIGFwdCBpbnN0YWxsIGN1cmwgZ2l0IHB5dGhvbiBnKysgYnVpbGQtZXNzZW50aWFsIGJ6aXAyIC15CiAgICAgIC0gZXhwb3J0IEhPTUU9L2Ryb25lCiAgICAgIC0gZXhwb3J0IFBBVEg9Ii9kcm9uZS8ubWV0ZW9yOiRQQVRIIgogICAgICAtIGlmIFsgISAtZSAiL2Ryb25lLy5tZXRlb3IvbWV0ZW9yIiBdOyB0aGVuIGV4cG9ydCBIT01FPS9kcm9uZTsgY3VybCBodHRwczovL2luc3RhbGwubWV0ZW9yLmNvbSB8IHNlZCBzLy0tcHJvZ3Jlc3MtYmFyLy1zTC9nIHwgL2Jpbi9zaDsgZmkKICAgICAgLSB3aGljaCBtZXRlb3IKICAgICAgLSBtZXRlb3IgbnBtIGluc3RhbGwKICAgICAgLSBzZXQgK2UKICAgICAgLSBtZXRlb3IgYWRkIHJvY2tldGNoYXQ6bGliCiAgICAgIC0gc2V0IC1lCiAgICAgIC0gbWtkaXIgL2Ryb25lL2J1aWxkCiAgICAgIC0gbWV0ZW9yIGJ1aWxkIC0tYWxsb3ctc3VwZXJ1c2VyIC0tc2VydmVyLW9ubHkgLS1kaXJlY3RvcnkgL2Ryb25lL2J1aWxkCiAgICAgIC0gY3AgLmRvY2tlci9Eb2NrZXJmaWxlLmxvY2FsIC9kcm9uZS9idWlsZC9Eb2NrZXJmaWxlCiAgcmVidWlsZC1jYWNoZToKICAgIGltYWdlOiBkcmlsbHN0ZXIvZHJvbmUtdm9sdW1lLWNhY2hlCiAgICByZWJ1aWxkOiB0cnVlCiAgICBtb3VudDoKICAgICAgLSAvZHJvbmUvLm1ldGVvci8KICAgICAgLSAuL25vZGVfbW9kdWxlcwogICAgICAtIC4vLm1ldGVvci9sb2NhbAogICAgdm9sdW1lczoKICAgICAgLSAvdG1wL2NhY2hlL1JvY2tldC5DaGF0Oi9jYWNoZQogIGRvY2tlcjoKICAgIGltYWdlOiBwbHVnaW5zL2RvY2tlcgogICAgcmVwbzogcm9ja2V0Y2hhdC9yb2NrZXQuY2hhdAogICAgZG9ja2VyZmlsZTogL2Ryb25lL2J1aWxkL0RvY2tlcmZpbGUKICAgIHN0b3JhZ2VfZHJpdmVyOiBvdmVybGF5CiAgICBjb250ZXh0OiAvZHJvbmUvYnVpbGQKICAgIHNlY3JldHM6IFsgZG9ja2VyX3VzZXJuYW1lLCBkb2NrZXJfcGFzc3dvcmQgXQogICAgdGFnOiBkZXNpZ25wcmV2aWV3Cg.vIwnazoqiKfxsC6hQHJFmB7jE0dvewf69xJgNxUWNic \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index b0d7fd91b35a..f2f826b09d65 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,12 +1,19 @@ -# editorconfig.org +# EditorConfig is awesome: http://EditorConfig.org + root = true [*] -indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +[*.{js,coffee,html,less,css,json}] +indent_style = tab + +[*.i18n.json] +indent_style = space +indent_size = 2 + [*.md] trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000000..f8e66c28c01d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,24 @@ +node_modules +packages/autoupdate/ +packages/meteor-streams/ +packages/meteor-timesync/ +packages/rocketchat-emoji-emojione/generateEmojiIndex.js +packages/rocketchat-favico/favico.js +packages/rocketchat-katex/client/katex/katex.min.js +packages/rocketchat-livechat/.app/node_modules +packages/rocketchat-livechat/.app/.meteor +packages/rocketchat-livechat/assets/rocketchat-livechat.min.js +packages/rocketchat-livechat/assets/rocket-livechat.js +packages/rocketchat-theme/client/minicolors/jquery.minicolors.js +packages/rocketchat-ui/client/lib/customEventPolyfill.js +packages/rocketchat-ui/client/lib/Modernizr.js +packages/rocketchat-ui/client/lib/recorderjs/recorder.js +packages/rocketchat-videobridge/client/public/external_api.js +packages/rocketchat-theme/client/vendor/ +packages/tap-i18n/lib/tap_i18next/tap_i18next-1.7.3.js +private/moment-locales/ +public/livechat/ +public/mp3-realtime-worker.js +public/lame.min.js +!.scripts +!packages/rocketchat-livechat/.app diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000000..7cf4fcf95d80 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,208 @@ +{ + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2017, + "ecmaFeatures": { + "experimentalObjectRestSpread" : true + } + }, + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true, + "jquery": true + }, + "rules": { + "no-multi-spaces": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-multi-str": 2, + "no-use-before-define": 2, + "no-const-assign": 2, + "no-cond-assign": 2, + "no-constant-condition": 2, + "no-control-regex": 2, + "no-debugger": 2, + "no-delete-var": 2, + "no-dupe-keys": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "no-duplicate-case": 2, + "no-empty": 2, + "no-empty-character-class": 2, + "no-ex-assign": 2, + "no-extra-boolean-cast": 2, + "no-extra-semi": 2, + "no-fallthrough": 2, + "no-func-assign": 2, + "no-inner-declarations": [2, "functions"], + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-mixed-operators": [2, { + "groups": [ + ["%", "**"], + ["%", "+"], + ["%", "-"], + ["%", "*"], + ["%", "/"], + ["**", "+"], + ["**", "-"], + ["**", "*"], + ["**", "/"], + ["&", "|", "^", "~", "<<", ">>", ">>>"], + ["==", "!=", "===", "!==", ">", ">=", "<", "<="], + ["&&", "||"], + ["in", "instanceof"] + ], + "allowSamePrecedence": false + }], + "no-mixed-spaces-and-tabs": 2, + "no-sparse-arrays": 2, + "no-negated-in-lhs": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-undef": 2, + "no-unreachable": 2, + "no-unused-vars": [2, { + "vars": "all", + "args": "after-used" + }], + "no-void": 2, + "no-var": 2, + "no-multiple-empty-lines": [2, { "max": 2 }], + "no-nested-ternary": 2, + "prefer-rest-params": 2, + "array-callback-return": 2, + "prefer-destructuring": [2, { + "VariableDeclarator": { + "array": false, + "object": true + }, + "AssignmentExpression": { + "array": false, + "object": false + } + }, { + "enforceForRenamedProperties": false + }], + "no-duplicate-imports": 2, + "arrow-parens": [2, "always"], + "quote-props": [2, "as-needed"], + "no-array-constructor": 2, + "arrow-spacing": 2, + "arrow-body-style": [2, "as-needed"], + "no-confusing-arrow": [2, { "allowParens": true }], + "dot-notation": 2, + "no-unneeded-ternary": 2, + "spaced-comment": 2, + "space-infix-ops": 2, + "array-bracket-spacing": [2, "never"], + "object-curly-spacing": [2, "always"], + "one-var": [2, "never"], + "no-lonely-if": 2, + "no-trailing-spaces": 2, + "complexity": [1, 31], + "space-in-parens": [2, "never"], + "space-before-function-paren": [2, "never"], + "space-before-blocks": [2, "always"], + "indent": [2, "tab", {"SwitchCase": 1}], + "eol-last": [2, "always"], + "comma-dangle": [2, "always-multiline"], + "keyword-spacing": 2, + "block-spacing": 2, + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "computed-property-spacing": 2, + "comma-spacing": 2, + "comma-style": 2, + "guard-for-in": 2, + "wrap-iife": 2, + "block-scoped-var": 2, + "curly": [2, "all"], + "eqeqeq": [2, "allow-null"], + "new-cap": [2, { + "capIsNewExceptions": ["Match.Optional", "Match.Maybe", "Match.OneOf", "Match.Where", "Match.ObjectIncluding", "Push.Configure", "SHA256"] + }], + "use-isnan": 2, + "valid-typeof": 2, + "linebreak-style": [2, "unix"], + "prefer-template": 2, + "template-curly-spacing": [2, "always"], + "quotes": [2, "single"], + "semi": [2, "always"], + "prefer-const": 2, + "object-shorthand": 2 + }, + "globals": { + "__meteor_runtime_config__" : false, + "AccountBox" : false, + "Accounts" : false, + "AgentUsers" : false, + "Apps" : false, + "Assets" : false, + "Blaze" : false, + "BlazeLayout" : false, + "browser" : false, + "ChatMessage" : false, + "ChatMessages" : false, + "ChatRoom" : false, + "ChatSubscription" : false, + "check" : false, + "CryptoJS" : false, + "Department" : false, + "DDPRateLimiter" : false, + "EJSON" : false, + "Email" : false, + "FlowRouter" : false, + "FileUpload" : false, + "HTTP" : false, + "getNextAgent" : false, + "handleError" : false, + "getAvatarUrlFromUsername" : false, + "LivechatCustomField" : false, + "LivechatDepartment" : false, + "LivechatDepartmentAgents" : false, + "livechatManagerRoutes" : true, + "LivechatPageVisited" : false, + "LivechatTrigger" : false, + "Logger" : false, + "Match" : false, + "Meteor" : false, + "modal" : false, + "moment" : false, + "Mongo" : false, + "Npm" : false, + "Package" : false, + "parentCall" : false, + "Promise" : false, + "Random" : false, + "ReactiveDict" : false, + "ReactiveVar" : false, + "Reload" : false, + "RocketChat" : true, + "RocketChatFile" : false, + "RoomHistoryManager" : false, + "RoomManager" : false, + "ServiceConfiguration" : false, + "Session" : false, + "Settings" : false, + "SHA256" : false, + "SideNav" : false, + "t" : false, + "TAPi18n" : false, + "TAPi18next" : false, + "Template" : false, + "TimeSync" : false, + "toastr" : false, + "Tracker" : false, + "Trigger" : false, + "Triggers" : false, + "UAParser" : false, + "visitor" : false, + "WebApp" : false, + "VideoRecorder" : false, + "VRecDialog" : false + } +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000000..dd85ed699b76 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing to Rocket.Chat + +:+1::tada: First off, thanks for taking the time to contribute! :tada::+1: + +The following is a set of guidelines for contributing to Rocket.Chat and its packages, which are hosted in the [Rocket.Chat Organization](https://github.com/RocketChat) on GitHub. + +__Note:__ If there's a feature you'd like, there's a bug you'd like to fix, or you'd just like to get involved please raise an issue and start a conversation. We'll help as much as we can so you can get contributing - although we may not always be able to respond right away :) + +## ECMAScript 2015 vs CoffeeScript + +While we still have a lot of CoffeeScript files you should not create new ones. New code contributions should be in **ECMAScript 2015**. + +## Coding standards + +Most of the coding standards are covered by `.editorconfig` and `.eslintrc.js`. + +Things not covered by `eslint`: + +* `exports`/`module.exports` should be at the end of the file +* Longer, descriptive variable names are preferred, e.g. `error` vs `err` + +We acknowledge all the code does not meet these standards but we are working to change this over time. + +### Syntax check + +Before submitting a PR you should get no errors on `eslint`. + +To check your files, first install `eslint`: + +``` +npm install -g eslint +``` + +Then run: + +``` +eslint . +``` + +# Contributor License Agreement + +Please review and sign our CLA at https://cla-assistant.io/RocketChat/Rocket.Chat diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000000..0822e6f29440 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,52 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + + + +### Description: + + + +### Steps to reproduce: + +1. +2. +3. + +### Expected behavior: + + + +### Actual behavior: + + + +### Server Setup Information: + +- Version of Rocket.Chat Server: +- Operating System: +- Deployment Method: +- Number of Running Instances: +- DB Replicaset Oplog: +- NodeJS Version: +- MongoDB Version: + +### Additional context + + + +### Relevant logs: + + + diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 000000000000..99bb9a00975f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,7 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000000..066b2d920a28 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md new file mode 100644 index 000000000000..03f57fcab160 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release.md @@ -0,0 +1,59 @@ +--- +name: Release +about: Internal release checklist template + +--- + +# Release {version} +We are releasing a new version, this issue will keep track of the progress between the first release candidate (20th of each month) to the final release (27th of each month). + +Beginning on the 20th of each month, we will start the release process which ends 7 days later (the 27th). During this period of time, we will enter a "Feature Freeze". This Feature Freeze means that we will only be merging pull requests which fix bugs and not ones which add new features. + +When you find a bug that is a regression, please open a new issue and link it to this one. + + +## Before Release - Preparation - 1 business day before the day 20th +- [x] Create the issue to track the release progress +- [ ] Define the highlights from release PRs as suggestion to be included on Blog Post +- [ ] Talk to the Marketing Team about starting the release Blog Post +- [ ] Talk to the Documentation Team about ensuring the Docs are up to date and all pull requests are merged +- [ ] Sync translations from [LingoHub](https://translate.lingohub.com/rocketchat/rocket-dot-chat/dashboard) + +## Release Candidate 1 - On the 20th +- [ ] Execute action `Release Candidate` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`) +- [ ] Check if `release-candidate` branch was published +- [ ] Check if the tag was published and contains the history +- [ ] Ensure the build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat) +- [ ] Ensure the image was sent to [Docker Hub](https://hub.docker.com/r/rocketchat/rocket.chat/tags/) + + + +## Final Release - On the 27th +- [ ] Execute action `Final Release` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`) +- [ ] Check if `release-{version}` branch was published +- [ ] Check if the release was created as **draft** and contains the history +- [ ] Check if the release Pull Request was created and contains the history +- [ ] Ensure the **Pull Request** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat) +- [ ] When build is passing ask for Pull Request approval +- [ ] When approved merge it! +- [ ] Ensure the **Tag** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat) +- [ ] Ensure the image was sent to [Docker Hub](https://hub.docker.com/r/rocketchat/rocket.chat/tags/) +- [ ] After all edit the release/tag and publish it + +## After Release - Conclusion - 1 business day after the 27th +- [ ] Ensure all of the related issues were closed +- [ ] Determine if all of the related issues were correctly assigned to the this version's milestone +- [ ] Get an update from Marketing Team about the release Blog Post +- [ ] Check with the Documentation Team about the Docs release +- [ ] Sync develop + - [ ] Execute action `Develop Sync` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`) + - [ ] Ensure the **Pull Request** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat) + - [ ] When build has passed, ask for approval and wait + - [ ] Merge Sync PR diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000000..db905f2f947a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ + + + + + + +Closes #ISSUE_NUMBER + + + + diff --git a/.github/bot-config.yml b/.github/bot-config.yml new file mode 100644 index 000000000000..2d181373504f --- /dev/null +++ b/.github/bot-config.yml @@ -0,0 +1,19 @@ +bot: + name: "@rocket-cat" +whitelist: + users: + - TwizzyDizzy + - theorenck + - JSzaszvari + labels: + - "Contributions: welcome" + - "Contributions: only core team" + - "Feature: Request" + - "Feature: Planned" + - "type: bug" + - "help wanted" + - duplicate + - enhancement + - invalid + - question + - wontfix diff --git a/.github/changelog.js b/.github/changelog.js new file mode 100644 index 000000000000..438d194d23ab --- /dev/null +++ b/.github/changelog.js @@ -0,0 +1,116 @@ +/* eslint no-var: 0, object-shorthand: 0, prefer-template: 0 */ + +'use strict'; +var readFile = require('fs').readFileSync; +var resolve = require('path').resolve; +var gitUrl = 'https://github.com/RocketChat/Rocket.Chat'; + +var parserOpts = { + headerPattern: /^(\[([A-z]+)\] )?(.*)$/m, + headerCorrespondence: [ + 'stype', + 'type', + 'subject' + ], + mergePattern: /^Merge pull request #(.*) from .*$/, + mergeCorrespondence: ['pr'] + // noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES'], + // revertPattern: /^revert:\s([\s\S]*?)\s*This reverts commit (\w*)\./, + // revertCorrespondence: ['header', 'hash'], + // mergePattern: /^Merge pull request #(\d+) from (.*)$/, + // mergeCorrespondence: ['id', 'source'] +}; + +var LABELS = { + BREAK: { + title: 'BREAKING CHANGES', + collapse: false + }, + NEW: { + title: 'New Features', + collapse: false + }, + FIX: { + title: 'Bug Fixes', + collapse: false + }, + DOC: { + title: 'Documentation', + collapse: true + }, + OTHER: { + title: 'Others', + collapse: true + } +}; + +var sort = Object.keys(LABELS); + +var writerOpts = { + transform: function(commit) { + if (!commit.pr) { + return; + } + + // console.log(commit); + commit.type = (commit.type || 'OTHER').toUpperCase(); + if (LABELS[commit.type] == null) { + return; + } + + commit.pr_url = gitUrl + '/pull/' + commit.pr; + + var issues = []; + + if (typeof commit.hash === 'string') { + commit.hash = commit.hash.substring(0, 7); + } + + if (typeof commit.subject === 'string') { + // GitHub issue URLs. + commit.subject = commit.subject.replace(/#([0-9]+)/g, function(_, issue) { + issues.push(issue); + return '[#' + issue + '](' + gitUrl + '/issues/' + issue + ')'; + }); + // GitHub user URLs. + commit.subject = commit.subject.replace(/@([a-zA-Z0-9_]+)/g, '[@$1](https://github.com/$1)'); + } + + // remove references that already appear in the subject + commit.references = commit.references.filter(function(reference) { + if (issues.indexOf(reference.issue) === -1) { + return true; + } + + return false; + }); + + return commit; + }, + groupBy: 'type', + commitGroupsSort: function(a, b) { + return sort.indexOf(a.title) > sort.indexOf(b.title); + }, + finalizeContext: function(context) { + context.commitGroups.forEach(function(group) { + Object.assign(group, LABELS[group.title.toUpperCase()]); + }); + + // console.log(context); + return context; + }, + commitsSort: ['subject'] +}; + +writerOpts.mainTemplate = readFile(resolve(__dirname, 'templates/template.hbs'), 'utf-8'); +writerOpts.headerPartial = readFile(resolve(__dirname, 'templates/header.hbs'), 'utf-8'); +writerOpts.commitPartial = readFile(resolve(__dirname, 'templates/commit.hbs'), 'utf-8'); +writerOpts.footerPartial = readFile(resolve(__dirname, 'templates/footer.hbs'), 'utf-8'); + +module.exports = { + gitRawCommitsOpts: { + merges: null + }, + parserOpts: parserOpts, + writerOpts: writerOpts +}; diff --git a/.github/history-manual.json b/.github/history-manual.json new file mode 100644 index 000000000000..394af77f43a0 --- /dev/null +++ b/.github/history-manual.json @@ -0,0 +1,15 @@ +{ + "0.55.0": [{ + "title": "[BREAK] `getUsersOfRoom` API to return array of objects with user and username, instead of array of strings", + "userLogin": "rodrigok", + "contributors": [] + }, { + "title": "[FIX] Incoming integrations would break when trying to use the `Store` feature.`", + "userLogin": "rodrigok", + "contributors": [] + }, { + "title": "[FIX] Removed Deprecated Package rocketchat:sharedsecret`", + "userLogin": "rodrigok", + "contributors": [] + }] +} diff --git a/.github/history.json b/.github/history.json new file mode 100644 index 000000000000..b0b510da35de --- /dev/null +++ b/.github/history.json @@ -0,0 +1,18684 @@ +{ + "version": 1, + "releases": { + "0.55.0-rc.0": { + "node_version": "4.7.3", + "npm_version": "4.1.2", + "pull_requests": [ + { + "pr": "6614", + "title": "Add candidate snap channel", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6597", + "title": "Add `fname` to subscriptions in memory", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "6608", + "title": "[New] Switch Snaps to use oplog", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "6576", + "title": "Convert Message Pin Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6585", + "title": "Move room display name logic to roomType definition", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6598", + "title": "[FIX] Large files crashed browser when trying to show preview", + "userLogin": "geekgonecrazy", + "milestone": "0.55.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "6600", + "title": "[FIX] messageBox: put \"joinCodeRequired\" back", + "userLogin": "karlprieb", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "6594", + "title": "[FIX] Do not add default roles for users without services field", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6596", + "title": "Only configure LoggerManager on server", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6298", + "title": "POC Google Natural Language integration", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6591", + "title": "Fix recently introduced bug: OnePassword not defined", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6553", + "title": "rocketchat-lib part1", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6590", + "title": "[FIX] Accounts from LinkedIn OAuth without name", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6584", + "title": "dependencies upgrade", + "userLogin": "engelgabriel", + "milestone": "0.55.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6580", + "title": "fixed typo in readme.md", + "userLogin": "sezinkarli", + "milestone": "0.55.0", + "contributors": [ + "sezinkarli", + "web-flow" + ] + }, + { + "pr": "6565", + "title": "[NEW] Add shield.svg api route to generate custom shields/badges", + "userLogin": "alexbrazier", + "milestone": "0.55.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "6575", + "title": "[FIX] Usage of subtagged languages", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "3851", + "title": "Use real name instead of username for messages and direct messages list", + "userLogin": "alexbrazier", + "milestone": "0.55.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "6561", + "title": "Convert Ui-Login Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6577", + "title": "[NEW] resolve merge share function", + "userLogin": "karlprieb", + "milestone": "0.55.0", + "contributors": [ + "tgxn", + "karlprieb" + ] + }, + { + "pr": "6551", + "title": "rocketchat-channel-settings coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6571", + "title": "Move wordpress packages client files to client folder", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6539", + "title": "convert rocketchat-ui part 2", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6541", + "title": "rocketchat-channel-settings-mail-messages coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6574", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6567", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6562", + "title": "[FIX] UTC offset missing UTC text when positive", + "userLogin": "alexbrazier", + "milestone": "0.55.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "6554", + "title": "[New] Added oauth2 userinfo endpoint", + "userLogin": "geekgonecrazy", + "milestone": "0.55.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "6531", + "title": "[FIX] can not get access_token when using custom oauth", + "userLogin": "fengt", + "milestone": "0.55.0", + "contributors": [ + "fengt" + ] + }, + { + "pr": "6540", + "title": "Remove Deprecated Shared Secret Package", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6542", + "title": "Remove coffeescript package from ui-sidenav", + "userLogin": "Kiran-Rao", + "milestone": "0.55.0", + "contributors": [ + "Kiran-Rao", + "web-flow" + ] + }, + { + "pr": "6543", + "title": "Remove coffeescript package from ui-flextab", + "userLogin": "Kiran-Rao", + "milestone": "0.55.0", + "contributors": [ + "Kiran-Rao", + "web-flow" + ] + }, + { + "pr": "6476", + "title": "[NEW] Two Factor Auth", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "6478", + "title": "[FIX] Outgoing webhooks which have an error and they're retrying would still retry even if the integration was disabled`", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6491", + "title": "Convert Theme Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6487", + "title": "Fix typo of the safari pinned tab label", + "userLogin": "qge", + "milestone": "0.55.0", + "contributors": [ + "qge", + "web-flow" + ] + }, + { + "pr": "6493", + "title": "fix channel merge option of user preferences", + "userLogin": "billtt", + "milestone": "0.55.0", + "contributors": [ + "billtt" + ] + }, + { + "pr": "6495", + "title": "converted Rocketchat logger coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6502", + "title": "converted rocketchat-integrations coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6522", + "title": "'allow reacting' should be a toggle option.otherwise, the style will display an error", + "userLogin": "szluohua", + "milestone": "0.55.0", + "contributors": [ + "szluohua", + "web-flow" + ] + }, + { + "pr": "6280", + "title": "Clipboard [Firefox version < 50]", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6473", + "title": "Convert ui-vrecord Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6474", + "title": "converted slashcommands-mute coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6494", + "title": "Convert Version Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "6498", + "title": "Convert Ui-Master Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "6500", + "title": "converted messageAttachment coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6503", + "title": "Convert File Package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "6505", + "title": "Create groups.addAll endpoint and add activeUsersOnly param.", + "userLogin": "nathanmarcos", + "milestone": "0.55.0", + "contributors": [ + "nathanmarcos", + null + ] + }, + { + "pr": "6351", + "title": "New feature: Room announcement", + "userLogin": "billtt", + "milestone": "0.55.0", + "contributors": [ + "billtt" + ] + }, + { + "pr": "6468", + "title": "converted slashcommand-me coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6469", + "title": "converted slashcommand-join coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6470", + "title": "converted slashcommand-leave coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6471", + "title": "convert mapview package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6496", + "title": "converted getAvatarUrlFromUsername", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6497", + "title": "converted slashcommand-invite coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6499", + "title": "Convert Wordpress Package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6501", + "title": "converted slashcommand-msg coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6504", + "title": "rocketchat-ui coffee to js part1", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6467", + "title": "converted rocketchat-mentions coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6479", + "title": "ESLint add rule `no-void`", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6456", + "title": "Add ESLint rules `prefer-template` and `template-curly-spacing`", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6466", + "title": "Fix livechat permissions", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6457", + "title": "Add ESLint rule `object-shorthand`", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6459", + "title": "Add ESLint rules `one-var` and `no-var`", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6458", + "title": "Add ESLint rule `one-var`", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6274", + "title": "Side-nav CoffeeScript to JavaScript III ", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6277", + "title": "Flex-Tab CoffeeScript to JavaScript II", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6430", + "title": "[NEW] Permission `join-without-join-code` assigned to admins and bots by default", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6420", + "title": "[NEW] Integrations, both incoming and outgoing, now have access to the models. Example: `Users.findOneById(id)`", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6266", + "title": "Side-nav CoffeeScript to JavaScript II", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6035", + "title": "Allow Livechat visitors to switch the department", + "userLogin": "drallgood", + "milestone": "0.55.0", + "contributors": [ + "drallgood", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "6122", + "title": "fix livechat widget on small screens", + "userLogin": "karlprieb", + "milestone": "0.55.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "6180", + "title": "Allow livechat managers to transfer chats", + "userLogin": "drallgood", + "milestone": "0.55.0", + "contributors": [ + "drallgood", + "web-flow" + ] + }, + { + "pr": "6257", + "title": "focus first textbox element", + "userLogin": "a5his", + "milestone": "0.55.0", + "contributors": [ + "a5his" + ] + }, + { + "pr": "6268", + "title": "Join command", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6419", + "title": "Fix visitor ending livechat if multiples still open", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6319", + "title": "Password reset Cleaner text", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6400", + "title": "Add permission check to the import methods and not just the UI", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6409", + "title": "Max textarea height", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6413", + "title": "Livechat fix office hours order", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6449", + "title": "Convert Spotify Package to JS", + "userLogin": "MartinSchoeler", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6422", + "title": "Make favicon package easier to read.", + "userLogin": "Kiran-Rao", + "milestone": "0.55.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "6426", + "title": "Just admins can change a Default Channel to Private (the channel will be a non default channel)", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6429", + "title": "Hide email settings on Sandstorm", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6432", + "title": "Do not show reset button for hidden settings", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6427", + "title": "Convert Dolphin Package to JavaScript", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6445", + "title": "converted rocketchat-message-mark-as-unread coffee/js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6453", + "title": "converted rocketchat-slashcommands-kick coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "6450", + "title": "converted meteor-accounts-saml coffee to js", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6447", + "title": "Convert Statistics Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6425", + "title": "Convert ChatOps Package to JavaScript", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6410", + "title": "Change all instances of Meteor.Collection for Mongo.Collection", + "userLogin": "marceloschmidt", + "milestone": "0.55.0", + "contributors": [ + "marceloschmidt" + ] + }, + { + "pr": "6278", + "title": "Flex-Tab CoffeeScript to JavaScript III", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "6276", + "title": "Flex-Tab CoffeeScript to JavaScript I ", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6264", + "title": "Side-nav CoffeeScript to JavaScript", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6446", + "title": "Convert Tutum Package to JS", + "userLogin": "MartinSchoeler", + "milestone": "0.55.0", + "contributors": [ + "MartinSchoeler" + ] + } + ] + }, + "0.55.0-rc.1": { + "node_version": "4.7.3", + "npm_version": "4.1.2", + "pull_requests": [ + { + "pr": "6620", + "title": "[FIX] Incorrect curl command being generated on incoming integrations", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6617", + "title": "[FIX] arguments logger", + "userLogin": "ggazzo", + "milestone": "0.55.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6616", + "title": "[NEW] 'users.resetAvatar' rest api endpoint", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336" + ] + } + ] + }, + "0.55.0-rc.2": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6632", + "title": "[NEW] Drupal oAuth Integration for Rocketchat", + "userLogin": "Lawri-van-Buel", + "milestone": "0.55.0", + "contributors": [ + "Lawri-van-Buel", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "6634", + "title": "[NEW] Add monitoring package", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6650", + "title": "[FIX] Improve markdown code", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6651", + "title": "[FIX] Encode avatar url to prevent CSS injection", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6649", + "title": "Added Deploy method and platform to stats", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "6648", + "title": "[FIX] Do not escaping markdown on message attachments", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6647", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.55.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6631", + "title": "meteor update", + "userLogin": "engelgabriel", + "milestone": "0.55.0", + "contributors": [ + "engelgabriel" + ] + } + ] + }, + "0.55.0-rc.3": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6658", + "title": "[FIX] Revert unwanted UI changes", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.55.0-rc.4": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6682", + "title": "[FIX] Fix Logger stdout publication", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6680", + "title": "[FIX] Downgrade email package to from 1.2.0 to 1.1.18", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6681", + "title": "[NEW] Expose Livechat to Incoming Integrations and allow response", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6659", + "title": "[FIX] Administrators being rate limited when editing users data", + "userLogin": "graywolf336", + "milestone": "0.55.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6674", + "title": "[FIX] Make sure username exists in findByActiveUsersExcept", + "userLogin": "geekgonecrazy", + "milestone": "0.55.0", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.55.0-rc.5": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6686", + "title": "[FIX] Update server cache indexes on record updates", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6684", + "title": "[FIX] Allow question on OAuth token path", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6163", + "title": "Env override initial setting", + "userLogin": "mrsimpson", + "milestone": "0.55.0", + "contributors": [ + "mrsimpson", + "web-flow" + ] + }, + { + "pr": "6683", + "title": "[FIX] Error when returning undefined from incoming intergation’s script", + "userLogin": "rodrigok", + "milestone": "0.55.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.55.0-rc.6": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6704", + "title": "[FIX] Fix message types", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.55.0": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6709", + "title": "[FIX] emoji picker exception", + "userLogin": "gdelavald", + "milestone": "0.55.0", + "contributors": [ + "gdelavald", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.55.1": { + "node_version": "4.8.0", + "npm_version": "4.3.0", + "pull_requests": [ + { + "pr": "6734", + "title": "[Fix] Bug with incoming integration (0.55.1)", + "userLogin": "rodrigok", + "milestone": "0.55.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.0": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6881", + "title": "[NEW] Add a pointer cursor to message images", + "userLogin": "MartinSchoeler", + "milestone": "0.56.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6842", + "title": "[New] Snap arm support", + "userLogin": "geekgonecrazy", + "milestone": "0.56.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "6861", + "title": "[FIX] start/unstar message", + "userLogin": "karlprieb", + "milestone": "0.56.0", + "contributors": [ + null + ] + }, + { + "pr": "6858", + "title": "Meteor update", + "userLogin": "engelgabriel", + "milestone": "0.56.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6845", + "title": "[FIX] Added helper for testing if the current user matches the params", + "userLogin": "abrom", + "milestone": "0.56.0", + "contributors": [ + "abrom" + ] + }, + { + "pr": "6827", + "title": "[NEW] Make channels.info accept roomName, just like groups.info", + "userLogin": "reist", + "milestone": "0.56.0", + "contributors": [ + "reist" + ] + }, + { + "pr": "6672", + "title": "Converted rocketchat-lib 3", + "userLogin": "ggazzo", + "milestone": "0.56.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6781", + "title": "Convert Message-Star Package to js ", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6780", + "title": "Convert Mailer Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.56.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6796", + "title": "[FIX] REST API user.update throwing error due to rate limiting", + "userLogin": "graywolf336", + "milestone": "0.56.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6797", + "title": "[NEW] Option to allow to signup as anonymous", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6816", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.56.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6807", + "title": "[NEW] create a method 'create token'", + "userLogin": "ggazzo", + "milestone": "0.56.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6804", + "title": "Missing useful fields in admin user list #5110", + "userLogin": "vlogic", + "milestone": "0.56.0", + "contributors": [ + null, + "vlogic" + ] + }, + { + "pr": "6790", + "title": "[FIX] fix german translation", + "userLogin": "sscholl", + "milestone": "0.56.0", + "contributors": [ + "sscholl", + "web-flow" + ] + }, + { + "pr": "6793", + "title": "[FIX] Improve and correct Iframe Integration help text", + "userLogin": "antgel", + "milestone": "0.56.0", + "contributors": [ + null + ] + }, + { + "pr": "6800", + "title": "[FIX] Quoted and replied messages not retaining the original message's alias", + "userLogin": "graywolf336", + "milestone": "0.56.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6798", + "title": "[FIX] Fix iframe wise issues", + "userLogin": "sampaiodiego", + "milestone": "0.56.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6747", + "title": "[FIX] Incorrect error message when creating channel", + "userLogin": "gdelavald", + "milestone": "0.56.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "6760", + "title": "[FIX] Hides nav buttons when selecting own profile", + "userLogin": "gdelavald", + "milestone": "0.56.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "6767", + "title": "[FIX] Search full name on client side", + "userLogin": "alexbrazier", + "milestone": "0.56.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "6758", + "title": "[FIX] Sort by real name if use real name setting is enabled", + "userLogin": "alexbrazier", + "milestone": "0.56.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "6671", + "title": "Convert Katex Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.56.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6688", + "title": "Convert Oembed Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.56.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6689", + "title": "Convert Mentions-Flextab Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.56.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6768", + "title": "[FIX] CSV importer: require that there is some data in the zip, not ALL data", + "userLogin": "reist", + "milestone": "0.56.0", + "contributors": [ + "reist" + ] + }, + { + "pr": "5986", + "title": "Anonymous use", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6368", + "title": "Breaking long URLS to prevent overflow", + "userLogin": "robertdown", + "milestone": "0.56.0", + "contributors": [ + "robertdown" + ] + }, + { + "pr": "6737", + "title": "[FIX] Archiving Direct Messages", + "userLogin": "graywolf336", + "milestone": "0.56.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "5373", + "title": "[NEW] Add option on Channel Settings: Hide Notifications and Hide Unread Room Status (#2707, #2143)", + "userLogin": "marceloschmidt", + "milestone": "0.56.0", + "contributors": [ + "marceloschmidt", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6593", + "title": "Rocketchat lib2", + "userLogin": "ggazzo", + "milestone": "0.56.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6734", + "title": "[Fix] Bug with incoming integration (0.55.1)", + "userLogin": "rodrigok", + "milestone": "0.55.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6722", + "title": "[NEW] Remove lesshat", + "userLogin": "karlprieb", + "milestone": "0.56.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "6654", + "title": "disable proxy configuration", + "userLogin": "glehmann", + "milestone": "0.56.0", + "contributors": [ + "glehmann" + ] + }, + { + "pr": "6721", + "title": "[FIX] Fix Caddy by forcing go 1.7 as needed by one of caddy's dependencies", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "6694", + "title": "Convert markdown to js", + "userLogin": "ehkasper", + "milestone": "0.56.0", + "contributors": [ + "ehkasper" + ] + }, + { + "pr": "6715", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.56.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6709", + "title": "[FIX] emoji picker exception", + "userLogin": "gdelavald", + "milestone": "0.55.0", + "contributors": [ + "gdelavald", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "6692", + "title": "[NEW] Use tokenSentVia parameter for clientid/secret to token endpoint", + "userLogin": "intelradoux", + "milestone": "0.56.0", + "contributors": [ + "intelradoux" + ] + }, + { + "pr": "6706", + "title": "meteor update to 1.4.4", + "userLogin": "engelgabriel", + "milestone": "0.56.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6704", + "title": "[FIX] Fix message types", + "userLogin": "sampaiodiego", + "milestone": "0.55.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6703", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6615", + "title": "[NEW] Add a setting to not run outgoing integrations on message edits", + "userLogin": "graywolf336", + "milestone": "0.56.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6734", + "title": "[Fix] Bug with incoming integration (0.55.1)", + "userLogin": "rodrigok", + "milestone": "0.55.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.1": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6896", + "title": "[FIX] Users status on main menu always offline", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.2": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6923", + "title": "[FIX] Not showing unread count on electron app’s icon", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.3": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6939", + "title": "[FIX] Compile CSS color variables", + "userLogin": "karlprieb", + "milestone": "0.56.0", + "contributors": [ + null + ] + }, + { + "pr": "6938", + "title": "[NEW] Improve CI/Docker build/release", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "6940", + "title": "[NEW] Add SMTP settings for Protocol and Pool", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.4": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6953", + "title": "[NEW] Show info about multiple instances at admin page", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.56.0-rc.5": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6955", + "title": "[FIX] Remove spaces from env PORT and INSTANCE_IP", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6935", + "title": "[Fix] Error when trying to show preview of undefined filetype", + "userLogin": "geekgonecrazy", + "milestone": "0.57.0", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.56.0-rc.6": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [] + }, + "0.56.0-rc.7": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6968", + "title": "[FIX] make channels.create API check for create-c", + "userLogin": "reist", + "milestone": "0.56.0", + "contributors": [ + "reist" + ] + } + ] + }, + "0.56.0": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "6734", + "title": "[Fix] Bug with incoming integration (0.55.1)", + "userLogin": "rodrigok", + "milestone": "0.55.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.57.0-rc.0": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7146", + "title": "Convert hipchat importer to js", + "userLogin": "rodrigok", + "milestone": "0.57.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "sampaiodiego", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7145", + "title": "Convert file unsubscribe.coffee to js", + "userLogin": "rodrigok", + "milestone": "0.57.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6991", + "title": "[FIX] Fix highlightjs bug", + "userLogin": "geekgonecrazy", + "milestone": "0.57.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "6788", + "title": "[NEW] New avatar storage types", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "7095", + "title": "[BREAK] Internal hubot does not load hubot-scripts anymore, it loads scripts from custom folders", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "6690", + "title": "[NEW] Show full name in mentions if use full name setting enabled", + "userLogin": "alexbrazier", + "milestone": "0.57.0", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "7017", + "title": "Convert oauth2-server-config package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7022", + "title": "Convert irc package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7055", + "title": "Ldap: User_Data_FieldMap description", + "userLogin": "bbrauns", + "milestone": "0.57.0", + "contributors": [ + "bbrauns" + ] + }, + { + "pr": "7030", + "title": "[FIX] do only store password if LDAP_Login_Fallback is on", + "userLogin": "pmb0", + "milestone": "0.57.0", + "contributors": [ + "pmb0" + ] + }, + { + "pr": "7059", + "title": "[NEW] Increase unread message count on @here mention", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7062", + "title": "Remove Useless Jasmine Tests ", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7121", + "title": "[FIX] fix bug in preview image", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7094", + "title": "[FIX]Fix the failing tests ", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7085", + "title": "[NEW] API method and REST Endpoint for getting a single message by id", + "userLogin": "graywolf336", + "milestone": "0.57.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7084", + "title": "[FIX] Add option to ignore TLS in SMTP server settings", + "userLogin": "colin-campbell", + "milestone": "0.57.0", + "contributors": [ + "colin-campbell" + ] + }, + { + "pr": "7072", + "title": "[FIX] Add support for carriage return in markdown code blocks", + "userLogin": "jm-factorin", + "milestone": "0.57.0", + "contributors": [ + "jm-factorin" + ] + }, + { + "pr": "7014", + "title": "[FIX] Parse HTML on admin setting's descriptions", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7018", + "title": "converted rocketchat-importer", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7114", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7105", + "title": "[FIX] edit button on firefox", + "userLogin": "karlprieb", + "milestone": "0.57.0", + "contributors": [ + null + ] + }, + { + "pr": "7104", + "title": "[FIX] Fix missing CSS files on production builds", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + null + ] + }, + { + "pr": "7103", + "title": "[FIX] clipboard (permalink, copy, pin, star buttons)", + "userLogin": "karlprieb", + "contributors": [ + null + ] + }, + { + "pr": "7096", + "title": "Convert Livechat from Coffeescript to JavaScript", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7092", + "title": "[FIX]Fixed typo hmtl -> html", + "userLogin": "jautero", + "contributors": [ + "jautero" + ] + }, + { + "pr": "7080", + "title": "[NEW] Migration to add tags to email header and footer", + "userLogin": "karlprieb", + "milestone": "0.57.0", + "contributors": [ + null + ] + }, + { + "pr": "7025", + "title": "[FIX] Add and to header and footer", + "userLogin": "ExTechOp", + "milestone": "0.57.0", + "contributors": [ + "ExTechOp", + "web-flow" + ] + }, + { + "pr": "7033", + "title": "[FIX] Prevent Ctrl key on message field from reloading messages list", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7044", + "title": "[FIX] New screen sharing Chrome extension checking method", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6982", + "title": "[NEW] postcss parser and cssnext implementation", + "userLogin": "karlprieb", + "contributors": [ + null, + "rodrigok", + "web-flow", + "MartinSchoeler" + ] + }, + { + "pr": "7049", + "title": "[FIX] Improve Tests", + "userLogin": "MartinSchoeler", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7045", + "title": "[FIX] Fix avatar upload via users.setAvatar REST endpoint", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7023", + "title": "[FIX] Sidenav roomlist", + "userLogin": "karlprieb", + "contributors": [ + null, + "sampaiodiego" + ] + }, + { + "pr": "7012", + "title": "[FIX] video message recording dialog is shown in an incorrect position", + "userLogin": "flaviogrossi", + "milestone": "0.57.0", + "contributors": [ + "flaviogrossi" + ] + }, + { + "pr": "7006", + "title": "Rocketchat ui3", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6836", + "title": "converted rocketchat-ui coffee to js part 2", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6912", + "title": "[FIX] Remove room from roomPick setting", + "userLogin": "marceloschmidt", + "milestone": "0.57.0", + "contributors": [ + "marceloschmidt", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "6605", + "title": "[NEW] Start running unit tests", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok", + "engelgabriel" + ] + }, + { + "pr": "6997", + "title": "[FIX] Parse markdown links last", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6999", + "title": "[FIX] overlapping text for users-typing-message", + "userLogin": "darkv", + "milestone": "0.57.0", + "contributors": [ + "darkv" + ] + }, + { + "pr": "7005", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6735", + "title": "rocketchat-lib[4] coffee to js", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6987", + "title": "rocketchat-importer-slack coffee to js", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6911", + "title": "Convert ui-admin package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6857", + "title": "[NEW] Make channel/group delete call answer to roomName", + "userLogin": "reist", + "milestone": "0.57.0", + "contributors": [ + "reist" + ] + }, + { + "pr": "6903", + "title": "[FIX] Updating Incoming Integration Post As Field Not Allowed", + "userLogin": "graywolf336", + "milestone": "0.57.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6972", + "title": "[FIX] Fix error handling for non-valid avatar URL", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6914", + "title": "Rocketchat ui message", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "6921", + "title": "[New] LDAP: Use variables in User_Data_FieldMap for name mapping", + "userLogin": "bbrauns", + "milestone": "0.57.0", + "contributors": [ + "bbrauns" + ] + }, + { + "pr": "6961", + "title": "[FIX] SAML: Only set KeyDescriptor when non empty", + "userLogin": "sathieu", + "milestone": "0.57.0", + "contributors": [ + "sathieu" + ] + }, + { + "pr": "6986", + "title": "[FIX] Fix the other tests failing due chimp update", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6936", + "title": "Convert meteor-autocomplete package to js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6795", + "title": "Convert Ui Account Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6950", + "title": "[FIX] Fix badge counter on iOS push notifications", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6974", + "title": "[FIX] Fix login with Meteor saving an object as email address", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6840", + "title": "[FIX] Check that username is not in the room when being muted / unmuted", + "userLogin": "matthewshirley", + "milestone": "0.57.0", + "contributors": [ + "matthewshirley", + "web-flow" + ] + }, + { + "pr": "6947", + "title": "[FIX] Use AWS Signature Version 4 signed URLs for uploads", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "6978", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.57.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "6976", + "title": "fix the crashing tests", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "6968", + "title": "[FIX] make channels.create API check for create-c", + "userLogin": "reist", + "milestone": "0.56.0", + "contributors": [ + "reist" + ] + }, + { + "pr": "6775", + "title": "Convert WebRTC Package to Js", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "6935", + "title": "[Fix] Error when trying to show preview of undefined filetype", + "userLogin": "geekgonecrazy", + "milestone": "0.57.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "6953", + "title": "[NEW] Show info about multiple instances at admin page", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "6938", + "title": "[NEW] Improve CI/Docker build/release", + "userLogin": "rodrigok", + "milestone": "0.56.0", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "6919", + "title": "[NEW] Feature/delete any message permission", + "userLogin": "phutchins", + "milestone": "0.57.0", + "contributors": [ + "phutchins" + ] + }, + { + "pr": "6904", + "title": "[FIX] Bugs in `isUserFromParams` helper", + "userLogin": "abrom", + "milestone": "0.57.0", + "contributors": [ + "abrom" + ] + }, + { + "pr": "6910", + "title": "[FIX] Allow image insert from slack through slackbridge", + "userLogin": "marceloschmidt", + "milestone": "0.57.0", + "contributors": [ + "marceloschmidt" + ] + }, + { + "pr": "6913", + "title": "[FIX] Slackbridge text replacements", + "userLogin": "marceloschmidt", + "milestone": "0.57.0", + "contributors": [ + "marceloschmidt" + ] + } + ] + }, + "0.57.0-rc.1": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7157", + "title": "[FIX] Fix all reactions having the same username", + "userLogin": "MartinSchoeler", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "7154", + "title": "Remove missing CoffeeScript dependencies", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7158", + "title": "Switch logic of artifact name", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + } + ] + }, + "0.57.0-rc.2": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7200", + "title": "[FIX] Fix editing others messages", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7208", + "title": "[FIX] Fix oembed previews not being shown", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7215", + "title": "Fix the Zapier oAuth return url to the new one", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7209", + "title": "[FIX] \"requirePasswordChange\" property not being saved when set to false", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7196", + "title": "Fix the admin oauthApps view not working", + "userLogin": "graywolf336", + "milestone": "0.57.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7160", + "title": "[FIX] Removing the kadira package install from example build script.", + "userLogin": "JSzaszvari", + "contributors": [ + "JSzaszvari", + "web-flow" + ] + }, + { + "pr": "7159", + "title": "Fix forbidden error on setAvatar REST endpoint", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7196", + "title": "Fix the admin oauthApps view not working", + "userLogin": "graywolf336", + "milestone": "0.57.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7177", + "title": "Fix mobile avatars", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.57.0-rc.3": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7358", + "title": "[FIX] Fix user's customFields not being saved correctly", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7352", + "title": "[FIX] Improve avatar migration", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7311", + "title": "[NEW] Force use of MongoDB for spotlight queries", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7320", + "title": "[FIX] Fix jump to unread button", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7345", + "title": "[FIX] click on image in a message", + "userLogin": "ggazzo", + "milestone": "0.57.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7304", + "title": "[FIX] Proxy upload to correct instance", + "userLogin": "rodrigok", + "milestone": "0.57.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7321", + "title": "[FIX] Fix Secret Url", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + } + ] + }, + "0.57.0": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7379", + "title": "[FIX] Message being displayed unescaped", + "userLogin": "gdelavald", + "milestone": "0.58.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7102", + "title": "add server methods getRoomNameById", + "userLogin": "thinkeridea", + "milestone": "0.57.0", + "contributors": [ + "thinkeridea" + ] + } + ] + }, + "0.57.1": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7428", + "title": "[FIX] Fix migration of avatars from version 0.57.0", + "userLogin": "rodrigok", + "milestone": "0.57.1", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + } + ] + }, + "0.57.2": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7431", + "title": "[FIX] Fix Emails in User Admin View", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7472", + "title": "[FIX] Always set LDAP properties on login", + "userLogin": "sampaiodiego", + "milestone": "0.57.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7403", + "title": "[FIX] Fix Unread Bar Disappearing", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7469", + "title": "[FIX] Fix file upload on Slack import", + "userLogin": "sampaiodiego", + "milestone": "0.57.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7432", + "title": "[FIX] Fix Private Channel List Submit", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7443", + "title": "[FIX] S3 uploads not working for custom URLs", + "userLogin": "rodrigok", + "milestone": "0.57.2", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.57.3": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "7212", + "title": "[Fix] Users and Channels list not respecting permissions", + "userLogin": "graywolf336", + "milestone": "0.57.3", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7325", + "title": "[FIX] Modernize rate limiting of sendMessage", + "userLogin": "jangmarker", + "milestone": "0.57.3", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7390", + "title": "[FIX] custom soundEdit.html", + "userLogin": "rasos", + "milestone": "0.57.3", + "contributors": [ + "rasos", + "web-flow" + ] + }, + { + "pr": "7394", + "title": "[FIX] Use UTF8 setting for /create command", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7395", + "title": "[FIX] file upload broken when running in subdirectory https://github.com…", + "userLogin": "ryoshimizu", + "milestone": "0.57.3", + "contributors": [ + "ryoshimizu" + ] + }, + { + "pr": "7444", + "title": "[FIX] Fix Anonymous User", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7533", + "title": "[FIX] Missing eventName in unUser", + "userLogin": "Darkneon", + "milestone": "0.57.3", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7535", + "title": "[FIX] Fix Join Channel Without Preview Room Permission", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7555", + "title": "[FIX] Improve build script example", + "userLogin": "sampaiodiego", + "milestone": "0.57.3", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.57.4": { + "node_version": "4.8.2", + "npm_version": "4.5.0", + "pull_requests": [ + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.58.0-rc.0": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "7212", + "title": "[Fix] Users and Channels list not respecting permissions", + "userLogin": "graywolf336", + "milestone": "0.57.3", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7325", + "title": "[FIX] Modernize rate limiting of sendMessage", + "userLogin": "jangmarker", + "milestone": "0.57.3", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7390", + "title": "[FIX] custom soundEdit.html", + "userLogin": "rasos", + "milestone": "0.57.3", + "contributors": [ + "rasos", + "web-flow" + ] + }, + { + "pr": "7394", + "title": "[FIX] Use UTF8 setting for /create command", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7395", + "title": "[FIX] file upload broken when running in subdirectory https://github.com…", + "userLogin": "ryoshimizu", + "milestone": "0.57.3", + "contributors": [ + "ryoshimizu" + ] + }, + { + "pr": "7444", + "title": "[FIX] Fix Anonymous User", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7533", + "title": "[FIX] Missing eventName in unUser", + "userLogin": "Darkneon", + "milestone": "0.57.3", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7535", + "title": "[FIX] Fix Join Channel Without Preview Room Permission", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7555", + "title": "[FIX] Improve build script example", + "userLogin": "sampaiodiego", + "milestone": "0.57.3", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7624", + "title": "[FIX] Error when updating message with an empty attachment array", + "userLogin": "graywolf336", + "milestone": "0.58.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7623", + "title": "[FIX] Uploading an unknown file type erroring out", + "userLogin": "graywolf336", + "milestone": "0.58.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7622", + "title": "[FIX] Error when acessing settings before ready", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7608", + "title": "Add missing parts of `one click to direct message`", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7621", + "title": "[FIX] Message box on safari", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7620", + "title": "[FIX] The username not being allowed to be passed into the user.setAvatar", + "userLogin": "graywolf336", + "milestone": "0.58.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7613", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7617", + "title": "[FIX] Fix Custom Fields Crashing on Register", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7615", + "title": "Improve link parser using tokens", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7616", + "title": "Improve login error messages", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7595", + "title": "[NEW] Allow special chars on room names", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7594", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.58.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7479", + "title": "[NEW] Add admin and user setting for notifications #4339", + "userLogin": "stalley", + "milestone": "0.58.0", + "contributors": [ + "stalley", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "7309", + "title": "[NEW] Edit user permissions", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "7324", + "title": "[NEW] Adding support for piwik sub domain settings", + "userLogin": "ruKurz", + "milestone": "0.58.0", + "contributors": [ + "ruKurz" + ] + }, + { + "pr": "7578", + "title": "Improve room leader", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7582", + "title": "[FIX] Fix admin room list show the correct i18n type", + "userLogin": "ccfang", + "milestone": "0.58.0", + "contributors": [ + "ccfang", + "rodrigok" + ] + }, + { + "pr": "6753", + "title": "[NEW] Add setting to change User Agent of OEmbed calls", + "userLogin": "AhmetS", + "milestone": "0.58.0", + "contributors": [ + "AhmetS", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "7517", + "title": "[NEW] Configurable Volume for Notifications #6087", + "userLogin": "lindoelio", + "milestone": "0.58.0", + "contributors": [ + "lindoelio" + ] + }, + { + "pr": "7590", + "title": "Develop sync", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "6564", + "title": "[NEW] Add customFields in rooms/get method", + "userLogin": "borsden", + "milestone": "0.58.0", + "contributors": [ + "borsden" + ] + }, + { + "pr": "7589", + "title": "[NEW] Option to select unread count style", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7580", + "title": "[NEW] Show different shape for alert numbers when have mentions", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7533", + "title": "[FIX] Missing eventName in unUser", + "userLogin": "Darkneon", + "milestone": "0.57.3", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7569", + "title": "[NEW] Add reaction to the last message when get the shortcut +:", + "userLogin": "danilomiranda", + "milestone": "0.58.0", + "contributors": [ + "danilomiranda", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7513", + "title": "[Fix] Don't save user to DB when a custom field is invalid", + "userLogin": "Darkneon", + "milestone": "0.58.0", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7538", + "title": "[FIX] URL parse error fix for issue #7169", + "userLogin": "satyapramodh", + "milestone": "0.58.0", + "contributors": [ + "satyapramodh", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7559", + "title": "[NEW] Show emojis and file uploads on notifications", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "7561", + "title": "[NEW] Closes tab bar on mobile when leaving room", + "userLogin": "gdelavald", + "milestone": "0.58.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7572", + "title": "[FIX] User avatar image background", + "userLogin": "filipedelimabrito", + "milestone": "0.58.0", + "contributors": [ + "filipedelimabrito", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "7564", + "title": "[NEW] Adds preference to one-click-to-direct-message and basic functionality", + "userLogin": "gdelavald", + "milestone": "0.58.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7555", + "title": "[FIX] Improve build script example", + "userLogin": "sampaiodiego", + "milestone": "0.57.3", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7535", + "title": "[FIX] Fix Join Channel Without Preview Room Permission", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7334", + "title": "[NEW] Search users also by email in toolbar", + "userLogin": "shahar3012", + "milestone": "0.58.0", + "contributors": [ + "shahar3012" + ] + }, + { + "pr": "7326", + "title": "[NEW] Do not rate limit bots on createDirectMessage", + "userLogin": "jangmarker", + "milestone": "0.58.0", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7214", + "title": "[NEW] Allow channel property in the integrations returned content", + "userLogin": "graywolf336", + "milestone": "0.58.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7212", + "title": "[Fix] Users and Channels list not respecting permissions", + "userLogin": "graywolf336", + "milestone": "0.57.3", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7554", + "title": "[FIX] Look for livechat visitor IP address on X-Forwarded-For header", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7556", + "title": "[BREAK] Remove Sandstorm login method", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7557", + "title": "[FIX] Revert emojione package version upgrade", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7562", + "title": "[FIX] Stop logging mentions object to console", + "userLogin": "gdelavald", + "milestone": "0.58.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7500", + "title": "Develop sync", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "thinkeridea", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7520", + "title": "[NEW] Add room type identifier to room list header", + "userLogin": "danischreiber", + "milestone": "0.58.0", + "contributors": [ + "danischreiber", + "sampaiodiego" + ] + }, + { + "pr": "7523", + "title": "[NEW] Room type and recipient data for global event", + "userLogin": "danischreiber", + "milestone": "0.58.0", + "contributors": [ + "danischreiber" + ] + }, + { + "pr": "7526", + "title": "[NEW] Show room leader at top of chat when user scrolls down. Set and unset leader as admin.", + "userLogin": "danischreiber", + "milestone": "0.58.0", + "contributors": [ + "danischreiber" + ] + }, + { + "pr": "7525", + "title": "[NEW] Add toolbar buttons for iframe API", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7492", + "title": "Better Issue Template", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "7529", + "title": "[NEW] Add close button to flex tabs", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7496", + "title": "[NEW] Update meteor to 1.5.1", + "userLogin": "engelgabriel", + "milestone": "0.58.0", + "contributors": [ + "engelgabriel", + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "7486", + "title": "[FIX] Fix hiding flex-tab on embedded view", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7195", + "title": "[FIX] Fix emoji picker translations", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7325", + "title": "[FIX] Modernize rate limiting of sendMessage", + "userLogin": "jangmarker", + "milestone": "0.57.3", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7390", + "title": "[FIX] custom soundEdit.html", + "userLogin": "rasos", + "milestone": "0.57.3", + "contributors": [ + "rasos", + "web-flow" + ] + }, + { + "pr": "7394", + "title": "[FIX] Use UTF8 setting for /create command", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7395", + "title": "[FIX] file upload broken when running in subdirectory https://github.com…", + "userLogin": "ryoshimizu", + "milestone": "0.57.3", + "contributors": [ + "ryoshimizu" + ] + }, + { + "pr": "7444", + "title": "[FIX] Fix Anonymous User", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7471", + "title": "[FIX] Issue #7365: added check for the existence of a parameter in the CAS URL", + "userLogin": "wsw70", + "milestone": "0.58.0", + "contributors": [ + "wsw70" + ] + }, + { + "pr": "7392", + "title": "[FIX] Fix Word Placement Anywhere on WebHooks", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7487", + "title": "[FIX] Prevent new room status from playing when user status changes", + "userLogin": "sampaiodiego", + "milestone": "0.58.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7443", + "title": "[FIX] S3 uploads not working for custom URLs", + "userLogin": "rodrigok", + "milestone": "0.57.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7432", + "title": "[FIX] Fix Private Channel List Submit", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7469", + "title": "[FIX] Fix file upload on Slack import", + "userLogin": "sampaiodiego", + "milestone": "0.57.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7403", + "title": "[FIX] Fix Unread Bar Disappearing", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7472", + "title": "[FIX] Always set LDAP properties on login", + "userLogin": "sampaiodiego", + "milestone": "0.57.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7448", + "title": "[NEW] flex-tab now is side by side with message list", + "userLogin": "ggazzo", + "milestone": "0.58.0", + "contributors": [ + "ggazzo", + "karlprieb", + "MartinSchoeler" + ] + }, + { + "pr": "7477", + "title": "[NEW] Option to select unread count behavior", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7205", + "title": "[FIX] url click events in the cordova app open in external browser or not at all", + "userLogin": "flaviogrossi", + "milestone": "0.58.0", + "contributors": [ + "flaviogrossi" + ] + }, + { + "pr": "7431", + "title": "[FIX] Fix Emails in User Admin View", + "userLogin": "MartinSchoeler", + "milestone": "0.57.2", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7428", + "title": "[FIX] Fix migration of avatars from version 0.57.0", + "userLogin": "rodrigok", + "milestone": "0.57.1", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "6340", + "title": "Add helm chart kubernetes deployment", + "userLogin": "pierreozoux", + "milestone": "0.58.0", + "contributors": [ + "pierreozoux" + ] + }, + { + "pr": "7404", + "title": "[FIX] sweetalert alignment on mobile", + "userLogin": "karlprieb", + "milestone": "0.58.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7376", + "title": "[FIX] Sweet-Alert modal popup position on mobile devices", + "userLogin": "Oliver84", + "milestone": "0.58.0", + "contributors": [ + "Oliver84", + "web-flow" + ] + }, + { + "pr": "7355", + "title": "[FIX] Update node-engine in Snap to latest v4 LTS relase: 4.8.3", + "userLogin": "al3x", + "milestone": "0.58.0", + "contributors": [ + "al3x" + ] + }, + { + "pr": "7354", + "title": "[FIX] Remove warning about 2FA support being unavailable in mobile apps", + "userLogin": "al3x", + "milestone": "0.58.0", + "contributors": [ + "al3x" + ] + }, + { + "pr": "7363", + "title": "Develop sync", + "userLogin": "rodrigok", + "milestone": "0.58.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "JSzaszvari", + "MartinSchoeler", + "graywolf336", + "sampaiodiego", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7308", + "title": "Escape error messages", + "userLogin": "rodrigok", + "milestone": "0.57.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7322", + "title": "[FIX] Fix geolocation button", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7207", + "title": "[FIX] Fix Block Delete Message After (n) Minutes", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7311", + "title": "[NEW] Force use of MongoDB for spotlight queries", + "userLogin": "sampaiodiego", + "milestone": "0.57.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7320", + "title": "[FIX] Fix jump to unread button", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7321", + "title": "[FIX] Fix Secret Url", + "userLogin": "MartinSchoeler", + "milestone": "0.57.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7199", + "title": "[FIX] Use I18n on \"File Uploaded\"", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7287", + "title": "update meteor to 1.5.0", + "userLogin": "engelgabriel", + "milestone": "0.58.0", + "contributors": [ + "engelgabriel", + "rodrigok" + ] + }, + { + "pr": "7215", + "title": "Fix the Zapier oAuth return url to the new one", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7209", + "title": "[FIX] \"requirePasswordChange\" property not being saved when set to false", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7211", + "title": "[New] Add instance id to response headers", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "7184", + "title": "[NEW] Add healthchecks in OpenShift templates", + "userLogin": "jfchevrette", + "contributors": [ + "jfchevrette" + ] + }, + { + "pr": "7208", + "title": "[FIX] Fix oembed previews not being shown", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7200", + "title": "[FIX] Fix editing others messages", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7187", + "title": "[FIX] Fix error on image preview due to undefined description|title ", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + } + ] + }, + "0.58.0-rc.1": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7629", + "title": "[FIX] Fix messagebox growth", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7630", + "title": "[FIX] Wrong render of snippet’s name", + "userLogin": "rodrigok", + "milestone": "0.58.0-rc.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7658", + "title": "[NEW] Add unread options for direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7687", + "title": "[FIX] Fix room load on first hit", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7644", + "title": "[FIX] Markdown noopener/noreferrer: use correct HTML attribute", + "userLogin": "jangmarker", + "milestone": "0.58.0-rc.1", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7652", + "title": "Only use \"File Uploaded\" prefix on files", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0-rc.1", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "7639", + "title": "[FIX] Wrong email subject when \"All Messages\" setting enabled", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0-rc.1", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + } + ] + }, + "0.58.0-rc.2": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7456", + "title": "[FIX] Csv importer: work with more problematic data", + "userLogin": "reist", + "milestone": "0.58.0-rc.2", + "contributors": [ + "reist" + ] + } + ] + }, + "0.58.0-rc.3": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7738", + "title": "[FIX] make flex-tab visible again when reduced width", + "userLogin": "geekgonecrazy", + "milestone": "0.58.0-rc.3", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.58.0": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7752", + "title": "Release 0.58.0", + "userLogin": "rodrigok", + "contributors": [ + "ryoshimizu", + "rodrigok", + "web-flow", + "MartinSchoeler", + "karlprieb", + "engelgabriel", + "sampaiodiego", + "pierreozoux", + "geekgonecrazy", + "jangmarker", + "flaviogrossi", + "ggazzo" + ] + }, + { + "pr": "7690", + "title": "Sync Master with 0.57.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7212", + "title": "[Fix] Users and Channels list not respecting permissions", + "userLogin": "graywolf336", + "milestone": "0.57.3", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "7325", + "title": "[FIX] Modernize rate limiting of sendMessage", + "userLogin": "jangmarker", + "milestone": "0.57.3", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7390", + "title": "[FIX] custom soundEdit.html", + "userLogin": "rasos", + "milestone": "0.57.3", + "contributors": [ + "rasos", + "web-flow" + ] + }, + { + "pr": "7394", + "title": "[FIX] Use UTF8 setting for /create command", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7395", + "title": "[FIX] file upload broken when running in subdirectory https://github.com…", + "userLogin": "ryoshimizu", + "milestone": "0.57.3", + "contributors": [ + "ryoshimizu" + ] + }, + { + "pr": "7444", + "title": "[FIX] Fix Anonymous User", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7533", + "title": "[FIX] Missing eventName in unUser", + "userLogin": "Darkneon", + "milestone": "0.57.3", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7535", + "title": "[FIX] Fix Join Channel Without Preview Room Permission", + "userLogin": "MartinSchoeler", + "milestone": "0.57.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7555", + "title": "[FIX] Improve build script example", + "userLogin": "sampaiodiego", + "milestone": "0.57.3", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.58.1": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7782", + "title": "Release 0.58.1", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7781", + "title": "[FIX] Fix flex tab not opening and getting offscreen", + "userLogin": "MartinSchoeler", + "contributors": [ + "MartinSchoeler" + ] + } + ] + }, + "0.58.2": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7841", + "title": "Release 0.58.2", + "userLogin": "geekgonecrazy", + "milestone": "0.58.2", + "contributors": [ + "snoozan", + "geekgonecrazy" + ] + } + ] + }, + "0.58.3": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [] + }, + "0.58.4": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.59.0-rc.0": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "7864", + "title": "[NEW] Replace message cog for vertical menu", + "userLogin": "karlprieb", + "milestone": "0.59.0", + "contributors": [ + "karlprieb", + "rodrigok" + ] + }, + { + "pr": "7865", + "title": "Mobile sidenav", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7830", + "title": "[NEW] block users to mention unknow users", + "userLogin": "ggazzo", + "milestone": "0.59.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7614", + "title": "[NEW] Allow ldap mapping of customFields", + "userLogin": "goiaba", + "milestone": "0.59.0", + "contributors": [ + "goiaba", + "web-flow" + ] + }, + { + "pr": "7853", + "title": "[NEW] Create a standard for our svg icons", + "userLogin": "karlprieb", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7565", + "title": "[NEW] Allows admin to list all groups with API", + "userLogin": "mboudet", + "contributors": [ + "mboudet", + "web-flow" + ] + }, + { + "pr": "7855", + "title": "[FIX] File upload on multi-instances using a path prefix", + "userLogin": "Darkneon", + "milestone": "0.59.0", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7863", + "title": "[FIX] Fix migration 100", + "userLogin": "ggazzo", + "milestone": "0.59.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7852", + "title": "[NEW] Add markdown parser \"marked\"", + "userLogin": "rodrigok", + "milestone": "0.59.0", + "contributors": [ + "nishimaki10", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "7817", + "title": "[NEW] Audio Notification updated in sidebar", + "userLogin": "aditya19496", + "milestone": "0.59.0", + "contributors": [ + "maarten-v", + "web-flow", + "aditya19496", + "engelgabriel", + "ggazzo" + ] + }, + { + "pr": "7846", + "title": "[FIX] Email message forward error", + "userLogin": "rodrigok", + "milestone": "0.59.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7854", + "title": "[FIX] Add CSS support for Safari versions > 7", + "userLogin": "sampaiodiego", + "milestone": "0.59.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7612", + "title": "[NEW] Search users by fields defined by admin", + "userLogin": "goiaba", + "milestone": "0.59.0", + "contributors": [ + "goiaba" + ] + }, + { + "pr": "7688", + "title": "[NEW] Template to show Custom Fields in user info view", + "userLogin": "goiaba", + "milestone": "0.59.0", + "contributors": [ + "goiaba" + ] + }, + { + "pr": "7842", + "title": "npm deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7168", + "title": "[FIX] Fix black background on transparent avatars", + "userLogin": "ggazzo", + "milestone": "0.59.0", + "contributors": [ + "ggazzo", + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "7711", + "title": "[NEW] Add room type as a class to the ul-group of rooms", + "userLogin": "danischreiber", + "milestone": "0.59.0", + "contributors": [ + "danischreiber", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "7636", + "title": "[NEW] Add classes to notification menu so they can be hidden in css", + "userLogin": "danischreiber", + "milestone": "0.59.0", + "contributors": [ + "danischreiber" + ] + }, + { + "pr": "5902", + "title": "[NEW] Adds a Keyboard Shortcut option to the flextab", + "userLogin": "cnash", + "milestone": "0.59.0", + "contributors": [ + "cnash", + "web-flow", + "karlprieb", + "rodrigok" + ] + }, + { + "pr": "7342", + "title": "[NEW] Integrated personal email gateway (GSoC'17)", + "userLogin": "pkgodara", + "milestone": "0.59.0", + "contributors": [ + "pkgodara", + "web-flow" + ] + }, + { + "pr": "7803", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.59.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7825", + "title": "[FIX] Google vision NSFW tag", + "userLogin": "marceloschmidt", + "milestone": "0.59.0", + "contributors": [ + "marceloschmidt" + ] + }, + { + "pr": "7793", + "title": "Additions to the REST API", + "userLogin": "graywolf336", + "milestone": "0.59.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "6301", + "title": "[NEW] Add tags to uploaded images using Google Cloud Vision API", + "userLogin": "marceloschmidt", + "milestone": "0.59.0", + "contributors": [ + "marceloschmidt", + "karlprieb", + "engelgabriel", + "web-flow", + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "6700", + "title": "[NEW] Package to render issue numbers into links to an issue tracker.", + "userLogin": "TobiasKappe", + "milestone": "0.59.0", + "contributors": [ + "TobiasKappe", + "TAdeJong" + ] + }, + { + "pr": "7721", + "title": "[FIX] meteor-accounts-saml issue with ns0,ns1 namespaces, makes it compatible with pysaml2 lib", + "userLogin": "arminfelder", + "milestone": "0.59.0", + "contributors": [ + "arminfelder" + ] + }, + { + "pr": "7823", + "title": "[FIX] Fix new-message button showing on search", + "userLogin": "sampaiodiego", + "milestone": "0.59.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7350", + "title": "[NEW] Automatically select the first channel", + "userLogin": "antaryami-sahoo", + "milestone": "0.59.0", + "contributors": [ + "antaryami-sahoo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "7779", + "title": "[FIX] Settings not getting applied from Meteor.settings and process.env ", + "userLogin": "Darkneon", + "milestone": "0.59.0", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "7748", + "title": "[FIX] scroll on flex-tab", + "userLogin": "ggazzo", + "milestone": "0.59.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7755", + "title": "npm deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7728", + "title": "FIX: Error when starting local development environment", + "userLogin": "rdebeasi", + "milestone": "0.59.0", + "contributors": [ + "rdebeasi" + ] + }, + { + "pr": "7815", + "title": "[FIX] Dutch translations", + "userLogin": "maarten-v", + "contributors": [ + "maarten-v", + "web-flow" + ] + }, + { + "pr": "7814", + "title": "[FIX] Fix Dutch translation", + "userLogin": "maarten-v", + "contributors": [ + "maarten-v", + "web-flow" + ] + }, + { + "pr": "7778", + "title": "[FIX] Update Snap links", + "userLogin": "MichaelGooden", + "contributors": [ + "MichaelGooden", + "web-flow" + ] + }, + { + "pr": "7809", + "title": "[FIX] Remove redundant \"do\" in \"Are you sure ...?\" messages.", + "userLogin": "xurizaemon", + "contributors": [ + "xurizaemon" + ] + }, + { + "pr": "7758", + "title": "[FIX] Fixed function closure syntax allowing validation emails to be sent.", + "userLogin": "snoozan", + "milestone": "0.58.2", + "contributors": [ + "snoozan" + ] + }, + { + "pr": "7739", + "title": "Remove CircleCI", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7643", + "title": "[NEW] Rocket.Chat UI Redesign", + "userLogin": "MartinSchoeler", + "contributors": [ + null, + "ggazzo", + "sampaiodiego" + ] + }, + { + "pr": "7677", + "title": "Meteor packages and npm dependencies update", + "userLogin": "engelgabriel", + "milestone": "0.59.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7456", + "title": "[FIX] Csv importer: work with more problematic data", + "userLogin": "reist", + "milestone": "0.58.0-rc.2", + "contributors": [ + "reist" + ] + }, + { + "pr": "7656", + "title": "[FIX] Fix avatar upload fail on Cordova app", + "userLogin": "ccfang", + "milestone": "0.58.0", + "contributors": [ + "ccfang" + ] + }, + { + "pr": "7679", + "title": "[FIX] Make link inside YouTube preview open in new tab", + "userLogin": "1lann", + "milestone": "0.59.0", + "contributors": [ + "1lann", + "web-flow" + ] + }, + { + "pr": "7664", + "title": "[MOVE] Client folder rocketchat-colors", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7665", + "title": "[MOVE] Client folder rocketchat-custom-oauth", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7666", + "title": "[MOVE] Client folder rocketchat-tooltip", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7667", + "title": "[MOVE] Client folder rocketchat-autolinker", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7668", + "title": "[MOVE] Client folder rocketchat-cas", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7669", + "title": "[MOVE] Client folder rocketchat-highlight-words", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7670", + "title": "[MOVE] Client folder rocketchat-custom-sounds", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7671", + "title": "[MOVE] Client folder rocketchat-emoji", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7672", + "title": "[FIX] Remove references to non-existent tests", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7673", + "title": "[FIX] Example usage of unsubscribe.js", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0", + "contributors": [ + "Kiran-Rao" + ] + }, + { + "pr": "7639", + "title": "[FIX] Wrong email subject when \"All Messages\" setting enabled", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0-rc.1", + "contributors": [ + "MartinSchoeler", + "rodrigok" + ] + }, + { + "pr": "7652", + "title": "Only use \"File Uploaded\" prefix on files", + "userLogin": "MartinSchoeler", + "milestone": "0.58.0-rc.1", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "7644", + "title": "[FIX] Markdown noopener/noreferrer: use correct HTML attribute", + "userLogin": "jangmarker", + "milestone": "0.58.0-rc.1", + "contributors": [ + "jangmarker" + ] + }, + { + "pr": "7687", + "title": "[FIX] Fix room load on first hit", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7658", + "title": "[NEW] Add unread options for direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7661", + "title": "Fix typo in generated URI", + "userLogin": "Rohlik", + "contributors": [ + "Rohlik", + "web-flow" + ] + }, + { + "pr": "7625", + "title": "Bump version to 0.59.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7630", + "title": "[FIX] Wrong render of snippet’s name", + "userLogin": "rodrigok", + "milestone": "0.58.0-rc.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7629", + "title": "[FIX] Fix messagebox growth", + "userLogin": "sampaiodiego", + "milestone": "0.58.0-rc.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "2", + "title": "implemented new page-loader animated icon", + "userLogin": "rcaferati", + "contributors": [ + null + ] + } + ] + }, + "0.59.0-rc.1": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7880", + "title": "[FIX] sidebar paddings", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7878", + "title": "[FIX] Adds default search text padding for emoji search", + "userLogin": "gdelavald", + "milestone": "0.59.0-rc.1", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7881", + "title": "[FIX] search results position on sidebar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7882", + "title": "[FIX] hyperlink style on sidebar footer", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7883", + "title": "[FIX] popover position on mobile", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7885", + "title": "[FIX] message actions over unread bar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7886", + "title": "[FIX] livechat icon", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7887", + "title": "[FIX] Makes text action menu width based on content size", + "userLogin": "gdelavald", + "milestone": "0.59.0-rc.1", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7888", + "title": "[FIX] sidebar buttons and badge paddings", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + } + ] + }, + "0.59.0-rc.2": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7912", + "title": "[FIX] Fix google play logo on repo README", + "userLogin": "luizbills", + "milestone": "0.59.0-rc.2", + "contributors": [ + "luizbills", + "web-flow" + ] + }, + { + "pr": "7904", + "title": "[FIX] Fix livechat toggle UI issue", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7895", + "title": "[FIX] Remove break change in Realtime API", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7894", + "title": "Hide flex-tab close button", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7893", + "title": "[FIX] Window exception when parsing Markdown on server", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.2", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.3": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7985", + "title": "[FIX] Text area buttons and layout on mobile ", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.3", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "7927", + "title": "[FIX] Double scroll on 'keyboard shortcuts' menu in sidepanel", + "userLogin": "aditya19496", + "milestone": "0.59.0-rc.3", + "contributors": [ + "aditya19496" + ] + }, + { + "pr": "7944", + "title": "[FIX] Broken embedded view layout", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7986", + "title": "[FIX] Textarea on firefox", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.3", + "contributors": [ + "MartinSchoeler", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "7984", + "title": "[FIX] Chat box no longer auto-focuses when typing", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7971", + "title": "[FIX] Add padding on messages to allow space to the action buttons", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7970", + "title": "[FIX] Small alignment fixes", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7965", + "title": "[FIX] Markdown being rendered in code tags", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7963", + "title": "[FIX] Fix the status on the members list", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7960", + "title": "[FIX] status and active room colors on sidebar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7954", + "title": "[FIX] OTR buttons padding", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7953", + "title": "[FIX] username ellipsis on firefox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7948", + "title": "[FIX] Document README.md. Drupal repo out of date", + "userLogin": "Lawri-van-Buel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "Lawri-van-Buel" + ] + }, + { + "pr": "7945", + "title": "[FIX] Fix placeholders in account profile", + "userLogin": "josiasds", + "milestone": "0.59.0-rc.3", + "contributors": [ + "josiasds" + ] + }, + { + "pr": "7943", + "title": "[FIX] Broken emoji picker on firefox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7942", + "title": "[FIX] Create channel button on Firefox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7941", + "title": "Update BlackDuck URL", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "7909", + "title": "[DOCS] Add native mobile app links into README and update button images", + "userLogin": "rafaelks", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "7712", + "title": "[FIX] Show leader on first load", + "userLogin": "danischreiber", + "milestone": "0.59.0-rc.3", + "contributors": [ + "danischreiber", + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.4": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "7988", + "title": "[FIX] Vertical menu on flex-tab", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "8048", + "title": "[FIX] Invisible leader bar on hover", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.4", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8046", + "title": "[FIX] Prevent autotranslate tokens race condition", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8039", + "title": "[FIX] copy to clipboard and update clipboard.js library", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8019", + "title": "[FIX] message-box autogrow", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8018", + "title": "[FIX] search results height", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb", + "gdelavald" + ] + }, + { + "pr": "8017", + "title": "[FIX] room icon on header", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8014", + "title": "[FIX] Hide scrollbar on login page if not necessary", + "userLogin": "alexbrazier", + "milestone": "0.59.0-rc.4", + "contributors": [ + "alexbrazier" + ] + }, + { + "pr": "8001", + "title": "[FIX] Error when translating message", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.4", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7998", + "title": "[FIX] Recent emojis not updated when adding via text", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.4", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7989", + "title": "[FIX][PL] Polish translation", + "userLogin": "Rzeszow", + "milestone": "0.59.0-rc.4", + "contributors": [ + "Rzeszow", + "web-flow" + ] + }, + { + "pr": "7754", + "title": "[FIX] Fix email on mention", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.4", + "contributors": [ + "MartinSchoeler" + ] + } + ] + }, + "0.59.0-rc.5": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8112", + "title": "[FIX] RTL", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.5", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8101", + "title": "[FIX] Dynamic popover", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.5", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8122", + "title": "[FIX] Settings description not showing", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.5", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8099", + "title": "[FIX] Fix setting user avatar on LDAP login", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.5", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8059", + "title": "[FIX] Not sending email to mentioned users with unchanged preference", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.5", + "contributors": [ + "MartinSchoeler", + "sampaiodiego" + ] + }, + { + "pr": "8054", + "title": "Remove unnecessary returns in cors common", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0-rc.5", + "contributors": [ + "Kiran-Rao", + "web-flow" + ] + }, + { + "pr": "8047", + "title": "[FIX] Scroll on messagebox", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.5", + "contributors": [ + "MartinSchoeler" + ] + } + ] + }, + "0.59.0-rc.6": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8172", + "title": "[FIX] Allow unknown file types if no allowed whitelist has been set (#7074)", + "userLogin": "TriPhoenix", + "milestone": "0.59.0-rc.6", + "contributors": [ + "TriPhoenix" + ] + }, + { + "pr": "8167", + "title": "[FIX] Issue #8166 where empty analytics setting breaks to load Piwik script", + "userLogin": "ruKurz", + "milestone": "0.59.0-rc.6", + "contributors": [ + "ruKurz" + ] + }, + { + "pr": "8154", + "title": "[FIX] Sidebar and RTL alignments", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.6", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8147", + "title": "[FIX] \"*.members\" rest api being useless and only returning usernames", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.6", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8146", + "title": "[FIX] Fix iframe login API response (issue #8145)", + "userLogin": "astax-t", + "milestone": "0.59.0-rc.6", + "contributors": [ + "astax-t" + ] + }, + { + "pr": "8159", + "title": "[FIX] Text area lost text when page reloads", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.6", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8144", + "title": "[FIX] Fix new room sound being played too much", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.6", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8094", + "title": "[FIX] Add admin audio preferences translations", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.6", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8073", + "title": "[NEW] Upgrade to meteor 1.5.2", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.6", + "contributors": [ + "engelgabriel" + ] + } + ] + }, + "0.59.0-rc.7": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8213", + "title": "[FIX] Leave and hide buttons was removed", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.7", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8211", + "title": "[FIX] Incorrect URL for login terms when using prefix", + "userLogin": "Darkneon", + "milestone": "0.59.0-rc.7", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "8210", + "title": "[FIX] User avatar in DM list.", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.7", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8197", + "title": "npm deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.7", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8194", + "title": "Fix more rtl issues", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.7", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8190", + "title": "[FIX] Scrollbar not using new style", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.7", + "contributors": [ + "ggazzo", + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.8": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8253", + "title": "readme-file: fix broken link", + "userLogin": "vcapretz", + "milestone": "0.59.0-rc.8", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8257", + "title": "[FIX] sidenav colors, hide and leave, create channel on safari", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.8", + "contributors": [ + "ggazzo", + "karlprieb", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8262", + "title": "[FIX] make sidebar item animation fast", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.8", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8261", + "title": "[FIX] RTL on reply", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.8", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8260", + "title": "[NEW] Enable read only channel creation", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.8", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8259", + "title": "[FIX] clipboard and permalink on new popover", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.8", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8252", + "title": "[FIX] sidenav mentions on hover", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.8", + "contributors": [ + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "8244", + "title": "Disable perfect scrollbar", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.8", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8243", + "title": "Fix `leave and hide` click, color and position", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.8", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8241", + "title": "[FIX] Api groups.files is always returning empty", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.8", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8216", + "title": "[FIX] Case insensitive SAML email check", + "userLogin": "arminfelder", + "milestone": "0.59.0-rc.8", + "contributors": [ + "arminfelder" + ] + } + ] + }, + "0.59.0-rc.9": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8310", + "title": "[FIX] Execute meteor reset on TRAVIS_TAG builds", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8307", + "title": "[FIX] Call buttons with wrong margin on RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.9", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8304", + "title": "[NEW] Add RD Station integration to livechat", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.9", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8300", + "title": "[FIX] Emoji Picker hidden for reactions in RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.9", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8299", + "title": " [FIX] Amin menu not showing all items & File list breaking line", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.9", + "contributors": [ + "ggazzo", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8298", + "title": "[FIX] TypeError: Cannot read property 't' of undefined", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.9", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8296", + "title": "[FIX] Wrong file name when upload to AWS S3", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.9", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8295", + "title": "[FIX] Check attachments is defined before accessing first element", + "userLogin": "Darkneon", + "milestone": "0.59.0-rc.9", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "8286", + "title": "[FIX] Missing placeholder translations", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8282", + "title": "[FIX] fix color on unread messages", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.9", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8278", + "title": "[FIX] \"Cancel button\" on modal in RTL in Firefox 55", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8273", + "title": "Deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8271", + "title": "[FIX] Attachment icons alignment in LTR and RTL", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8270", + "title": "[FIX] [i18n] My Profile & README.md links", + "userLogin": "Rzeszow", + "milestone": "0.59.0-rc.9", + "contributors": [ + "Rzeszow", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8269", + "title": "[FIX] some placeholder and phrase traslation fix", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8266", + "title": "[FIX] \"Channel Setting\" buttons alignment in RTL", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8237", + "title": "[FIX] Removing pipe and commas from custom emojis (#8168)", + "userLogin": "matheusml", + "milestone": "0.59.0-rc.9", + "contributors": [ + "matheusml" + ] + } + ] + }, + "0.59.0-rc.10": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8355", + "title": "Update meteor to 1.5.2.2-rc.0", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.10", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8314", + "title": "[FIX] After deleting the room, cache is not synchronizing", + "userLogin": "szluohua", + "milestone": "0.59.0-rc.10", + "contributors": [ + "szluohua" + ] + }, + { + "pr": "8334", + "title": "[FIX] Remove sidebar header on admin embedded version", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8331", + "title": "[FIX-RC] Mobile file upload not working", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8317", + "title": "[FIX] Email Subjects not being sent", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.10", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "8315", + "title": "[FIX] Put delete action on another popover group", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8316", + "title": "[FIX] Mention unread indicator was removed", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.10", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.11": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8375", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8372", + "title": "[FIX] Various LDAP issues & Missing pagination", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.11", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8364", + "title": "Update Meteor to 1.5.2.2", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8363", + "title": "Sync translations from LingoHub", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8358", + "title": "[FIX] remove accountBox from admin menu", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8361", + "title": "[NEW] Unify unread and mentions badge", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8362", + "title": "[NEW] make sidebar item width 100%", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8360", + "title": "[NEW] Smaller accountBox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8357", + "title": "[FIX] Missing i18n translations", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.11", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8345", + "title": "Remove field `lastActivity` from subscription data", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.11", + "contributors": [ + "ggazzo" + ] + } + ] + }, + "0.59.0-rc.12": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8416", + "title": "Fix: Account menu position on RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.12", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8417", + "title": "Fix: Missing LDAP option to show internal logs", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8414", + "title": "Fix: Missing LDAP reconnect setting", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8397", + "title": "[FIX] Sidebar item menu position in RTL", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.12", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8386", + "title": "[FIX] disabled katex tooltip on messageBox", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.12", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8394", + "title": "Add i18n Title to snippet messages", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.12", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8398", + "title": "Fix: Missing settings to configure LDAP size and page limits", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.13": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8459", + "title": "[NEW] Setting to disable MarkDown and enable AutoLinker", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8457", + "title": "[FIX] LDAP memory issues when pagination is not available", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8451", + "title": "Improve markdown parser code", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.14": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8515", + "title": "Change artifact path", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8463", + "title": "Color variables migration", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.14", + "contributors": [ + "ggazzo", + "rodrigok", + "karlprieb" + ] + }, + { + "pr": "8516", + "title": "Fix: Change password not working in new UI", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8514", + "title": "[FIX] Uncessary route reload break some routes", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8491", + "title": "[FIX] Invalid Code message for password protected channel", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8489", + "title": "[FIX] Wrong message when reseting password and 2FA is enabled", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8490", + "title": "Enable AutoLinker back", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.15": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8518", + "title": "Fix artifact path", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8520", + "title": "Fix high CPU load when sending messages on large rooms (regression)", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0-rc.16": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8527", + "title": "[FIX] Do not send joinCode field to clients", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.59.0-rc.17": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8529", + "title": "Improve room sync speed", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.0": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8420", + "title": "Merge 0.58.4 to master", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8335", + "title": "0.58.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.59.1": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8543", + "title": "[FIX] Color reset when default value editor is different", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "8547", + "title": "[FIX] Wrong colors after migration 103", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8541", + "title": "[FIX] LDAP login error regression at 0.59.0", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8544", + "title": "[FIX] Migration 103 wrong converting primrary colors", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.2": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8637", + "title": "[FIX] Missing scroll at create channel page", + "userLogin": "karlprieb", + "milestone": "0.59.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8634", + "title": "[FIX] Message popup menu on mobile/cordova", + "userLogin": "karlprieb", + "milestone": "0.59.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8635", + "title": "[FIX] API channel/group.members not sorting", + "userLogin": "rodrigok", + "milestone": "0.59.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8613", + "title": "[FIX] LDAP not merging existent users && Wrong id link generation", + "userLogin": "rodrigok", + "milestone": "0.59.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8551", + "title": "[FIX] encode filename in url to prevent links breaking", + "userLogin": "joesitton", + "milestone": "0.59.2", + "contributors": [ + "joesitton", + "web-flow" + ] + }, + { + "pr": "8577", + "title": "[FIX] Fix guest pool inquiry taking", + "userLogin": "sampaiodiego", + "milestone": "0.59.2", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.59.3": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8593", + "title": "[FIX] AmazonS3: Quote file.name for ContentDisposition for files with commas", + "userLogin": "xenithorb", + "milestone": "0.59.3", + "contributors": [ + "xenithorb" + ] + }, + { + "pr": "8434", + "title": "removing a duplicate line", + "userLogin": "vikaskedia", + "milestone": "0.59.3", + "contributors": [ + "vikaskedia", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8645", + "title": "[FIX] Fix e-mail message forward", + "userLogin": "sampaiodiego", + "milestone": "0.59.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "8648", + "title": "[FIX] Audio message icon", + "userLogin": "karlprieb", + "milestone": "0.59.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8431", + "title": "[FIX] Highlighted color height issue", + "userLogin": "cyclops24", + "milestone": "0.59.3", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8655", + "title": "[FIX] Update pt-BR translation", + "userLogin": "rodorgas", + "milestone": "0.59.3", + "contributors": [ + "rodorgas" + ] + }, + { + "pr": "8679", + "title": "[FIX] Fix typos", + "userLogin": "sampaiodiego", + "milestone": "0.59.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "8653", + "title": "install grpc package manually to fix snap armhf build", + "userLogin": "geekgonecrazy", + "milestone": "0.59.3", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8691", + "title": "[FIX] LDAP not respecting UTF8 characters & Sync Interval not working", + "userLogin": "rodrigok", + "milestone": "0.59.3", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.59.4": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8967", + "title": "Release/0.59.4", + "userLogin": "geekgonecrazy", + "contributors": [ + "cpitman", + "geekgonecrazy", + "karlprieb", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "8685", + "title": "Add CircleCI", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8753", + "title": "[FIX] Channel settings buttons", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + } + ] + }, + "0.59.5": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8972", + "title": "Fix CircleCI deploy filter", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.59.6": { + "node_version": "4.8.4", + "npm_version": "4.6.1", + "pull_requests": [ + { + "pr": "8973", + "title": "Fix tag build", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.60.0-rc.0": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9084", + "title": "Fix tag build", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7285", + "title": "[NEW] Allow user's default preferences configuration", + "userLogin": "goiaba", + "milestone": "0.60.0", + "contributors": [ + "goiaba", + "web-flow" + ] + }, + { + "pr": "8925", + "title": "[FIX] Can't react on Read Only rooms even when enabled", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9068", + "title": "Turn off prettyJson if the node environment isn't development", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9049", + "title": "Fix api regression (exception when deleting user)", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8654", + "title": "[FIX] CAS does not share secrets when operating multiple server instances", + "userLogin": "AmShaegar13", + "milestone": "0.60.0", + "contributors": [ + "AmShaegar13" + ] + }, + { + "pr": "8937", + "title": "[FIX] Snippetted messages not working", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8915", + "title": "[NEW] Add \"Favorites\" and \"Mark as read\" options to the room list", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8807", + "title": "[NEW] Facebook livechat integration", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego", + "ggazzo", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9022", + "title": "[FIX] Added afterUserCreated trigger after first CAS login", + "userLogin": "AmShaegar13", + "milestone": "0.60.0", + "contributors": [ + "AmShaegar13" + ] + }, + { + "pr": "8902", + "title": "[NEW] Added support for Dataporten's userid-feide scope", + "userLogin": "torgeirl", + "milestone": "0.60.0", + "contributors": [ + "torgeirl", + "web-flow" + ] + }, + { + "pr": "8828", + "title": "[FIX] Notification is not sent when a video conference start", + "userLogin": "seainside75", + "milestone": "0.60.0", + "contributors": [ + "stefanoverducci", + "deepseainside75" + ] + }, + { + "pr": "8868", + "title": "[FIX] long filename overlaps cancel button in progress bar", + "userLogin": "joesitton", + "milestone": "0.60.0", + "contributors": [ + "joesitton", + "web-flow" + ] + }, + { + "pr": "8924", + "title": "[NEW] Describe file uploads when notifying by email", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9012", + "title": "[FIX] Changed oembedUrlWidget to prefer og:image and twitter:image over msapplication-TileImage", + "userLogin": "wferris722", + "milestone": "0.60.0", + "contributors": [ + "wferris722", + "web-flow" + ] + }, + { + "pr": "9046", + "title": "[FIX] Update insecure moment.js dependency", + "userLogin": "robbyoconnor", + "milestone": "0.60.0", + "contributors": [ + "robbyoconnor" + ] + }, + { + "pr": "8149", + "title": "[NEW] Feature/livechat hide email", + "userLogin": "icosamuel", + "milestone": "0.60.0", + "contributors": [ + "sarbasamuel", + "icosamuel", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "7999", + "title": "[NEW] Sender's name in email notifications.", + "userLogin": "pkgodara", + "milestone": "0.60.0", + "contributors": [ + "pkgodara", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7922", + "title": "Use real names for user and room in emails", + "userLogin": "danischreiber", + "milestone": "0.60.0", + "contributors": [ + "danischreiber", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9034", + "title": "[FIX] Custom OAuth: Not able to set different token place for routes", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9044", + "title": "[FIX] Can't use OAuth login against a Rocket.Chat OAuth server", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "graywolf336", + "web-flow" + ] + }, + { + "pr": "9042", + "title": "[FIX] Notification sound is not disabling when busy", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8739", + "title": "[NEW] Add \"real name change\" setting", + "userLogin": "AmShaegar13", + "milestone": "0.60.0", + "contributors": [ + "AmShaegar13" + ] + }, + { + "pr": "8433", + "title": "[NEW] Use enter separator rather than comma in highlight preferences + Auto refresh after change highlighted words", + "userLogin": "cyclops24", + "milestone": "0.60.0", + "contributors": [ + "cyclops24", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "7641", + "title": "[NEW] Adds admin option to globally set mobile devices to always be notified regardless of presence status.", + "userLogin": "stalley", + "milestone": "0.60.0", + "contributors": [ + "stalley", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9024", + "title": "[FIX] Use encodeURI in AmazonS3 contentDisposition file.name to prevent fail", + "userLogin": "paulovitin", + "milestone": "0.60.0", + "contributors": [ + "paulovitin", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9029", + "title": "[FIX] snap install by setting grpc package used by google/vision to 1.6.6", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "8142", + "title": "[MOVE] Move mentions files to client/server", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8947", + "title": "[NEW] Add new API endpoints", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok", + "graywolf336", + "web-flow" + ] + }, + { + "pr": "8671", + "title": "[FIX] Enable CORS for Restivus", + "userLogin": "mrsimpson", + "milestone": "0.60.0", + "contributors": [ + "mrsimpson", + "engelgabriel", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8966", + "title": "[FIX] Importers failing when usernames exists but cases don't match and improve the importer framework's performance", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336", + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9023", + "title": "[FIX] Error when saving integration with symbol as only trigger", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8006", + "title": "[FIX] Sync of non existent field throws exception", + "userLogin": "goiaba", + "milestone": "0.60.0", + "contributors": [ + "goiaba", + "web-flow" + ] + }, + { + "pr": "9018", + "title": "Update multiple-instance-status package", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9007", + "title": "Use redhat official image with openshift", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "8107", + "title": "[FIX] Autoupdate of CSS does not work when using a prefix", + "userLogin": "Darkneon", + "milestone": "0.60.0", + "contributors": [ + "Darkneon", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8656", + "title": "[FIX] Contextual errors for this and RegExp declarations in IRC module", + "userLogin": "Pharserror", + "milestone": "0.60.0", + "contributors": [ + "Pharserror", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8029", + "title": "[NEW] Option to enable/disable auto away and configure timer", + "userLogin": "armand1m", + "milestone": "0.60.0", + "contributors": [ + "armand1m", + null, + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9013", + "title": "[FIX] Wrong room counter name", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8975", + "title": "Added d2c.io to deployment", + "userLogin": "mastappl", + "contributors": [ + "mastappl", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "8882", + "title": "[NEW] New Modal component", + "userLogin": "ggazzo", + "milestone": "0.60.0", + "contributors": [ + "ggazzo", + "web-flow", + "karlprieb" + ] + }, + { + "pr": "8932", + "title": "[FIX] Message-box autogrow flick", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9009", + "title": "[NEW] Improve room types API and usages", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "mrsimpson", + "graywolf336" + ] + }, + { + "pr": "8812", + "title": "[FIX] Don't strip trailing slash on autolinker urls", + "userLogin": "jwilkins", + "milestone": "0.60.0", + "contributors": [ + "jwilkins", + "web-flow" + ] + }, + { + "pr": "8831", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8866", + "title": "[NEW] Room counter sidebar preference", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8883", + "title": "[FIX] Change the unread messages style", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8884", + "title": "[FIX] Missing sidebar footer padding", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8907", + "title": "[FIX] Long room announcement cut off", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8917", + "title": "[FIX] DM email notifications always being sent regardless of account setting", + "userLogin": "ashward", + "milestone": "0.60.0", + "contributors": [ + null, + "ashward", + "web-flow" + ] + }, + { + "pr": "8938", + "title": "[FIX] Typo Fix", + "userLogin": "seangeleno", + "milestone": "0.60.0", + "contributors": [ + "seangeleno", + "web-flow" + ] + }, + { + "pr": "8948", + "title": "[FIX] Katex markdown link changed", + "userLogin": "mritunjaygoutam12", + "milestone": "0.60.0", + "contributors": [ + "mritunjaygoutam12", + "web-flow" + ] + }, + { + "pr": "8979", + "title": "[NEW] Save room's last message", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego", + "karlprieb", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9000", + "title": "[FIX] if ogImage exists use it over image in oembedUrlWidget", + "userLogin": "satyapramodh", + "milestone": "0.60.0", + "contributors": [ + "satyapramodh" + ] + }, + { + "pr": "8060", + "title": "[NEW] Token Controlled Access channels", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "lindoelio", + "sampaiodiego", + "web-flow", + "karlprieb" + ] + }, + { + "pr": "8889", + "title": "[FIX] Cannot edit or delete custom sounds", + "userLogin": "ccfang", + "milestone": "0.60.0", + "contributors": [ + "ccfang", + "web-flow" + ] + }, + { + "pr": "8928", + "title": "[FIX] Change old 'rocketbot' username to 'InternalHubot_Username' setting", + "userLogin": "ramrami", + "milestone": "0.60.0", + "contributors": [ + "ramrami", + "web-flow" + ] + }, + { + "pr": "8985", + "title": "[FIX] Link for channels are not rendering correctly", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8968", + "title": "[FIX] Xenforo [BD]API for 'user.user_id; instead of 'id'", + "userLogin": "wesnspace", + "milestone": "0.60.0", + "contributors": [ + "wesnspace", + "web-flow" + ] + }, + { + "pr": "8994", + "title": "[FIX] flextab height on smaller screens", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8931", + "title": "[FIX] Check for mention-all permission in room scope", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8905", + "title": "[NEW] Send category and title fields to iOS push notification", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8981", + "title": "Fix snap download url", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "8753", + "title": "[FIX] Channel settings buttons", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8906", + "title": "Add a few dots in readme.md", + "userLogin": "dusta", + "contributors": [ + "dusta", + "web-flow" + ] + }, + { + "pr": "8872", + "title": "Changed wording for \"Maximum Allowed Message Size\"", + "userLogin": "HammyHavoc", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "8822", + "title": "[FIX] fix emoji package path so they show up correctly in browser", + "userLogin": "ryoshimizu", + "milestone": "0.60.0", + "contributors": [ + "ryoshimizu" + ] + }, + { + "pr": "8857", + "title": "[NEW] code to get the updated messages", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8862", + "title": "Fix Docker image build", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8531", + "title": "[NEW] Rest API endpoints to list, get, and run commands", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8830", + "title": "[FIX] Set correct Twitter link", + "userLogin": "jotafeldmann", + "contributors": [ + "jotafeldmann", + "web-flow" + ] + }, + { + "pr": "8829", + "title": "Fix link to .asc file on S3", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8820", + "title": "Bump version to 0.60.0-develop", + "userLogin": "geekgonecrazy", + "contributors": [ + "rodrigok", + "karlprieb", + "gdelavald", + "ggazzo", + "engelgabriel" + ] + }, + { + "pr": "8819", + "title": "Update path for s3 redirect in circle ci", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "8810", + "title": "[FIX] User email settings on DM", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8721", + "title": "[FIX] i18n'd Resend_verification_mail, username_initials, upload avatar", + "userLogin": "arungalva", + "milestone": "0.60.0", + "contributors": [ + "arungalva", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8716", + "title": "[FIX] Username clipping on firefox", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8742", + "title": "Remove chatops package", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8743", + "title": "Removed tmeasday:crypto-md5", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8802", + "title": "Update meteor package to 1.8.1", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8795", + "title": "[FIX] Improved grammar and made it clearer to the user", + "userLogin": "HammyHavoc", + "milestone": "0.60.0", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "8705", + "title": "Fix typo", + "userLogin": "rmetzler", + "milestone": "0.60.0", + "contributors": [ + "rmetzler", + "geekgonecrazy", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "8718", + "title": "[FIX] Show real name of current user at top of side nav if setting enabled", + "userLogin": "alexbrazier", + "milestone": "0.60.0", + "contributors": [ + "alexbrazier", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8441", + "title": "[FIX] Range Slider Value label has bug in RTL", + "userLogin": "cyclops24", + "milestone": "0.60.0", + "contributors": [ + "cyclops24", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8413", + "title": "[Fix] Store Outgoing Integration Result as String in Mongo", + "userLogin": "cpitman", + "milestone": "0.60.0", + "contributors": [ + "cpitman", + "graywolf336", + "web-flow" + ] + }, + { + "pr": "8708", + "title": "[FIX] Add historic chats icon in Livechat", + "userLogin": "mrsimpson", + "milestone": "0.60.0", + "contributors": [ + "mrsimpson", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8717", + "title": "[FIX] Sort direct messages by full name if show real names setting enabled", + "userLogin": "alexbrazier", + "milestone": "0.60.0", + "contributors": [ + "alexbrazier", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8793", + "title": "Update DEMO to OPEN links", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8796", + "title": "[FIX] Improving consistency of UX", + "userLogin": "HammyHavoc", + "milestone": "0.60.0", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "8787", + "title": "[FIX] fixed some typos", + "userLogin": "TheReal1604", + "milestone": "0.60.0", + "contributors": [ + "TheReal1604", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "8715", + "title": "[NEW] Upgrade Meteor to 1.6", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "karlprieb", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8685", + "title": "Add CircleCI", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8750", + "title": "Fix Travis CI build", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8719", + "title": "Updated comments.", + "userLogin": "jasonjyu", + "contributors": [ + "jasonjyu", + "web-flow" + ] + }, + { + "pr": "8434", + "title": "removing a duplicate line", + "userLogin": "vikaskedia", + "milestone": "0.59.3", + "contributors": [ + "vikaskedia", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8645", + "title": "[FIX] Fix e-mail message forward", + "userLogin": "sampaiodiego", + "milestone": "0.59.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "8648", + "title": "[FIX] Audio message icon", + "userLogin": "karlprieb", + "milestone": "0.59.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8431", + "title": "[FIX] Highlighted color height issue", + "userLogin": "cyclops24", + "milestone": "0.59.3", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8593", + "title": "[FIX] AmazonS3: Quote file.name for ContentDisposition for files with commas", + "userLogin": "xenithorb", + "milestone": "0.59.3", + "contributors": [ + "xenithorb" + ] + }, + { + "pr": "8655", + "title": "[FIX] Update pt-BR translation", + "userLogin": "rodorgas", + "milestone": "0.59.3", + "contributors": [ + "rodorgas" + ] + }, + { + "pr": "8679", + "title": "[FIX] Fix typos", + "userLogin": "sampaiodiego", + "milestone": "0.59.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "8653", + "title": "install grpc package manually to fix snap armhf build", + "userLogin": "geekgonecrazy", + "milestone": "0.59.3", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8691", + "title": "[FIX] LDAP not respecting UTF8 characters & Sync Interval not working", + "userLogin": "rodrigok", + "milestone": "0.59.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8637", + "title": "[FIX] Missing scroll at create channel page", + "userLogin": "karlprieb", + "milestone": "0.59.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8634", + "title": "[FIX] Message popup menu on mobile/cordova", + "userLogin": "karlprieb", + "milestone": "0.59.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8635", + "title": "[FIX] API channel/group.members not sorting", + "userLogin": "rodrigok", + "milestone": "0.59.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8613", + "title": "[FIX] LDAP not merging existent users && Wrong id link generation", + "userLogin": "rodrigok", + "milestone": "0.59.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8551", + "title": "[FIX] encode filename in url to prevent links breaking", + "userLogin": "joesitton", + "milestone": "0.59.2", + "contributors": [ + "joesitton", + "web-flow" + ] + }, + { + "pr": "8577", + "title": "[FIX] Fix guest pool inquiry taking", + "userLogin": "sampaiodiego", + "milestone": "0.59.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8589", + "title": "Fix community links in readme", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "8588", + "title": "[FIX] Changed all rocket.chat/docs/ to docs.rocket.chat/", + "userLogin": "RekkyRek", + "contributors": [ + "RekkyRek", + "web-flow" + ] + }, + { + "pr": "8543", + "title": "[FIX] Color reset when default value editor is different", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "8547", + "title": "[FIX] Wrong colors after migration 103", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8541", + "title": "[FIX] LDAP login error regression at 0.59.0", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8544", + "title": "[FIX] Migration 103 wrong converting primrary colors", + "userLogin": "rodrigok", + "milestone": "0.59.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8529", + "title": "Improve room sync speed", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8527", + "title": "[FIX] Do not send joinCode field to clients", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8520", + "title": "Fix high CPU load when sending messages on large rooms (regression)", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8515", + "title": "Change artifact path", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8463", + "title": "Color variables migration", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.14", + "contributors": [ + "ggazzo", + "rodrigok", + "karlprieb" + ] + }, + { + "pr": "8516", + "title": "Fix: Change password not working in new UI", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8514", + "title": "[FIX] Uncessary route reload break some routes", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8491", + "title": "[FIX] Invalid Code message for password protected channel", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8489", + "title": "[FIX] Wrong message when reseting password and 2FA is enabled", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8490", + "title": "Enable AutoLinker back", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.14", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8459", + "title": "[NEW] Setting to disable MarkDown and enable AutoLinker", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8457", + "title": "[FIX] LDAP memory issues when pagination is not available", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8451", + "title": "Improve markdown parser code", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.13", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8066", + "title": "[NEW] Add settings for allow user direct messages to yourself", + "userLogin": "lindoelio", + "milestone": "0.60.0", + "contributors": [ + "lindoelio" + ] + }, + { + "pr": "8108", + "title": "[NEW] Add sweet alert to video call tab", + "userLogin": "MartinSchoeler", + "milestone": "0.60.0", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8143", + "title": "[NEW] Displays QR code for manually entering when enabling 2fa", + "userLogin": "marceloschmidt", + "milestone": "0.60.0", + "contributors": [ + "marceloschmidt" + ] + }, + { + "pr": "8077", + "title": "[MOVE] Move favico to client folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8078", + "title": "[MOVE] Move files from emojione to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8084", + "title": "[MOVE] Move files from slashcommands-unarchive to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8132", + "title": "[MOVE] Move slashcommands-open to client folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8135", + "title": "[MOVE] Move kick command to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8136", + "title": "[MOVE] Move join command to client/server folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8137", + "title": "[MOVE] Move inviteall command to client/server folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8138", + "title": "[MOVE] Move invite command to client/server folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8139", + "title": "[MOVE] Move create command to client/server folder", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8140", + "title": "[MOVE] Move archiveroom command to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8141", + "title": "[MOVE] Move slackbridge to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8150", + "title": "[MOVE] Move logger files to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8152", + "title": "[MOVE] Move timesync files to client/server folders", + "userLogin": "vcapretz", + "milestone": "0.60.0", + "contributors": [ + "vcapretz" + ] + }, + { + "pr": "8416", + "title": "Fix: Account menu position on RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.12", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8417", + "title": "Fix: Missing LDAP option to show internal logs", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8414", + "title": "Fix: Missing LDAP reconnect setting", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8389", + "title": "[FIX] Add needed dependency for snaps", + "userLogin": "geekgonecrazy", + "milestone": "0.59.0-rc.12", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "8390", + "title": "[FIX] Slack import failing and not being able to be restarted", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8397", + "title": "[FIX] Sidebar item menu position in RTL", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.12", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8386", + "title": "[FIX] disabled katex tooltip on messageBox", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.12", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8394", + "title": "Add i18n Title to snippet messages", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.12", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "8408", + "title": "[FIX] Duplicate code in rest api letting in a few bugs with the rest api", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.12", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8398", + "title": "Fix: Missing settings to configure LDAP size and page limits", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.12", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8375", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8372", + "title": "[FIX] Various LDAP issues & Missing pagination", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.11", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8364", + "title": "Update Meteor to 1.5.2.2", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8363", + "title": "Sync translations from LingoHub", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8358", + "title": "[FIX] remove accountBox from admin menu", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.11", + "contributors": [ + "engelgabriel", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8361", + "title": "[NEW] Unify unread and mentions badge", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8362", + "title": "[NEW] make sidebar item width 100%", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8360", + "title": "[NEW] Smaller accountBox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.11", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8357", + "title": "[FIX] Missing i18n translations", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.11", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8345", + "title": "Remove field `lastActivity` from subscription data", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.11", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8355", + "title": "Update meteor to 1.5.2.2-rc.0", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.10", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8314", + "title": "[FIX] After deleting the room, cache is not synchronizing", + "userLogin": "szluohua", + "milestone": "0.59.0-rc.10", + "contributors": [ + "szluohua" + ] + }, + { + "pr": "8334", + "title": "[FIX] Remove sidebar header on admin embedded version", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8331", + "title": "[FIX-RC] Mobile file upload not working", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8317", + "title": "[FIX] Email Subjects not being sent", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.10", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "8315", + "title": "[FIX] Put delete action on another popover group", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.10", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8316", + "title": "[FIX] Mention unread indicator was removed", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.10", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8304", + "title": "[NEW] Add RD Station integration to livechat", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.9", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8310", + "title": "[FIX] Execute meteor reset on TRAVIS_TAG builds", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8296", + "title": "[FIX] Wrong file name when upload to AWS S3", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.9", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8298", + "title": "[FIX] TypeError: Cannot read property 't' of undefined", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.9", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8295", + "title": "[FIX] Check attachments is defined before accessing first element", + "userLogin": "Darkneon", + "milestone": "0.59.0-rc.9", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "8299", + "title": " [FIX] Amin menu not showing all items & File list breaking line", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.9", + "contributors": [ + "ggazzo", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8307", + "title": "[FIX] Call buttons with wrong margin on RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.9", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8300", + "title": "[FIX] Emoji Picker hidden for reactions in RTL", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.9", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8273", + "title": "Deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8282", + "title": "[FIX] fix color on unread messages", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.9", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8286", + "title": "[FIX] Missing placeholder translations", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.9", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8278", + "title": "[FIX] \"Cancel button\" on modal in RTL in Firefox 55", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8271", + "title": "[FIX] Attachment icons alignment in LTR and RTL", + "userLogin": "cyclops24", + "milestone": "0.59.0-rc.9", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "8270", + "title": "[FIX] [i18n] My Profile & README.md links", + "userLogin": "Rzeszow", + "milestone": "0.59.0-rc.9", + "contributors": [ + "Rzeszow", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8211", + "title": "[FIX] Incorrect URL for login terms when using prefix", + "userLogin": "Darkneon", + "milestone": "0.59.0-rc.7", + "contributors": [ + "Darkneon" + ] + }, + { + "pr": "8194", + "title": "Fix more rtl issues", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.7", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8190", + "title": "[FIX] Scrollbar not using new style", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.7", + "contributors": [ + "ggazzo", + "rodrigok" + ] + }, + { + "pr": "8210", + "title": "[FIX] User avatar in DM list.", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.7", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8197", + "title": "npm deps update", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.7", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8146", + "title": "[FIX] Fix iframe login API response (issue #8145)", + "userLogin": "astax-t", + "milestone": "0.59.0-rc.6", + "contributors": [ + "astax-t" + ] + }, + { + "pr": "8167", + "title": "[FIX] Issue #8166 where empty analytics setting breaks to load Piwik script", + "userLogin": "ruKurz", + "milestone": "0.59.0-rc.6", + "contributors": [ + "ruKurz" + ] + }, + { + "pr": "8154", + "title": "[FIX] Sidebar and RTL alignments", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.6", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8147", + "title": "[FIX] \"*.members\" rest api being useless and only returning usernames", + "userLogin": "graywolf336", + "milestone": "0.59.0-rc.6", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "8159", + "title": "[FIX] Text area lost text when page reloads", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.6", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8094", + "title": "[FIX] Add admin audio preferences translations", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.6", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8073", + "title": "[NEW] Upgrade to meteor 1.5.2", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.6", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "8112", + "title": "[FIX] RTL", + "userLogin": "ggazzo", + "milestone": "0.59.0-rc.5", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "8122", + "title": "[FIX] Settings description not showing", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.5", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8059", + "title": "[FIX] Not sending email to mentioned users with unchanged preference", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.5", + "contributors": [ + "MartinSchoeler", + "sampaiodiego" + ] + }, + { + "pr": "8101", + "title": "[FIX] Dynamic popover", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.5", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8099", + "title": "[FIX] Fix setting user avatar on LDAP login", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.5", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8054", + "title": "Remove unnecessary returns in cors common", + "userLogin": "Kiran-Rao", + "milestone": "0.59.0-rc.5", + "contributors": [ + "Kiran-Rao", + "web-flow" + ] + }, + { + "pr": "8047", + "title": "[FIX] Scroll on messagebox", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.5", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8048", + "title": "[FIX] Invisible leader bar on hover", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.4", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7754", + "title": "[FIX] Fix email on mention", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.4", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "8046", + "title": "[FIX] Prevent autotranslate tokens race condition", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7988", + "title": "[FIX] Vertical menu on flex-tab", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "8019", + "title": "[FIX] message-box autogrow", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8039", + "title": "[FIX] copy to clipboard and update clipboard.js library", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "8037", + "title": "[NEW] Add yunohost.org installation method to Readme.md", + "userLogin": "selamanse", + "contributors": [ + "selamanse", + "web-flow" + ] + }, + { + "pr": "8036", + "title": "Adding: How to Install in WeDeploy", + "userLogin": "thompsonemerson", + "contributors": [ + "thompsonemerson", + "web-flow" + ] + }, + { + "pr": "7998", + "title": "[FIX] Recent emojis not updated when adding via text", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.4", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7989", + "title": "[FIX][PL] Polish translation", + "userLogin": "Rzeszow", + "milestone": "0.59.0-rc.4", + "contributors": [ + "Rzeszow", + "web-flow" + ] + }, + { + "pr": "7984", + "title": "[FIX] Chat box no longer auto-focuses when typing", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7963", + "title": "[FIX] Fix the status on the members list", + "userLogin": "MartinSchoeler", + "milestone": "0.59.0-rc.3", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "7965", + "title": "[FIX] Markdown being rendered in code tags", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7983", + "title": "Revert \"npm deps update\"", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "7923", + "title": "[FIX] Email verification indicator added", + "userLogin": "aditya19496", + "milestone": "0.59.0-rc.3", + "contributors": [ + "aditya19496", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "7712", + "title": "[FIX] Show leader on first load", + "userLogin": "danischreiber", + "milestone": "0.59.0-rc.3", + "contributors": [ + "danischreiber", + "rodrigok" + ] + }, + { + "pr": "7909", + "title": "[DOCS] Add native mobile app links into README and update button images", + "userLogin": "rafaelks", + "milestone": "0.59.0-rc.3", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "7971", + "title": "[FIX] Add padding on messages to allow space to the action buttons", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7970", + "title": "[FIX] Small alignment fixes", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7969", + "title": "npm deps update", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "7953", + "title": "[FIX] username ellipsis on firefox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7948", + "title": "[FIX] Document README.md. Drupal repo out of date", + "userLogin": "Lawri-van-Buel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "Lawri-van-Buel" + ] + }, + { + "pr": "7927", + "title": "[FIX] Double scroll on 'keyboard shortcuts' menu in sidepanel", + "userLogin": "aditya19496", + "milestone": "0.59.0-rc.3", + "contributors": [ + "aditya19496" + ] + }, + { + "pr": "7943", + "title": "[FIX] Broken emoji picker on firefox", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7944", + "title": "[FIX] Broken embedded view layout", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7945", + "title": "[FIX] Fix placeholders in account profile", + "userLogin": "josiasds", + "milestone": "0.59.0-rc.3", + "contributors": [ + "josiasds" + ] + }, + { + "pr": "7954", + "title": "[FIX] OTR buttons padding", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7960", + "title": "[FIX] status and active room colors on sidebar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7941", + "title": "Update BlackDuck URL", + "userLogin": "engelgabriel", + "milestone": "0.59.0-rc.3", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "7912", + "title": "[FIX] Fix google play logo on repo README", + "userLogin": "luizbills", + "milestone": "0.59.0-rc.2", + "contributors": [ + "luizbills", + "web-flow" + ] + }, + { + "pr": "7904", + "title": "[FIX] Fix livechat toggle UI issue", + "userLogin": "sampaiodiego", + "milestone": "0.59.0-rc.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7895", + "title": "[FIX] Remove break change in Realtime API", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7893", + "title": "[FIX] Window exception when parsing Markdown on server", + "userLogin": "rodrigok", + "milestone": "0.59.0-rc.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "7894", + "title": "Hide flex-tab close button", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.2", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7888", + "title": "[FIX] sidebar buttons and badge paddings", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7882", + "title": "[FIX] hyperlink style on sidebar footer", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7886", + "title": "[FIX] livechat icon", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7887", + "title": "[FIX] Makes text action menu width based on content size", + "userLogin": "gdelavald", + "milestone": "0.59.0-rc.1", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "7885", + "title": "[FIX] message actions over unread bar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7883", + "title": "[FIX] popover position on mobile", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7881", + "title": "[FIX] search results position on sidebar", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7880", + "title": "[FIX] sidebar paddings", + "userLogin": "karlprieb", + "milestone": "0.59.0-rc.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "7878", + "title": "[FIX] Adds default search text padding for emoji search", + "userLogin": "gdelavald", + "milestone": "0.59.0-rc.1", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "6606", + "title": "Added RocketChatLauncher (SaaS)", + "userLogin": "designgurudotorg", + "milestone": "0.59.0", + "contributors": [ + "designgurudotorg", + "web-flow" + ] + }, + { + "pr": "7866", + "title": "Develop sync", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow", + "geekgonecrazy", + "engelgabriel", + "MartinSchoeler" + ] + }, + { + "pr": "8973", + "title": "Fix tag build", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8972", + "title": "Fix CircleCI deploy filter", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8967", + "title": "Release/0.59.4", + "userLogin": "geekgonecrazy", + "contributors": [ + "cpitman", + "geekgonecrazy", + "karlprieb", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "8685", + "title": "Add CircleCI", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8753", + "title": "[FIX] Channel settings buttons", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + } + ] + }, + "0.60.0-rc.1": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9092", + "title": "[NEW] Modal", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "9111", + "title": "Fix: users listed as online after API login", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9110", + "title": "Fix regression in api channels.members", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9108", + "title": "[FIX] REST API file upload not respecting size limit", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9109", + "title": "[FIX] Creating channels on Firefox", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9095", + "title": "[FIX] Some UI problems on 0.60", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9094", + "title": "[FIX] Update rocketchat:streamer to be compatible with previous version", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.60.0-rc.2": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9137", + "title": "Fix: Clear all unreads modal not closing after confirming", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9138", + "title": "Fix: Message action quick buttons drops if \"new message\" divider is being shown", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9136", + "title": "Fix: Confirmation modals showing `Send` button", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9134", + "title": "[FIX] Importers not recovering when an error occurs", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9121", + "title": "[FIX] Do not block room while loading history", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9120", + "title": "Fix: Multiple unread indicators", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9091", + "title": "[FIX] Channel page error", + "userLogin": "ggrish", + "milestone": "0.60.0", + "contributors": [ + "ggrish", + "web-flow" + ] + } + ] + }, + "0.60.0-rc.3": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9144", + "title": "Fix: Messages being displayed in reverse order", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9062", + "title": "[FIX] Update Rocket.Chat for sandstorm", + "userLogin": "peterlee0127", + "milestone": "0.60.0", + "contributors": [ + "peterlee0127", + "web-flow" + ] + } + ] + }, + "0.60.0-rc.4": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9171", + "title": "[FIX] modal data on enter and modal style for file preview", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9170", + "title": "[FIX] show oauth logins when adblock is used", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9169", + "title": "[FIX] Last sent message reoccurs in textbox", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9166", + "title": "Fix: UI: Descenders of glyphs are cut off", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9165", + "title": "Fix: Click on channel name - hover area bigger than link area", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9162", + "title": "Fix: Can’t login using LDAP via REST", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9149", + "title": "Fix: Unread line", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9146", + "title": "Fix test without oplog by waiting a successful login on changing users", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.60.0-rc.5": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9200", + "title": "Replace postcss-nesting with postcss-nested", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9197", + "title": "Dependencies Update", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9196", + "title": "Fix: Rooms and users are using different avatar style", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9193", + "title": "[FIX] Made welcome emails more readable", + "userLogin": "HammyHavoc", + "milestone": "0.60.0", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9190", + "title": "Typo: German language file", + "userLogin": "TheReal1604", + "milestone": "0.60.0", + "contributors": [ + "TheReal1604" + ] + }, + { + "pr": "9188", + "title": "[FIX] Unread bar position when room have announcement", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9186", + "title": "[FIX] Emoji size on last message preview", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9185", + "title": "[FIX] Cursor position when reply on safari", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9184", + "title": "Fix: Snippet name to not showing in snippet list", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9183", + "title": "Fix/api me only return verified", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9182", + "title": "[FIX] \"Use Emoji\" preference not working", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9181", + "title": "Fix: UI: Descenders of glyphs are cut off", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9176", + "title": "[FIX] make the cross icon on user selection at channel creation page work", + "userLogin": "vitor-nagao", + "milestone": "0.60.0", + "contributors": [ + "vitor-nagao", + "karlprieb", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9172", + "title": "[FIX] go to replied message", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9168", + "title": "[FIX] channel create scroll on small screens", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9066", + "title": "[NEW] Make Custom oauth accept nested usernameField", + "userLogin": "pierreozoux", + "milestone": "0.60.0", + "contributors": [ + "pierreozoux", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "9040", + "title": "[FIX] Error when user roles is missing or is invalid", + "userLogin": "paulovitin", + "milestone": "0.60.0", + "contributors": [ + "paulovitin", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8922", + "title": "[FIX] Make mentions and menu icons color darker", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.60.0-rc.6": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9241", + "title": "[FIX] Show modal with announcement", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9240", + "title": "Fix: Unneeded warning in payload of REST API calls", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9229", + "title": "Fix: Missing option to set user's avatar from a url", + "userLogin": "ggazzo", + "milestone": "0.60.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "9227", + "title": "Fix: updating last message on message edit or delete", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9217", + "title": "Fix: Username find is matching partially", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9215", + "title": "Fix: Upload access control too distributed", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9206", + "title": "[FIX] File upload not working on IE and weird on Chrome", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9194", + "title": "[FIX] \"Enter usernames\" placeholder is cutting in \"create channel\" view", + "userLogin": "TheReal1604", + "milestone": "0.60.0", + "contributors": [ + "TheReal1604" + ] + } + ] + }, + "0.60.0-rc.7": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9243", + "title": "[FIX] Move emojipicker css to theme package", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + } + ] + }, + "0.60.0-rc.8": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9257", + "title": "Do not change room icon color when room is unread", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9256", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9248", + "title": "Add curl, its missing on worker nodes so has to be explicitly added", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "9247", + "title": "Fix: Sidebar item on rtl and small devices", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + } + ] + }, + "0.60.0": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9259", + "title": "Release 0.60.0", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "graywolf336", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8973", + "title": "Fix tag build", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8972", + "title": "Fix CircleCI deploy filter", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8967", + "title": "Release/0.59.4", + "userLogin": "geekgonecrazy", + "contributors": [ + "cpitman", + "geekgonecrazy", + "karlprieb", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "8685", + "title": "Add CircleCI", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "8753", + "title": "[FIX] Channel settings buttons", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + } + ] + }, + "0.60.1": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9262", + "title": "[FIX] File access not working when passing credentials via querystring", + "userLogin": "rodrigok", + "milestone": "0.60.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.60.2": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9280", + "title": "Release 0.60.2", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9277", + "title": "[FIX] Restore translations from other languages", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9274", + "title": "[FIX] Remove sweetalert from livechat facebook integration page", + "userLogin": "sampaiodiego", + "milestone": "0.60.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9272", + "title": "[FIX] Missing translations", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.60.3": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9320", + "title": "Release 0.60.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "HammyHavoc" + ] + }, + { + "pr": "9314", + "title": "[FIX] custom emoji size on sidebar item", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9311", + "title": "[FIX] svg render on firefox", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9249", + "title": "[FIX] sidebar footer padding", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9309", + "title": "[FIX] LDAP/AD is not importing all users", + "userLogin": "rodrigok", + "milestone": "0.60.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9299", + "title": "Fix: English language improvements", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9291", + "title": "Fix: Change 'Wordpress' to 'WordPress", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9290", + "title": "Fix: Improved README.md", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9289", + "title": "[FIX] Wrong position of notifications alert in accounts preference page", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9286", + "title": "Fix: README typo", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9285", + "title": "[FIX] English Typos", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + } + ] + }, + "0.60.4-rc.0": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9343", + "title": "[FIX] LDAP TLS not working in some cases", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9320", + "title": "Release 0.60.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "HammyHavoc" + ] + } + ] + }, + "0.60.4-rc.1": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9328", + "title": "[FIX] popover on safari for iOS", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9330", + "title": "[FIX] announcement hyperlink color", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9335", + "title": "[FIX] Deleting message with store last message not removing", + "userLogin": "sampaiodiego", + "milestone": "0.60.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9345", + "title": "[FIX] last message cutting on bottom", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9346", + "title": "Update Marked dependecy to 0.3.9", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.60.4": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9377", + "title": "Release 0.60.4", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9320", + "title": "Release 0.60.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "HammyHavoc" + ] + } + ] + }, + "0.61.0-rc.0": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "8411", + "title": "[NEW] Contextual Bar Redesign", + "userLogin": "ggazzo", + "milestone": "0.61.0", + "contributors": [ + "geekgonecrazy", + "sampaiodiego", + "MartinSchoeler", + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "9369", + "title": "[FIX][i18n] add room type translation support for room-changed-privacy message", + "userLogin": "cyclops24", + "milestone": "0.61.0", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "9442", + "title": "[NEW] Update documentation: provide example for multiple basedn", + "userLogin": "rndmh3ro", + "milestone": "0.61.0", + "contributors": [ + "rndmh3ro" + ] + }, + { + "pr": "9452", + "title": "[FIX] Fix livechat register form", + "userLogin": "sampaiodiego", + "milestone": "0.61.0", + "contributors": [ + "sampaiodiego", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9451", + "title": "[FIX] Fix livechat build", + "userLogin": "sampaiodiego", + "milestone": "0.61.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9164", + "title": "[FIX] Fix closing livechat inquiry", + "userLogin": "sampaiodiego", + "milestone": "0.61.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9439", + "title": "Add community bot", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9435", + "title": "[FIX] Slash command 'unarchive' throws exception if the channel does not exist ", + "userLogin": "ramrami", + "milestone": "0.61.0", + "contributors": [ + "ramrami", + "web-flow" + ] + }, + { + "pr": "9428", + "title": "[FIX] Slash command 'archive' throws exception if the channel does not exist", + "userLogin": "ramrami", + "milestone": "0.61.0", + "contributors": [ + "ramrami", + "web-flow" + ] + }, + { + "pr": "9432", + "title": "[FIX] Subscriptions not removed when removing user", + "userLogin": "rodrigok", + "milestone": "0.61.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9216", + "title": "[NEW] Sidebar menu option to mark room as unread", + "userLogin": "karlprieb", + "milestone": "0.61.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9228", + "title": "[NEW] Add mention-here permission #7631", + "userLogin": "ryjones", + "milestone": "0.61.0", + "contributors": [ + "ryjones", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "9234", + "title": "[NEW] Indicate the Self DM room", + "userLogin": "rodrigok", + "milestone": "0.61.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9245", + "title": "[NEW] new layout for emojipicker", + "userLogin": "karlprieb", + "milestone": "0.61.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "9364", + "title": "[FIX] Highlight setting not working correctly", + "userLogin": "cyclops24", + "milestone": "0.60.4", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "9366", + "title": "[NEW] add /home link to sidenav footer logo", + "userLogin": "cyclops24", + "contributors": [ + "cyclops24" + ] + }, + { + "pr": "9356", + "title": "Use correct version of Mailparser module", + "userLogin": "rodrigok", + "milestone": "0.61.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9330", + "title": "[FIX] announcement hyperlink color", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9328", + "title": "[FIX] popover on safari for iOS", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9345", + "title": "[FIX] last message cutting on bottom", + "userLogin": "karlprieb", + "milestone": "0.60.4", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9346", + "title": "Update Marked dependecy to 0.3.9", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9335", + "title": "[FIX] Deleting message with store last message not removing", + "userLogin": "sampaiodiego", + "milestone": "0.60.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9314", + "title": "[FIX] custom emoji size on sidebar item", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9311", + "title": "[FIX] svg render on firefox", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9249", + "title": "[FIX] sidebar footer padding", + "userLogin": "karlprieb", + "milestone": "0.60.3", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9309", + "title": "[FIX] LDAP/AD is not importing all users", + "userLogin": "rodrigok", + "milestone": "0.60.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9299", + "title": "Fix: English language improvements", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9291", + "title": "Fix: Change 'Wordpress' to 'WordPress", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9290", + "title": "Fix: Improved README.md", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9289", + "title": "[FIX] Wrong position of notifications alert in accounts preference page", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9286", + "title": "Fix: README typo", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9285", + "title": "[FIX] English Typos", + "userLogin": "HammyHavoc", + "milestone": "0.60.3", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9277", + "title": "[FIX] Restore translations from other languages", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9274", + "title": "[FIX] Remove sweetalert from livechat facebook integration page", + "userLogin": "sampaiodiego", + "milestone": "0.60.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9272", + "title": "[FIX] Missing translations", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9264", + "title": "[FIX] File access not working when passing credentials via querystring", + "userLogin": "rodrigok", + "milestone": "0.60.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9135", + "title": "[NEW] Livechat extract lead data from message", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9107", + "title": "[NEW] Add impersonate option for livechat triggers", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9053", + "title": "[NEW] Add support to external livechat queue service provider", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "9048", + "title": "[BREAK] Decouple livechat visitors from regular users", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9260", + "title": "Develop sync - Bump version to 0.61.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "cpitman", + "geekgonecrazy", + "karlprieb", + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "9257", + "title": "Do not change room icon color when room is unread", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9256", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9247", + "title": "Fix: Sidebar item on rtl and small devices", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9248", + "title": "Add curl, its missing on worker nodes so has to be explicitly added", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "9243", + "title": "[FIX] Move emojipicker css to theme package", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9241", + "title": "[FIX] Show modal with announcement", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9240", + "title": "Fix: Unneeded warning in payload of REST API calls", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9229", + "title": "Fix: Missing option to set user's avatar from a url", + "userLogin": "ggazzo", + "milestone": "0.60.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "9215", + "title": "Fix: Upload access control too distributed", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9217", + "title": "Fix: Username find is matching partially", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9227", + "title": "Fix: updating last message on message edit or delete", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9194", + "title": "[FIX] \"Enter usernames\" placeholder is cutting in \"create channel\" view", + "userLogin": "TheReal1604", + "milestone": "0.60.0", + "contributors": [ + "TheReal1604" + ] + }, + { + "pr": "9206", + "title": "[FIX] File upload not working on IE and weird on Chrome", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9176", + "title": "[FIX] make the cross icon on user selection at channel creation page work", + "userLogin": "vitor-nagao", + "milestone": "0.60.0", + "contributors": [ + "vitor-nagao", + "karlprieb", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9196", + "title": "Fix: Rooms and users are using different avatar style", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9200", + "title": "Replace postcss-nesting with postcss-nested", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9197", + "title": "Dependencies Update", + "userLogin": "engelgabriel", + "milestone": "0.60.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9193", + "title": "[FIX] Made welcome emails more readable", + "userLogin": "HammyHavoc", + "milestone": "0.60.0", + "contributors": [ + "HammyHavoc", + "web-flow" + ] + }, + { + "pr": "9190", + "title": "Typo: German language file", + "userLogin": "TheReal1604", + "milestone": "0.60.0", + "contributors": [ + "TheReal1604" + ] + }, + { + "pr": "9184", + "title": "Fix: Snippet name to not showing in snippet list", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9183", + "title": "Fix/api me only return verified", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9185", + "title": "[FIX] Cursor position when reply on safari", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9186", + "title": "[FIX] Emoji size on last message preview", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9188", + "title": "[FIX] Unread bar position when room have announcement", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9040", + "title": "[FIX] Error when user roles is missing or is invalid", + "userLogin": "paulovitin", + "milestone": "0.60.0", + "contributors": [ + "paulovitin", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "8922", + "title": "[FIX] Make mentions and menu icons color darker", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9182", + "title": "[FIX] \"Use Emoji\" preference not working", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9181", + "title": "Fix: UI: Descenders of glyphs are cut off", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9066", + "title": "[NEW] Make Custom oauth accept nested usernameField", + "userLogin": "pierreozoux", + "milestone": "0.60.0", + "contributors": [ + "pierreozoux", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "9168", + "title": "[FIX] channel create scroll on small screens", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9172", + "title": "[FIX] go to replied message", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9173", + "title": "[Fix] oauth not working because of email array", + "userLogin": "geekgonecrazy", + "milestone": "0.60.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9171", + "title": "[FIX] modal data on enter and modal style for file preview", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9170", + "title": "[FIX] show oauth logins when adblock is used", + "userLogin": "karlprieb", + "milestone": "0.60.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9165", + "title": "Fix: Click on channel name - hover area bigger than link area", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9166", + "title": "Fix: UI: Descenders of glyphs are cut off", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9169", + "title": "[FIX] Last sent message reoccurs in textbox", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9162", + "title": "Fix: Can’t login using LDAP via REST", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9149", + "title": "Fix: Unread line", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9146", + "title": "Fix test without oplog by waiting a successful login on changing users", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9062", + "title": "[FIX] Update Rocket.Chat for sandstorm", + "userLogin": "peterlee0127", + "milestone": "0.60.0", + "contributors": [ + "peterlee0127", + "web-flow" + ] + }, + { + "pr": "9144", + "title": "Fix: Messages being displayed in reverse order", + "userLogin": "sampaiodiego", + "milestone": "0.60.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9137", + "title": "Fix: Clear all unreads modal not closing after confirming", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9138", + "title": "Fix: Message action quick buttons drops if \"new message\" divider is being shown", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9136", + "title": "Fix: Confirmation modals showing `Send` button", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9134", + "title": "[FIX] Importers not recovering when an error occurs", + "userLogin": "graywolf336", + "milestone": "0.60.0", + "contributors": [ + "graywolf336", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9121", + "title": "[FIX] Do not block room while loading history", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9120", + "title": "Fix: Multiple unread indicators", + "userLogin": "rodrigok", + "milestone": "0.60.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9091", + "title": "[FIX] Channel page error", + "userLogin": "ggrish", + "milestone": "0.60.0", + "contributors": [ + "ggrish", + "web-flow" + ] + }, + { + "pr": "9377", + "title": "Release 0.60.4", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9320", + "title": "Release 0.60.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "HammyHavoc" + ] + }, + { + "pr": "9277", + "title": "[FIX] Restore translations from other languages", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9274", + "title": "[FIX] Remove sweetalert from livechat facebook integration page", + "userLogin": "sampaiodiego", + "milestone": "0.60.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9272", + "title": "[FIX] Missing translations", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9262", + "title": "[FIX] File access not working when passing credentials via querystring", + "userLogin": "rodrigok", + "milestone": "0.60.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.61.0-rc.1": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9469", + "title": "[DOCS] Update the links of our Mobile Apps in Features topic", + "userLogin": "rafaelks", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "9490", + "title": "Update license", + "userLogin": "frdmn", + "contributors": [ + "frdmn", + "web-flow" + ] + }, + { + "pr": "9481", + "title": "[FIX] Contextual bar redesign", + "userLogin": "ggazzo", + "milestone": "0.61.0", + "contributors": [ + "ggazzo", + "karlprieb", + "gdelavald" + ] + }, + { + "pr": "9456", + "title": "[FIX] mention-here is missing i18n text #9455", + "userLogin": "ryjones", + "contributors": [ + "ryjones" + ] + } + ] + }, + "0.61.0-rc.2": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9506", + "title": "[FIX] Fix livechat visitor edit", + "userLogin": "sampaiodiego", + "milestone": "0.61.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9510", + "title": "[NEW] Contextual bar mail messages", + "userLogin": "karlprieb", + "milestone": "0.61.0", + "contributors": [ + "karlprieb", + "rodrigok" + ] + }, + { + "pr": "9504", + "title": "Prevent NPM package-lock inside livechat", + "userLogin": "rodrigok", + "milestone": "0.61.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9493", + "title": "[FIX] large names on userinfo, and admin user bug on users with no usernames", + "userLogin": "ggazzo", + "milestone": "0.61.0", + "contributors": [ + "ggazzo", + "web-flow", + "gdelavald" + ] + } + ] + }, + "0.61.0": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9533", + "title": "Release 0.61.0", + "userLogin": "rodrigok", + "milestone": "0.61.0", + "contributors": [ + "rodrigok", + "karlprieb", + "web-flow", + "geekgonecrazy", + "engelgabriel", + "sampaiodiego", + "ryjones" + ] + }, + { + "pr": "9377", + "title": "Release 0.60.4", + "userLogin": "rodrigok", + "milestone": "0.60.4", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9320", + "title": "Release 0.60.3", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "HammyHavoc" + ] + }, + { + "pr": "9277", + "title": "[FIX] Restore translations from other languages", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9274", + "title": "[FIX] Remove sweetalert from livechat facebook integration page", + "userLogin": "sampaiodiego", + "milestone": "0.60.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9272", + "title": "[FIX] Missing translations", + "userLogin": "rodrigok", + "milestone": "0.60.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9262", + "title": "[FIX] File access not working when passing credentials via querystring", + "userLogin": "rodrigok", + "milestone": "0.60.1", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.61.1": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9721", + "title": "Release 0.61.1", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.61.2": { + "node_version": "8.9.3", + "npm_version": "5.5.1", + "pull_requests": [ + { + "pr": "9786", + "title": "Release 0.61.2", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "9750", + "title": "[FIX] Livechat issues on external queue and lead capture", + "userLogin": "sampaiodiego", + "milestone": "0.61.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9776", + "title": "[FIX] Emoji rendering on last message", + "userLogin": "ggazzo", + "milestone": "0.61.2", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "9772", + "title": "[FIX] Livechat conversation not receiving messages when start without form", + "userLogin": "sampaiodiego", + "milestone": "0.61.2", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.62.0-rc.0": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9796", + "title": "Sync from Master", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow", + "HammyHavoc" + ] + }, + { + "pr": "9793", + "title": "[NEW] Version update check", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9778", + "title": "[NEW] General alert banner", + "userLogin": "ggazzo", + "milestone": "0.62.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "9642", + "title": "[NEW] Browse more channels / Directory", + "userLogin": "ggazzo", + "milestone": "0.62.0", + "contributors": [ + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "9665", + "title": "[FIX] Wrong behavior of rooms info's *Read Only* and *Collaborative* buttons", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9457", + "title": "[NEW] Add user settings / preferences API endpoint", + "userLogin": "jgtoriginal", + "milestone": "0.62.0", + "contributors": [ + "jgtoriginal", + "MarcosSpessatto", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9608", + "title": "[NEW] New sidebar layout", + "userLogin": "ggazzo", + "milestone": "0.62.0", + "contributors": [ + "karlprieb", + "ggazzo", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "9662", + "title": "[FIX] Close button on file upload bar was not working", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9717", + "title": "[NEW] Message read receipts", + "userLogin": "sampaiodiego", + "milestone": "0.62.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "7098", + "title": "[NEW] Alert admins when user requires approval & alert users when the account is approved/activated/deactivated", + "userLogin": "luisfn", + "milestone": "0.62.0", + "contributors": [ + "luisfn" + ] + }, + { + "pr": "9666", + "title": "[OTHER] Rocket.Chat Apps", + "userLogin": "graywolf336", + "milestone": "0.62.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9772", + "title": "[FIX] Livechat conversation not receiving messages when start without form", + "userLogin": "sampaiodiego", + "milestone": "0.61.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9776", + "title": "[FIX] Emoji rendering on last message", + "userLogin": "ggazzo", + "milestone": "0.61.2", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "9753", + "title": "Move NRR package to inside the project and convert from CoffeeScript", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "9527", + "title": "[NEW] Allow configuration of SAML logout behavior", + "userLogin": "mrsimpson", + "milestone": "0.62.0", + "contributors": [ + "mrsimpson", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9560", + "title": "[FIX] Chrome 64 breaks jitsi-meet iframe", + "userLogin": "speedy01", + "milestone": "0.62.0", + "contributors": [ + "speedy01", + "web-flow" + ] + }, + { + "pr": "9697", + "title": "[FIX] Harmonize channel-related actions", + "userLogin": "mrsimpson", + "milestone": "0.62.0", + "contributors": [ + "mrsimpson", + "engelgabriel", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9676", + "title": "[FIX] Custom emoji was cropping sometimes", + "userLogin": "anu-007", + "milestone": "0.62.0", + "contributors": [ + "anu-007" + ] + }, + { + "pr": "9696", + "title": "[FIX] Show custom room types icon in channel header", + "userLogin": "mrsimpson", + "milestone": "0.62.0", + "contributors": [ + "mrsimpson", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "8933", + "title": "[NEW] Internal hubot support for Direct Messages and Private Groups", + "userLogin": "ramrami", + "milestone": "0.62.0", + "contributors": [ + "ramrami", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "9424", + "title": "[FIX] 'Query' support for channels.list.joined, groups.list, groups.listAll, im.list", + "userLogin": "xbolshe", + "milestone": "0.62.0", + "contributors": [ + "xbolshe", + "web-flow" + ] + }, + { + "pr": "9298", + "title": "[NEW] Improved default welcome message", + "userLogin": "HammyHavoc", + "milestone": "0.62.0", + "contributors": [ + "HammyHavoc", + "web-flow", + "engelgabriel", + "graywolf336" + ] + }, + { + "pr": "9750", + "title": "[FIX] Livechat issues on external queue and lead capture", + "userLogin": "sampaiodiego", + "milestone": "0.61.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9746", + "title": "[NEW] Makes shield icon configurable", + "userLogin": "c0dzilla", + "milestone": "0.62.0", + "contributors": [ + "c0dzilla", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9747", + "title": "[FIX] DeprecationWarning: prom-client ... when starting Rocket Chat server", + "userLogin": "jgtoriginal", + "milestone": "0.62.0", + "contributors": [ + "jgtoriginal", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9737", + "title": "[FIX] API to retrive rooms was returning empty objects", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "9687", + "title": "[NEW] Global message search (beta: disabled by default)", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "cyberhck", + "savikko", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9487", + "title": "[FIX] Chat Message Reactions REST API End Point", + "userLogin": "jgtoriginal", + "milestone": "0.62.0", + "contributors": [ + "jgtoriginal", + "MarcosSpessatto" + ] + }, + { + "pr": "9312", + "title": "[NEW] Allow sounds when conversation is focused", + "userLogin": "RationalCoding", + "milestone": "0.62.0", + "contributors": [ + "RationalCoding", + "graywolf336" + ] + }, + { + "pr": "9519", + "title": "[NEW] API to fetch permissions & user roles", + "userLogin": "rafaelks", + "milestone": "0.62.0", + "contributors": [ + "rafaelks", + "MarcosSpessatto" + ] + }, + { + "pr": "9509", + "title": "[NEW] REST API to use Spotlight", + "userLogin": "rafaelks", + "milestone": "0.62.0", + "contributors": [ + "rafaelks", + "MarcosSpessatto" + ] + }, + { + "pr": "9546", + "title": "Update to meteor 1.6.1", + "userLogin": "engelgabriel", + "milestone": "0.62.0", + "contributors": [ + "engelgabriel", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9720", + "title": "[FIX] Messages can't be quoted sometimes", + "userLogin": "geekgonecrazy", + "milestone": "0.61.1", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "9716", + "title": "[FIX] GitLab OAuth does not work when GitLab’s URL ends with slash", + "userLogin": "rodrigok", + "milestone": "0.61.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9714", + "title": "[FIX] Close Livechat conversation by visitor not working in version 0.61.0", + "userLogin": "renatobecker", + "milestone": "0.61.1", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "9067", + "title": "[FIX] Formal pronouns and some small mistakes in German texts", + "userLogin": "AmShaegar13", + "milestone": "0.61.1", + "contributors": [ + "AmShaegar13" + ] + }, + { + "pr": "9640", + "title": "[FIX] Facebook integration in livechat not working on version 0.61.0", + "userLogin": "sampaiodiego", + "milestone": "0.61.1", + "contributors": [ + "sampaiodiego", + "web-flow", + "renatobecker" + ] + }, + { + "pr": "9623", + "title": "[FIX] Weird rendering of emojis at sidebar when `last message` is activated", + "userLogin": "ggazzo", + "milestone": "0.61.1", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "9699", + "title": "[NEW] Option to proxy files and avatars through the server", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9711", + "title": "[BREAK] Remove Graphics/Image Magick support", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8193", + "title": "[NEW] Allow request avatar placeholders as PNG or JPG instead of SVG", + "userLogin": "lindoelio", + "milestone": "0.62.0", + "contributors": [ + "lindoelio", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9218", + "title": " [NEW] Image preview as 32x32 base64 jpeg", + "userLogin": "jorgeluisrezende", + "milestone": "0.62.0", + "contributors": [ + "jorgeluisrezende", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9520", + "title": "[FIX] Rest API helpers only applying to v1", + "userLogin": "graywolf336", + "milestone": "0.62.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9639", + "title": "[FIX] Desktop notification not showing when avatar came from external storage service", + "userLogin": "rodrigok", + "milestone": "0.61.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9454", + "title": "[FIX] Missing link Site URLs in enrollment e-mails", + "userLogin": "kemitchell", + "milestone": "0.62.0", + "contributors": [ + "kemitchell" + ] + }, + { + "pr": "9610", + "title": "[FIX] Missing string 'Username_already_exist' on the accountProfile page", + "userLogin": "lunaticmonk", + "milestone": "0.62.0", + "contributors": [ + "lunaticmonk" + ] + }, + { + "pr": "9507", + "title": "[NEW] New REST API to mark channel as read", + "userLogin": "rafaelks", + "milestone": "0.62.0", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "9549", + "title": "[NEW] Add route to get user shield/badge", + "userLogin": "kb0304", + "milestone": "0.62.0", + "contributors": [ + "kb0304", + "graywolf336" + ] + }, + { + "pr": "9570", + "title": "[FIX] SVG avatars are not been displayed correctly when load in non HTML containers", + "userLogin": "filipedelimabrito", + "milestone": "0.62.0", + "contributors": [ + "filipedelimabrito" + ] + }, + { + "pr": "9599", + "title": "[FIX] Livechat is not working when running in a sub path", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "8158", + "title": "[NEW] GraphQL API", + "userLogin": "kamilkisiela", + "milestone": "0.62.0", + "contributors": [ + "kamilkisiela", + "web-flow" + ] + }, + { + "pr": "9255", + "title": "[NEW] Livestream tab", + "userLogin": "gdelavald", + "milestone": "0.62.0", + "contributors": [ + "gdelavald" + ] + } + ] + }, + "0.62.0-rc.1": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9843", + "title": "Regression: Avatar now open account related options", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9837", + "title": "Regression: Open search using ctrl/cmd + p and ctrl/cmd + k", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9839", + "title": "Regression: Search bar is now full width", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9658", + "title": "[NEW] Add documentation requirement to PRs", + "userLogin": "SeanPackham", + "contributors": [ + "SeanPackham", + "web-flow", + "MartinSchoeler" + ] + }, + { + "pr": "9807", + "title": "[NEW] Request mongoDB version in github issue template", + "userLogin": "TwizzyDizzy", + "contributors": [ + "TwizzyDizzy", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "9802", + "title": "[FIX] Not receiving sound notifications in rooms created by new LiveChats", + "userLogin": "renatobecker", + "milestone": "0.62.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "9811", + "title": "Dependencies update", + "userLogin": "engelgabriel", + "milestone": "0.62.0", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9821", + "title": "Fix: Custom fields not showing on user info panel", + "userLogin": "ggazzo", + "milestone": "0.62.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "9804", + "title": "Regression: Page was not respecting the window height on Firefox", + "userLogin": "MartinSchoeler", + "milestone": "0.62.0", + "contributors": [ + "MartinSchoeler", + "web-flow" + ] + }, + { + "pr": "9784", + "title": "Update bot-config.yml", + "userLogin": "JSzaszvari", + "contributors": [ + "JSzaszvari", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "9797", + "title": "Develop fix sync from master", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.62.0-rc.2": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9851", + "title": "Regression: Change create channel icon", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9852", + "title": "Regression: Fix channel icons on safari", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9845", + "title": "Regression: Fix admin/user settings item text", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "9858", + "title": "[FIX] Silence the update check error message", + "userLogin": "graywolf336", + "milestone": "0.62.0", + "contributors": [ + "graywolf336" + ] + } + ] + }, + "0.62.0-rc.3": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9905", + "title": "Regression: Improve sidebar filter", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9902", + "title": "[OTHER] Fix Apps not working on multi-instance deployments", + "userLogin": "graywolf336", + "milestone": "0.62.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9877", + "title": "[Fix] Not Translated Phrases", + "userLogin": "bernardoetrevisan", + "milestone": "0.62.0", + "contributors": [ + "bernardoetrevisan", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9884", + "title": "[FIX] Parsing messages with multiple markdown matches ignore some tokens", + "userLogin": "c0dzilla", + "milestone": "0.62.0", + "contributors": [ + "c0dzilla" + ] + }, + { + "pr": "9850", + "title": "[FIX] Importers no longer working due to the FileUpload changes", + "userLogin": "graywolf336", + "milestone": "0.62.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9889", + "title": "Regression: Overlapping header in user profile panel", + "userLogin": "kaiiiiiiiii", + "milestone": "0.62.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "9888", + "title": "[FIX] Misplaced \"Save Changes\" button in user account panel", + "userLogin": "kaiiiiiiiii", + "milestone": "0.62.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "9897", + "title": "Regression: sort on room's list not working correctly", + "userLogin": "ggazzo", + "milestone": "0.62.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "9879", + "title": "[FIX] Snap build was failing", + "userLogin": "geekgonecrazy", + "milestone": "0.62.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + } + ] + }, + "0.62.0": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9935", + "title": "Release 0.62.0", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow", + "sampaiodiego", + "MartinSchoeler", + "renatobecker", + "engelgabriel", + "geekgonecrazy" + ] + }, + { + "pr": "9934", + "title": "[FIX] Typo on french translation for \"Open\"", + "userLogin": "sizrar", + "milestone": "0.62.0", + "contributors": [ + "sizrar", + "web-flow" + ] + }, + { + "pr": "9928", + "title": "Regression: Fix livechat queue link", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9931", + "title": "Regression: Directory now list default channel", + "userLogin": "karlprieb", + "milestone": "0.62.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9908", + "title": "Improve link handling for attachments", + "userLogin": "rodrigok", + "milestone": "0.62.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9883", + "title": "Regression: Misplaced language dropdown in user preferences panel", + "userLogin": "kaiiiiiiiii", + "milestone": "0.62.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "9901", + "title": "Fix RHCC image path for OpenShift and default to the current namespace.", + "userLogin": "jsm84", + "contributors": [ + "jsm84", + "geekgonecrazy", + "web-flow" + ] + } + ] + }, + "0.62.1": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9989", + "title": "Release 0.62.1", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9986", + "title": "[FIX] Delete user without username was removing direct rooms of all users", + "userLogin": "rodrigok", + "milestone": "0.62.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "9988", + "title": "[FIX] New channel page on medium size screens", + "userLogin": "karlprieb", + "milestone": "0.62.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9960", + "title": "[FIX] Empty sidenav when sorting by activity and there is a subscription without room", + "userLogin": "ggazzo", + "milestone": "0.62.1", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9982", + "title": "[FIX] Two factor authentication modal was not showing", + "userLogin": "sampaiodiego", + "milestone": "0.62.1", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.62.2": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10087", + "title": "Release 0.62.2", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10071", + "title": "[FIX] Slack Import reports `invalid import file type` due to a call to BSON.native() which is now doesn't exist", + "userLogin": "trongthanh", + "milestone": "0.62.2", + "contributors": [ + "trongthanh" + ] + }, + { + "pr": "9719", + "title": "[FIX] Verified property of user is always set to false if not supplied", + "userLogin": "MarcosSpessatto", + "milestone": "0.62.2", + "contributors": [ + "MarcosSpessatto", + "rodrigok" + ] + }, + { + "pr": "10076", + "title": "[FIX] Update preferences of users with settings: null was crashing the server", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10009", + "title": "[FIX] REST API: Can't list all public channels when user has permission `view-joined-room`", + "userLogin": "MarcosSpessatto", + "milestone": "0.62.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10061", + "title": "[FIX] Message editing is crashing the server when read receipts are enabled", + "userLogin": "sampaiodiego", + "milestone": "0.62.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10029", + "title": "[FIX] Download links was duplicating Sub Paths", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.63.0-rc.0": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10246", + "title": "[NEW] Interface to install and manage RocketChat Apps (alpha)", + "userLogin": "ggazzo", + "milestone": "0.63.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10243", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.63.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10012", + "title": "[FIX] \"View All Members\" button inside channel's \"User Info\" is over sized", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10242", + "title": "Revert \"[FIX] Apostrophe-containing URL misparsed\"", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10054", + "title": "[NEW] Livechat messages rest APIs", + "userLogin": "hmagarotto", + "milestone": "0.63.0", + "contributors": [ + "hmagarotto", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "9907", + "title": "[NEW] Endpoint to retrieve message read receipts", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10237", + "title": "Rename migration name on 108 to match file name", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10159", + "title": "Fix typo for Nextcloud login", + "userLogin": "pierreozoux", + "milestone": "0.63.0", + "contributors": [ + "pierreozoux", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "10222", + "title": "[FIX] user status on sidenav", + "userLogin": "ggazzo", + "milestone": "0.63.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10152", + "title": "[FIX] Dynamic CSS script isn't working on older browsers", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9816", + "title": "[NEW] Add option to login via REST using Facebook and Twitter tokens", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "9629", + "title": "[NEW] Add REST endpoint to get the list of custom emojis", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "9947", + "title": "[NEW] GDPR Right to be forgotten/erased", + "userLogin": "Hudell", + "milestone": "0.63.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10105", + "title": "[NEW] Added endpoint to retrieve mentions of a channel", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10160", + "title": "[FIX] Extended view mode on sidebar", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "10082", + "title": "[FIX] Cannot answer to a livechat as a manager if agent has not answered yet", + "userLogin": "kb0304", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "web-flow" + ] + }, + { + "pr": "9584", + "title": "[NEW] Add leave public channel & leave private channel permissions", + "userLogin": "kb0304", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10128", + "title": "[NEW] Added GET/POST channels.notifications", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10103", + "title": "[BREAK] Removed Private History Route", + "userLogin": "Hudell", + "milestone": "0.63.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "9866", + "title": "[FIX] User status missing on user info", + "userLogin": "lunaticmonk", + "milestone": "0.63.0", + "contributors": [ + "lunaticmonk" + ] + }, + { + "pr": "9672", + "title": "[FIX] Name of files in file upload list cuts down at bottom due to overflow", + "userLogin": "lunaticmonk", + "milestone": "0.63.0", + "contributors": [ + "lunaticmonk" + ] + }, + { + "pr": "9783", + "title": "[FIX] No pattern for user's status text capitalization", + "userLogin": "lunaticmonk", + "milestone": "0.63.0", + "contributors": [ + "lunaticmonk" + ] + }, + { + "pr": "9739", + "title": "[FIX] Apostrophe-containing URL misparsed", + "userLogin": "lunaticmonk", + "milestone": "0.63.0", + "contributors": [ + "lunaticmonk" + ] + }, + { + "pr": "9860", + "title": "[FIX] Popover divs don't scroll if they overflow the viewport", + "userLogin": "Joe-mcgee", + "milestone": "0.63.0", + "contributors": [ + "Joe-mcgee", + "web-flow" + ] + }, + { + "pr": "10086", + "title": "[NEW] Reply preview", + "userLogin": "ubarsaiyan", + "milestone": "0.63.0", + "contributors": [ + "ubarsaiyan", + "web-flow" + ] + }, + { + "pr": "10104", + "title": "[FIX] Reactions not working on mobile", + "userLogin": "ggazzo", + "milestone": "0.63.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10123", + "title": "[NEW] Support for agent's phone field", + "userLogin": "renatobecker", + "milestone": "0.63.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "9872", + "title": "[FIX] Broken video call accept dialog", + "userLogin": "ramrami", + "milestone": "0.63.0", + "contributors": [ + "ramrami" + ] + }, + { + "pr": "10081", + "title": "[FIX] Wrong switch button border color", + "userLogin": "kb0304", + "milestone": "0.63.0", + "contributors": [ + "kb0304" + ] + }, + { + "pr": "10154", + "title": "Add a few listener supports for the Rocket.Chat Apps", + "userLogin": "graywolf336", + "milestone": "0.63.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10148", + "title": "Add forums as a place to suggest, discuss and upvote features", + "userLogin": "SeanPackham", + "contributors": [ + "SeanPackham", + "web-flow" + ] + }, + { + "pr": "10090", + "title": "[FIX] Nextcloud as custom oauth provider wasn't mapping data correctly", + "userLogin": "pierreozoux", + "milestone": "0.63.0", + "contributors": [ + "pierreozoux", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10144", + "title": "[NEW] Added endpoint to get the list of available oauth services", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10016", + "title": "[FIX] Missing sidebar default options on admin", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "8667", + "title": "[FIX] Able to react with invalid emoji", + "userLogin": "mutdmour", + "milestone": "0.63.0", + "contributors": [ + "mutdmour", + "rodrigok", + "web-flow", + "MarcosSpessatto" + ] + }, + { + "pr": "9742", + "title": "[NEW] REST API method to set room's announcement (channels.setAnnouncement)", + "userLogin": "TopHattedCat", + "milestone": "0.63.0", + "contributors": [ + "TopHattedCat", + "web-flow" + ] + }, + { + "pr": "9726", + "title": "[NEW] Audio recording as mp3 and better ui for recording", + "userLogin": "kb0304", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "rodrigok", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "9732", + "title": "[NEW] Setting to configure max delta for 2fa", + "userLogin": "Hudell", + "milestone": "0.63.0", + "contributors": [ + "Hudell", + "web-flow", + "engelgabriel", + "sampaiodiego" + ] + }, + { + "pr": "9870", + "title": "[NEW] Livechat webhook request on message", + "userLogin": "hmagarotto", + "milestone": "0.63.0", + "contributors": [ + "hmagarotto", + "web-flow" + ] + }, + { + "pr": "10071", + "title": "[FIX] Slack Import reports `invalid import file type` due to a call to BSON.native() which is now doesn't exist", + "userLogin": "trongthanh", + "milestone": "0.62.2", + "contributors": [ + "trongthanh" + ] + }, + { + "pr": "9719", + "title": "[FIX] Verified property of user is always set to false if not supplied", + "userLogin": "MarcosSpessatto", + "milestone": "0.62.2", + "contributors": [ + "MarcosSpessatto", + "rodrigok" + ] + }, + { + "pr": "10076", + "title": "[FIX] Update preferences of users with settings: null was crashing the server", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10065", + "title": "Fix tests breaking randomly", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10009", + "title": "[FIX] REST API: Can't list all public channels when user has permission `view-joined-room`", + "userLogin": "MarcosSpessatto", + "milestone": "0.62.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10061", + "title": "[FIX] Message editing is crashing the server when read receipts are enabled", + "userLogin": "sampaiodiego", + "milestone": "0.62.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10029", + "title": "[FIX] Download links was duplicating Sub Paths", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10051", + "title": "[FIX] User preferences can't be saved when roles are hidden in admin settings", + "userLogin": "Hudell", + "milestone": "0.63.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "9367", + "title": "[NEW] Announcement bar color wasn't using color from theming variables", + "userLogin": "cyclops24", + "milestone": "0.63.0", + "contributors": [ + "cyclops24", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "9932", + "title": "[FIX] Browser was auto-filling values when editing another user profile", + "userLogin": "kaiiiiiiiii", + "milestone": "0.63.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "10011", + "title": "[FIX] Avatar input was accepting not supported image types", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "10028", + "title": "[FIX] Initial loading feedback was missing", + "userLogin": "karlprieb", + "milestone": "0.63.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "10036", + "title": "[OTHER] Reactivate all tests", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9844", + "title": "[OTHER] Reactivate API tests", + "userLogin": "karlprieb", + "contributors": [ + "karlprieb", + "MarcosSpessatto" + ] + }, + { + "pr": "9986", + "title": "[FIX] Delete user without username was removing direct rooms of all users", + "userLogin": "rodrigok", + "milestone": "0.62.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "9982", + "title": "[FIX] Two factor authentication modal was not showing", + "userLogin": "sampaiodiego", + "milestone": "0.62.1", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "9960", + "title": "[FIX] Empty sidenav when sorting by activity and there is a subscription without room", + "userLogin": "ggazzo", + "milestone": "0.62.1", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9988", + "title": "[FIX] New channel page on medium size screens", + "userLogin": "karlprieb", + "milestone": "0.62.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9985", + "title": "Start 0.63.0-develop / develop sync from master", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10087", + "title": "Release 0.62.2", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9986", + "title": "[FIX] Delete user without username was removing direct rooms of all users", + "userLogin": "rodrigok", + "milestone": "0.62.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "9988", + "title": "[FIX] New channel page on medium size screens", + "userLogin": "karlprieb", + "milestone": "0.62.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9960", + "title": "[FIX] Empty sidenav when sorting by activity and there is a subscription without room", + "userLogin": "ggazzo", + "milestone": "0.62.1", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9982", + "title": "[FIX] Two factor authentication modal was not showing", + "userLogin": "sampaiodiego", + "milestone": "0.62.1", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.63.0-rc.1": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10272", + "title": "[FIX] File had redirect delay when using external storage services and no option to proxy only avatars", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10257", + "title": "Fix: Renaming channels.notifications Get/Post endpoints", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10262", + "title": "[FIX] Missing pt-BR translations", + "userLogin": "sampaiodiego", + "milestone": "0.63.0", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10240", + "title": "[FIX] /me REST endpoint was missing user roles and preferences", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10260", + "title": "Fix caddy download link to pull from github", + "userLogin": "geekgonecrazy", + "milestone": "0.63.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10252", + "title": "Fix: possible errors on rocket.chat side of the apps", + "userLogin": "graywolf336", + "milestone": "0.63.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10015", + "title": "Fix snap install. Remove execstack from sharp, and bypass grpc error", + "userLogin": "geekgonecrazy", + "milestone": "0.63.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + } + ] + }, + "0.63.0-rc.2": { + "node_version": "8.9.4", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10078", + "title": "[FIX] Unable to mention after newline in message", + "userLogin": "c0dzilla", + "milestone": "0.63.0", + "contributors": [ + "c0dzilla" + ] + }, + { + "pr": "10224", + "title": "[FIX] Wrong pagination information on /api/v1/channels.members", + "userLogin": "MarcosSpessatto", + "milestone": "0.63.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10163", + "title": "[FIX] Inline code following a url leads to autolinking of code with url", + "userLogin": "c0dzilla", + "milestone": "0.63.0", + "contributors": [ + "c0dzilla" + ] + }, + { + "pr": "10258", + "title": "[FIX] Incoming Webhooks were missing the raw content", + "userLogin": "Hudell", + "milestone": "0.63.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10270", + "title": "[FIX] Missing Translation Key on Reactions", + "userLogin": "bernardoetrevisan", + "milestone": "0.63.0", + "contributors": [ + "bernardoetrevisan", + "web-flow", + "graywolf336" + ] + }, + { + "pr": "10274", + "title": "Fix: inputs for rocketchat apps", + "userLogin": "ggazzo", + "milestone": "0.63.0", + "contributors": [ + "ggazzo", + "web-flow", + "graywolf336" + ] + }, + { + "pr": "10290", + "title": "Fix: chat.react api not accepting previous emojis", + "userLogin": "graywolf336", + "milestone": "0.63.0", + "contributors": [ + "graywolf336", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10300", + "title": "Fix: Scroll on content page", + "userLogin": "ggazzo", + "milestone": "0.63.0", + "contributors": [ + "ggazzo" + ] + } + ] + }, + "0.63.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10324", + "title": "Release 0.63.0", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "MarcosSpessatto", + "hmagarotto", + "engelgabriel", + "web-flow", + "TopHattedCat", + "karlprieb", + "Joe-mcgee", + "lunaticmonk", + "ramrami", + "kaiiiiiiiii", + "Hudell", + "ggazzo", + "rodrigok" + ] + }, + { + "pr": "10087", + "title": "Release 0.62.2", + "userLogin": "rodrigok", + "milestone": "0.62.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9986", + "title": "[FIX] Delete user without username was removing direct rooms of all users", + "userLogin": "rodrigok", + "milestone": "0.62.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "9988", + "title": "[FIX] New channel page on medium size screens", + "userLogin": "karlprieb", + "milestone": "0.62.1", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "9960", + "title": "[FIX] Empty sidenav when sorting by activity and there is a subscription without room", + "userLogin": "ggazzo", + "milestone": "0.62.1", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9982", + "title": "[FIX] Two factor authentication modal was not showing", + "userLogin": "sampaiodiego", + "milestone": "0.62.1", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10303", + "title": "[FIX] Audio Message UI fixes", + "userLogin": "kb0304", + "contributors": [ + "kb0304", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10319", + "title": "[NEW] Improve history generation", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10323", + "title": "Fix: Reaction endpoint/api only working with regular emojis", + "userLogin": "graywolf336", + "milestone": "0.63.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10313", + "title": "Bump snap version to include security fix", + "userLogin": "geekgonecrazy", + "milestone": "0.63.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10314", + "title": "Update Meteor to 1.6.1.1", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.63.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10374", + "title": "Release 0.63.1", + "userLogin": "sampaiodiego", + "contributors": [ + "TechyPeople", + "web-flow", + "tttt-conan", + "rodrigok", + "geekgonecrazy", + "graywolf336", + "kaiiiiiiiii", + "sampaiodiego" + ] + }, + { + "pr": "10324", + "title": "Release 0.63.0", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "MarcosSpessatto", + "hmagarotto", + "engelgabriel", + "web-flow", + "TopHattedCat", + "karlprieb", + "Joe-mcgee", + "lunaticmonk", + "ramrami", + "kaiiiiiiiii", + "Hudell", + "ggazzo", + "rodrigok" + ] + }, + { + "pr": "10324", + "title": "Release 0.63.0", + "userLogin": "rodrigok", + "milestone": "0.63.0", + "contributors": [ + "kb0304", + "MarcosSpessatto", + "hmagarotto", + "engelgabriel", + "web-flow", + "TopHattedCat", + "karlprieb", + "Joe-mcgee", + "lunaticmonk", + "ramrami", + "kaiiiiiiiii", + "Hudell", + "ggazzo", + "rodrigok" + ] + } + ] + }, + "0.63.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10476", + "title": "Release 0.63.2", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10408", + "title": "add redhat dockerfile to master", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.63.3": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10504", + "title": "Release 0.63.3", + "userLogin": "graywolf336", + "contributors": [ + "rafaelks", + "graywolf336" + ] + } + ] + }, + "0.64.0-rc.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10532", + "title": "Included missing lib for migrations", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell", + "rodrigok" + ] + }, + { + "pr": "10502", + "title": "[NEW] Option to mute group mentions (@all and @here)", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "9906", + "title": "[NEW] GDPR - Right to access and Data Portability", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "9922", + "title": "[BREAK] Validate incoming message schema", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto", + "ggazzo" + ] + }, + { + "pr": "9950", + "title": "[NEW] Broadcast Channels", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "web-flow", + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "10480", + "title": "[FIX] Add user object to responses in /*.files Rest endpoints", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto", + "rodrigok" + ] + }, + { + "pr": "10517", + "title": "[NEW] Option to ignore users on channels", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "gdelavald", + "web-flow", + "karlprieb" + ] + }, + { + "pr": "10110", + "title": "[NEW] Search Provider Framework", + "userLogin": "tkurz", + "milestone": "0.64.0", + "contributors": [ + "tkurz", + "web-flow" + ] + }, + { + "pr": "10473", + "title": "[FIX] Missing user data on files uploaded through the API", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10498", + "title": "[FIX] Rename method to clean history of messages", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10410", + "title": "[FIX] REST spotlight API wasn't allowing searches with # and @", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10505", + "title": "Develop sync", + "userLogin": "graywolf336", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336", + "nsuchy", + "rodrigok", + "rafaelks", + "engelgabriel" + ] + }, + { + "pr": "10442", + "title": "[NEW] REST API endpoint `/directory`", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10482", + "title": "[FIX] Dropdown elements were using old styles", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "10513", + "title": "Fix: Remove \"secret\" from REST endpoint /settings.oauth response", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10403", + "title": "[FIX] Directory sort and column sizes were wrong", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "web-flow", + "karlprieb" + ] + }, + { + "pr": "10299", + "title": "[FIX] REST API OAuth services endpoint were missing fields and flag to indicate custom services", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10446", + "title": "[FIX] Error messages weren't been displayed when email verification fails", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10454", + "title": "[FIX] Wrong column positions in the directory search for users", + "userLogin": "lunaticmonk", + "milestone": "0.64.0", + "contributors": [ + "lunaticmonk", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10463", + "title": "[FIX] Custom fields was misaligned in registration form", + "userLogin": "dschuan", + "milestone": "0.64.0", + "contributors": [ + "dschuan", + "web-flow" + ] + }, + { + "pr": "10341", + "title": "[FIX] Unique identifier file not really being unique", + "userLogin": "abernix", + "milestone": "0.64.0", + "contributors": [ + "abernix", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "10335", + "title": "[OTHER] More Listeners for Apps & Utilize Promises inside Apps", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10404", + "title": "[FIX] Empty panel after changing a user's username", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10418", + "title": " [FIX] Russian translation of \"False\"", + "userLogin": "strangerintheq", + "contributors": [ + "strangerintheq", + "web-flow" + ] + }, + { + "pr": "10496", + "title": "[FIX] Links being embedded inside of blockquotes", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10485", + "title": "[FIX] The 'channel.messages' REST API Endpoint error", + "userLogin": "rafaelks", + "milestone": "0.64.0", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "10487", + "title": "[OTHER] Develop sync", + "userLogin": "graywolf336", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336" + ] + }, + { + "pr": "10358", + "title": "[FIX] Button on user info contextual bar scrolling with the content", + "userLogin": "okaybroda", + "milestone": "0.64.0", + "contributors": [ + "okaybroda", + "ggazzo", + "web-flow", + "karlprieb", + "graywolf336" + ] + }, + { + "pr": "9824", + "title": "[FIX] \"Idle Time Limit\" using milliseconds instead of seconds", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii", + "web-flow", + "geekgonecrazy", + "sampaiodiego", + "graywolf336" + ] + }, + { + "pr": "10259", + "title": "[NEW] Body of the payload on an incoming webhook is included on the request object", + "userLogin": "Hudell", + "milestone": "0.64.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10387", + "title": "[FIX] Missing i18n translation key for \"Unread\"", + "userLogin": "Hudell", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "9729", + "title": "[FIX] Owner unable to delete channel or group from APIs", + "userLogin": "c0dzilla", + "milestone": "0.64.0", + "contributors": [ + "c0dzilla", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10371", + "title": "[NEW] REST endpoint to recover forgotten password", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10354", + "title": "[NEW] REST endpoint to report messages", + "userLogin": "MarcosSpessatto", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10108", + "title": "[NEW] Livechat setting to customize ended conversation message", + "userLogin": "renatobecker", + "milestone": "0.64.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "10369", + "title": "[FIX] Livechat translation files being ignored", + "userLogin": "renatobecker", + "milestone": "0.64.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "7964", + "title": "[NEW] Twilio MMS support for LiveChat integration", + "userLogin": "t3hchipmunk", + "milestone": "0.64.0", + "contributors": [ + "t3hchipmunk", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "6673", + "title": "[FIX] Missing page \"not found\"", + "userLogin": "Prakharsvnit", + "milestone": "0.64.0", + "contributors": [ + "Prakharsvnit", + "web-flow", + "geekgonecrazy", + "karlprieb" + ] + }, + { + "pr": "10083", + "title": "[FIX] \"Highlight Words\" wasn't working with more than one word", + "userLogin": "nemaniarjun", + "milestone": "0.64.0", + "contributors": [ + "nemaniarjun", + "gdelavald", + "web-flow" + ] + }, + { + "pr": "10171", + "title": "[FIX] Missing \"Administration\" menu for user with manage-emoji permission", + "userLogin": "c0dzilla", + "milestone": "0.64.0", + "contributors": [ + "c0dzilla", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10395", + "title": "[FIX] Message view mode setting was missing at user's preferences ", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10399", + "title": "[FIX] Profile image was not being shown in user's directory search", + "userLogin": "lunaticmonk", + "milestone": "0.64.0", + "contributors": [ + "lunaticmonk", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10342", + "title": "[NEW] REST API endpoint `rooms.favorite` to favorite and unfavorite rooms", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10428", + "title": "[FIX] Wrong positioning of popover when using RTL languages", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10472", + "title": "[FIX] Messages was grouping wrong some times when server is slow", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10225", + "title": "[FIX] GitLab authentication scope was too open, reduced to read only access", + "userLogin": "rafaelks", + "milestone": "0.64.0", + "contributors": [ + "rafaelks", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10344", + "title": "[FIX] Renaming agent's username within Livechat's department", + "userLogin": "renatobecker", + "milestone": "0.64.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "10394", + "title": "[FIX] Missing RocketApps input types", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "web-flow", + "graywolf336", + "karlprieb" + ] + }, + { + "pr": "10221", + "title": "[FIX] Livechat desktop notifications not being displayed", + "userLogin": "renatobecker", + "milestone": "0.64.0", + "contributors": [ + "renatobecker", + "web-flow" + ] + }, + { + "pr": "10336", + "title": "Change Docker-Compose to use mmapv1 storage engine for mongo", + "userLogin": "geekgonecrazy", + "milestone": "0.64.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10396", + "title": "[NEW] Add internal API to handle room announcements", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10409", + "title": "[FIX] Autocomplete list when inviting a user was partial hidden", + "userLogin": "karlprieb", + "milestone": "0.64.0", + "contributors": [ + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10423", + "title": "[FIX] Remove a user from the user's list when creating a new channel removes the wrong user", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10430", + "title": "[FIX] Room's name was cutting instead of having ellipses on sidebar", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10435", + "title": "Add some missing translations", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10437", + "title": "[NEW] Add message preview when quoting another message", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10438", + "title": "[FIX] Button to delete rooms by the owners wasn't appearing", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "10439", + "title": "[NEW] Prevent the browser to autocomplete some setting fields", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10441", + "title": "[OTHER] Removed the developer warning on the rest api", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10444", + "title": "[NEW] Shows user's real name on autocomplete popup", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10414", + "title": "[NEW] Automatically trigger Redhat registry build when tagging new release", + "userLogin": "geekgonecrazy", + "milestone": "0.64.0", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "10397", + "title": "Fix and improve vietnamese translation", + "userLogin": "tttt-conan", + "contributors": [ + "tttt-conan", + "TDiNguyen", + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10411", + "title": "[BREAK] The property \"settings\" is no longer available to regular users via rest api", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "9946", + "title": "[FIX] Updated OpenShift Template to take an Image as a Param", + "userLogin": "christianh814", + "contributors": [ + "christianh814", + "web-flow", + "geekgonecrazy" + ] + }, + { + "pr": "10405", + "title": "Use Node 8.9 for CI build", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "9576", + "title": "[FIX] Incoming integrations being able to trigger an empty message with a GET", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10360", + "title": "Update allowed labels for bot", + "userLogin": "TwizzyDizzy", + "contributors": [ + "TwizzyDizzy", + "web-flow" + ] + }, + { + "pr": "10384", + "title": "Remove @core team mention from Pull Request template", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10390", + "title": "[FIX] Snaps installations are breaking on avatar requests", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10234", + "title": "New issue template for *Release Process*", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10376", + "title": "Master into Develop Branch Sync", + "userLogin": "graywolf336", + "contributors": [ + "sampaiodiego", + "rodrigok", + "web-flow", + "graywolf336" + ] + }, + { + "pr": "10504", + "title": "Release 0.63.3", + "userLogin": "graywolf336", + "contributors": [ + "rafaelks", + "graywolf336" + ] + }, + { + "pr": "10476", + "title": "Release 0.63.2", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10408", + "title": "add redhat dockerfile to master", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.64.0-rc.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10545", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.64.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10544", + "title": "Regression: Revert announcement structure", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10543", + "title": "Regression: Upload was not working", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.64.0-rc.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10549", + "title": "Deps update", + "userLogin": "engelgabriel", + "milestone": "0.64.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10560", + "title": "Regression: /api/v1/settings.oauth not returning clientId for Twitter", + "userLogin": "cardoso", + "milestone": "0.64.0", + "contributors": [ + "cardoso", + "web-flow" + ] + }, + { + "pr": "10555", + "title": "Regression: Webhooks breaking due to restricted test", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10559", + "title": "Regression: Rooms and Apps weren't playing nice with each other", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10554", + "title": "Regression: Fix announcement bar being displayed without content", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald" + ] + } + ] + }, + "0.64.0-rc.3": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10550", + "title": "[FIX] Wordpress oAuth authentication wasn't behaving correctly", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "10553", + "title": "Regression: Inconsistent response of settings.oauth endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10571", + "title": "Regression: Remove added mentions on quote/reply", + "userLogin": "gdelavald", + "milestone": "0.64.0", + "contributors": [ + "gdelavald", + "rodrigok" + ] + }, + { + "pr": "10573", + "title": "Regression: Attachments and fields incorrectly failing on validation", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + } + ] + }, + "0.64.0-rc.4": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10558", + "title": "[FIX] Switch buttons were cutting in RTL mode", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10574", + "title": "[NEW] Add information regarding Zapier and Bots to the integrations page", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10575", + "title": "Regression: Rocket.Chat App author link opens in same window", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii", + "web-flow" + ] + }, + { + "pr": "10503", + "title": "[FIX] Stop Firefox announcement overflowing viewport", + "userLogin": "brendangadd", + "milestone": "0.64.0", + "contributors": [ + "brendangadd", + "web-flow" + ] + } + ] + }, + "0.64.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10613", + "title": "Release 0.64.0", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "web-flow", + "graywolf336", + "TwizzyDizzy", + "christianh814", + "tttt-conan", + "gdelavald", + "ggazzo" + ] + }, + { + "pr": "10504", + "title": "Release 0.63.3", + "userLogin": "graywolf336", + "contributors": [ + "rafaelks", + "graywolf336" + ] + }, + { + "pr": "10476", + "title": "Release 0.63.2", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10408", + "title": "add redhat dockerfile to master", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + }, + { + "pr": "10591", + "title": "Regression: Various search provider fixes", + "userLogin": "tkurz", + "milestone": "0.64.0", + "contributors": [ + "tkurz", + "web-flow", + "engelgabriel", + "sampaiodiego" + ] + }, + { + "pr": "10596", + "title": "Regression: /api/v1/settings.oauth not sending needed info for SAML & CAS", + "userLogin": "cardoso", + "milestone": "0.64.0", + "contributors": [ + "cardoso", + "web-flow" + ] + }, + { + "pr": "10598", + "title": "Regression: Apps and Livechats not getting along well with each other", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10551", + "title": " [FIX] Missing \"Administration\" menu for users with some administration permissions", + "userLogin": "kaiiiiiiiii", + "milestone": "0.64.0", + "contributors": [ + "kaiiiiiiiii" + ] + }, + { + "pr": "10599", + "title": "[FIX] Member list search with no results", + "userLogin": "ggazzo", + "milestone": "0.64.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10586", + "title": "Development: Add Visual Studio Code debugging configuration", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10576", + "title": "[FIX] Integrations with room data not having the usernames filled in", + "userLogin": "graywolf336", + "milestone": "0.64.0", + "contributors": [ + "graywolf336", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.64.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10660", + "title": "Release 0.64.1", + "userLogin": "rodrigok", + "milestone": "0.64.1", + "contributors": [ + "saplla", + "web-flow", + "engelgabriel", + "graywolf336", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10597", + "title": "[NEW] Store the last sent message to show bellow the room's name by default", + "userLogin": "graywolf336", + "milestone": "0.64.1", + "contributors": [ + "graywolf336", + "engelgabriel", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10529", + "title": "Support passing extra connection options to the Mongo driver", + "userLogin": "saplla", + "milestone": "0.64.1", + "contributors": [ + "saplla", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10615", + "title": "[FIX] E-mails were hidden some information", + "userLogin": "rodrigok", + "milestone": "0.64.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10611", + "title": "Regression: Updating an App on multi-instance servers wasn't working", + "userLogin": "graywolf336", + "milestone": "0.64.1", + "contributors": [ + "graywolf336", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10627", + "title": "[FIX] Regression on 0.64.0 was freezing the application when posting some URLs", + "userLogin": "rodrigok", + "milestone": "0.64.1", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10648", + "title": "Dependencies update", + "userLogin": "engelgabriel", + "milestone": "0.64.1", + "contributors": [ + "engelgabriel" + ] + } + ] + }, + "0.64.2-rc.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10736", + "title": "More improvements on send notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10720", + "title": "[FIX] Send a message when muted returns inconsistent result in chat.sendMessage", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10733", + "title": "[FIX] Regression: Empty content on announcement modal", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10607", + "title": "[NEW] Add REST endpoints `channels.roles` & `groups.roles`", + "userLogin": "cardoso", + "milestone": "0.64.2", + "contributors": [ + "cardoso", + "web-flow", + "rafaelks" + ] + }, + { + "pr": "10724", + "title": "[NEW] Add more options for Wordpress OAuth configuration", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10523", + "title": "[NEW] Setup Wizard", + "userLogin": "karlprieb", + "milestone": "0.64.2", + "contributors": [ + "karlprieb", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10691", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10686", + "title": "[NEW] Improvements to notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10705", + "title": "[FIX] Missing attachment description when Rocket.Chat Apps were enabled", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10445", + "title": "[FIX] Improve desktop notification formatting", + "userLogin": "Sameesunkaria", + "milestone": "0.64.2", + "contributors": [ + "Sameesunkaria", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10524", + "title": "Add `npm run postinstall` into example build script", + "userLogin": "peccu", + "milestone": "0.64.2", + "contributors": [ + "peccu", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10678", + "title": "[FIX] Message box emoji icon was flickering when typing a text", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10674", + "title": "Correct links in README file", + "userLogin": "winterstefan", + "milestone": "0.64.2", + "contributors": [ + "winterstefan" + ] + }, + { + "pr": "10665", + "title": "[FIX] Channel owner was being set as muted when creating a read-only channel", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10681", + "title": "[FIX] SAML wasn't working correctly when running multiple instances", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.64.2-rc.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10789", + "title": "Prometheus: Improve metric names", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10788", + "title": "Improvement to push notifications on direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10786", + "title": "Better metric for notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10779", + "title": "Add badge back to push notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10776", + "title": "Wizard improvements", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10766", + "title": "Add setting and expose prometheus on port 9100", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10760", + "title": "Regression: Fix notifications for direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.64.2-rc.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10798", + "title": "Prometheus: Add metric to track hooks time", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10802", + "title": "Regression: Autorun of wizard was not destroyed after completion", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10803", + "title": "Prometheus: Fix notification metric", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10804", + "title": "Regression: Fix wrong wizard field name", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10793", + "title": "[FIX] Not escaping special chars on mentions", + "userLogin": "erhan-", + "milestone": "0.64.2", + "contributors": [ + "erhan-", + "sampaiodiego" + ] + } + ] + }, + "0.64.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10812", + "title": "Release 0.64.2", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow", + "MarcosSpessatto", + "winterstefan", + "gdelavald", + "peccu", + "Sameesunkaria", + "sampaiodiego", + "engelgabriel", + "karlprieb", + "cardoso", + "erhan-" + ] + }, + { + "pr": "10798", + "title": "Prometheus: Add metric to track hooks time", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10802", + "title": "Regression: Autorun of wizard was not destroyed after completion", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10803", + "title": "Prometheus: Fix notification metric", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10804", + "title": "Regression: Fix wrong wizard field name", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10793", + "title": "[FIX] Not escaping special chars on mentions", + "userLogin": "erhan-", + "milestone": "0.64.2", + "contributors": [ + "erhan-", + "sampaiodiego" + ] + }, + { + "pr": "10789", + "title": "Prometheus: Improve metric names", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10788", + "title": "Improvement to push notifications on direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10786", + "title": "Better metric for notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10779", + "title": "Add badge back to push notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10776", + "title": "Wizard improvements", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10766", + "title": "Add setting and expose prometheus on port 9100", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10760", + "title": "Regression: Fix notifications for direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10736", + "title": "More improvements on send notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10720", + "title": "[FIX] Send a message when muted returns inconsistent result in chat.sendMessage", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10733", + "title": "[FIX] Regression: Empty content on announcement modal", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10607", + "title": "[NEW] Add REST endpoints `channels.roles` & `groups.roles`", + "userLogin": "cardoso", + "milestone": "0.64.2", + "contributors": [ + "cardoso", + "web-flow", + "rafaelks" + ] + }, + { + "pr": "10724", + "title": "[NEW] Add more options for Wordpress OAuth configuration", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10523", + "title": "[NEW] Setup Wizard", + "userLogin": "karlprieb", + "milestone": "0.64.2", + "contributors": [ + "karlprieb", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10691", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10686", + "title": "[NEW] Improvements to notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10705", + "title": "[FIX] Missing attachment description when Rocket.Chat Apps were enabled", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10445", + "title": "[FIX] Improve desktop notification formatting", + "userLogin": "Sameesunkaria", + "milestone": "0.64.2", + "contributors": [ + "Sameesunkaria", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10524", + "title": "Add `npm run postinstall` into example build script", + "userLogin": "peccu", + "milestone": "0.64.2", + "contributors": [ + "peccu", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10678", + "title": "[FIX] Message box emoji icon was flickering when typing a text", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10674", + "title": "Correct links in README file", + "userLogin": "winterstefan", + "milestone": "0.64.2", + "contributors": [ + "winterstefan" + ] + }, + { + "pr": "10665", + "title": "[FIX] Channel owner was being set as muted when creating a read-only channel", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10681", + "title": "[FIX] SAML wasn't working correctly when running multiple instances", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.65.0-rc.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10822", + "title": "Apps: Command Previews, Message and Room Removal Events", + "userLogin": "graywolf336", + "milestone": "0.65.0", + "contributors": [ + "graywolf336", + "rodrigok", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "9857", + "title": "[NEW] Implement a local password policy", + "userLogin": "graywolf336", + "milestone": "0.65.0", + "contributors": [ + "graywolf336", + "rodrigok" + ] + }, + { + "pr": "10663", + "title": "[FIX] Livechat managers were not being able to send messages in some cases", + "userLogin": "renatobecker", + "milestone": "0.65.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "10584", + "title": "[NEW] Options to enable/disable each Livechat registration form field", + "userLogin": "renatobecker", + "milestone": "0.65.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10612", + "title": "[FIX] Livechat settings not appearing correctly", + "userLogin": "renatobecker", + "milestone": "0.65.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "10677", + "title": "[NEW] Return the result of the `/me` endpoint within the result of the `/login` endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10815", + "title": "Develop sync", + "userLogin": "rodrigok", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336", + "nsuchy", + "rodrigok", + "rafaelks", + "sampaiodiego" + ] + }, + { + "pr": "10608", + "title": "[NEW] Lazy load image attachments", + "userLogin": "ggazzo", + "milestone": "0.65.0", + "contributors": [ + "ggazzo", + "web-flow", + "karlprieb", + "rodrigok" + ] + }, + { + "pr": "10427", + "title": "[FIX] Enabling `Collapse Embedded Media by Default` was hiding replies and quotes", + "userLogin": "c0dzilla", + "milestone": "0.65.0", + "contributors": [ + "c0dzilla" + ] + }, + { + "pr": "10214", + "title": "[NEW] View pinned message's attachment", + "userLogin": "c0dzilla", + "milestone": "0.65.0", + "contributors": [ + "c0dzilla", + "karlprieb", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "10704", + "title": "[FIX] Missing option to disable/enable System Messages", + "userLogin": "ggazzo", + "milestone": "0.65.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10448", + "title": "[FIX] Remove outdated translations of Internal Hubot's description of Scripts to Load that were pointing to a non existent address", + "userLogin": "Hudell", + "milestone": "0.65.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10661", + "title": "Major dependencies update", + "userLogin": "engelgabriel", + "milestone": "0.65.0", + "contributors": [ + "engelgabriel", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10702", + "title": "[NEW] Add REST API endpoint `users.getUsernameSuggestion` to get username suggestion", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10488", + "title": "[NEW] REST API endpoint `settings` now allow set colors and trigger actions", + "userLogin": "ThomasRoehl", + "milestone": "0.65.0", + "contributors": [ + "ThomasRoehl", + "MarcosSpessatto" + ] + }, + { + "pr": "10778", + "title": "[NEW] Add REST endpoint `subscriptions.unread` to mark messages as unread", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10662", + "title": "[NEW] REST API endpoint `/me` now returns all the settings, including the default values", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10741", + "title": "[NEW] Now is possible to access files using header authorization (`x-user-id` and `x-auth-token`)", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10564", + "title": "[FIX] UI was not disabling the actions when users has had no permissions to create channels or add users to rooms", + "userLogin": "chuckAtCataworx", + "milestone": "0.65.0", + "contributors": [ + "cfunkles", + "chuckAtCataworx", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "9679", + "title": "[NEW] Add REST API endpoints `channels.counters`, `groups.counters and `im.counters`", + "userLogin": "xbolshe", + "milestone": "0.65.0", + "contributors": [ + "xbolshe", + "MarcosSpessatto" + ] + }, + { + "pr": "9733", + "title": "[NEW] Add REST API endpoints `channels.setCustomFields` and `groups.setCustomFields`", + "userLogin": "xbolshe", + "milestone": "0.65.0", + "contributors": [ + "xbolshe", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10625", + "title": "[FIX] Private settings were not being cleared from client cache in some cases", + "userLogin": "Hudell", + "milestone": "0.65.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10811", + "title": "Prevent setup wizard redirects", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10798", + "title": "Prometheus: Add metric to track hooks time", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10802", + "title": "Regression: Autorun of wizard was not destroyed after completion", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10803", + "title": "Prometheus: Fix notification metric", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10804", + "title": "Regression: Fix wrong wizard field name", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10793", + "title": "[FIX] Not escaping special chars on mentions", + "userLogin": "erhan-", + "milestone": "0.64.2", + "contributors": [ + "erhan-", + "sampaiodiego" + ] + }, + { + "pr": "10789", + "title": "Prometheus: Improve metric names", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10788", + "title": "Improvement to push notifications on direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10786", + "title": "Better metric for notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10779", + "title": "Add badge back to push notifications", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10776", + "title": "Wizard improvements", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10766", + "title": "Add setting and expose prometheus on port 9100", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10760", + "title": "Regression: Fix notifications for direct messages", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10736", + "title": "More improvements on send notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10720", + "title": "[FIX] Send a message when muted returns inconsistent result in chat.sendMessage", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10733", + "title": "[FIX] Regression: Empty content on announcement modal", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10607", + "title": "[NEW] Add REST endpoints `channels.roles` & `groups.roles`", + "userLogin": "cardoso", + "milestone": "0.64.2", + "contributors": [ + "cardoso", + "web-flow", + "rafaelks" + ] + }, + { + "pr": "10724", + "title": "[NEW] Add more options for Wordpress OAuth configuration", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10523", + "title": "[NEW] Setup Wizard", + "userLogin": "karlprieb", + "milestone": "0.64.2", + "contributors": [ + "karlprieb", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10691", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.64.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10686", + "title": "[NEW] Improvements to notifications logic", + "userLogin": "sampaiodiego", + "milestone": "0.64.2", + "contributors": [ + "sampaiodiego", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10705", + "title": "[FIX] Missing attachment description when Rocket.Chat Apps were enabled", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10445", + "title": "[FIX] Improve desktop notification formatting", + "userLogin": "Sameesunkaria", + "milestone": "0.64.2", + "contributors": [ + "Sameesunkaria", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10524", + "title": "Add `npm run postinstall` into example build script", + "userLogin": "peccu", + "milestone": "0.64.2", + "contributors": [ + "peccu", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10678", + "title": "[FIX] Message box emoji icon was flickering when typing a text", + "userLogin": "gdelavald", + "milestone": "0.64.2", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10674", + "title": "Correct links in README file", + "userLogin": "winterstefan", + "milestone": "0.64.2", + "contributors": [ + "winterstefan" + ] + }, + { + "pr": "10665", + "title": "[FIX] Channel owner was being set as muted when creating a read-only channel", + "userLogin": "MarcosSpessatto", + "milestone": "0.64.2", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10681", + "title": "[FIX] SAML wasn't working correctly when running multiple instances", + "userLogin": "Hudell", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10812", + "title": "Release 0.64.2", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow", + "MarcosSpessatto", + "winterstefan", + "gdelavald", + "peccu", + "Sameesunkaria", + "sampaiodiego", + "engelgabriel", + "karlprieb", + "cardoso", + "erhan-" + ] + }, + { + "pr": "10660", + "title": "Release 0.64.1", + "userLogin": "rodrigok", + "milestone": "0.64.1", + "contributors": [ + "saplla", + "web-flow", + "engelgabriel", + "graywolf336", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10613", + "title": "Release 0.64.0", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "web-flow", + "graywolf336", + "TwizzyDizzy", + "christianh814", + "tttt-conan", + "gdelavald", + "ggazzo" + ] + }, + { + "pr": "10504", + "title": "Release 0.63.3", + "userLogin": "graywolf336", + "contributors": [ + "rafaelks", + "graywolf336" + ] + }, + { + "pr": "10476", + "title": "Release 0.63.2", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10408", + "title": "add redhat dockerfile to master", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.65.0-rc.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10837", + "title": "[FIX] Internal Error when requesting user data download", + "userLogin": "Hudell", + "milestone": "0.65.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10835", + "title": "[FIX] Broadcast channels were showing reply button for deleted messages and generating wrong reply links some times", + "userLogin": "ggazzo", + "milestone": "0.65.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10833", + "title": "Fix: Regression in REST API endpoint `/me` ", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10734", + "title": "[FIX] User's preference `Unread on Top` wasn't working for LiveChat rooms", + "userLogin": "renatobecker", + "milestone": "0.65.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10753", + "title": "[NEW] Add permission `view-broadcast-member-list`", + "userLogin": "cardoso", + "milestone": "0.65.0", + "contributors": [ + "cardoso", + "web-flow" + ] + }, + { + "pr": "10715", + "title": "[FIX] Cancel button wasn't working while uploading file", + "userLogin": "Mr-Gryphon", + "milestone": "0.65.0", + "contributors": [ + "Mr-Gryphon", + "web-flow", + "karlprieb" + ] + } + ] + }, + "0.65.0-rc.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10847", + "title": "Regression: Fix email notification preference not showing correct selected value", + "userLogin": "sampaiodiego", + "milestone": "0.65.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10853", + "title": "Apps: Command previews are clickable & Apps Framework is controlled via a setting", + "userLogin": "graywolf336", + "milestone": "0.65.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "10840", + "title": "[FIX] Missing pagination fields in the response of REST /directory endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.65.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10846", + "title": "[FIX] Layout badge cutting on unread messages for long names", + "userLogin": "kos4live", + "milestone": "0.65.0", + "contributors": [ + "kos4live" + ] + }, + { + "pr": "10848", + "title": "Regression: Make settings `Site_Name` and `Language` public again", + "userLogin": "rodrigok", + "milestone": "0.65.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10520", + "title": "Fix: Clarify the wording of the release issue template", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10836", + "title": "Fix: Regression on users avatar in admin pages", + "userLogin": "ggazzo", + "milestone": "0.65.0", + "contributors": [ + "ggazzo", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.65.0-rc.3": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10875", + "title": "[FIX] Slack-Bridge bug when migrating to 0.64.1", + "userLogin": "iliaal", + "milestone": "0.65.0", + "contributors": [ + null + ] + }, + { + "pr": "10882", + "title": "Fix: Manage apps layout was a bit confuse", + "userLogin": "gdelavald", + "milestone": "0.65.0", + "contributors": [ + "gdelavald", + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "10886", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.65.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10887", + "title": "Fix: Regression Lazyload fix shuffle avatars", + "userLogin": "ggazzo", + "milestone": "0.65.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10883", + "title": "[FIX] Horizontally align items in preview message", + "userLogin": "gdelavald", + "milestone": "0.65.0", + "contributors": [ + "gdelavald" + ] + }, + { + "pr": "10857", + "title": "Fix: typo on error message for push token API", + "userLogin": "rafaelks", + "milestone": "0.65.0", + "contributors": [ + "rafaelks", + "web-flow" + ] + }, + { + "pr": "10878", + "title": "[FIX] The first users was not set as admin some times", + "userLogin": "rodrigok", + "milestone": "0.65.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.65.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10893", + "title": "Release 0.65.0", + "userLogin": "rodrigok", + "milestone": "0.65.0", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow", + "MarcosSpessatto", + "winterstefan", + "gdelavald", + "peccu", + "Sameesunkaria", + "sampaiodiego", + "engelgabriel", + "karlprieb", + "cardoso", + "erhan-" + ] + }, + { + "pr": "10812", + "title": "Release 0.64.2", + "userLogin": "rodrigok", + "milestone": "0.64.2", + "contributors": [ + "Hudell", + "rodrigok", + "web-flow", + "MarcosSpessatto", + "winterstefan", + "gdelavald", + "peccu", + "Sameesunkaria", + "sampaiodiego", + "engelgabriel", + "karlprieb", + "cardoso", + "erhan-" + ] + }, + { + "pr": "10660", + "title": "Release 0.64.1", + "userLogin": "rodrigok", + "milestone": "0.64.1", + "contributors": [ + "saplla", + "web-flow", + "engelgabriel", + "graywolf336", + "rodrigok", + "sampaiodiego" + ] + }, + { + "pr": "10613", + "title": "Release 0.64.0", + "userLogin": "rodrigok", + "milestone": "0.64.0", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "web-flow", + "graywolf336", + "TwizzyDizzy", + "christianh814", + "tttt-conan", + "gdelavald", + "ggazzo" + ] + }, + { + "pr": "10504", + "title": "Release 0.63.3", + "userLogin": "graywolf336", + "contributors": [ + "rafaelks", + "graywolf336" + ] + }, + { + "pr": "10476", + "title": "Release 0.63.2", + "userLogin": "graywolf336", + "contributors": [ + "graywolf336", + "web-flow" + ] + }, + { + "pr": "10408", + "title": "add redhat dockerfile to master", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.65.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10940", + "title": "[FIX] Livechat not loading", + "userLogin": "sampaiodiego", + "milestone": "0.65.1", + "contributors": [ + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "10934", + "title": "[FIX] Application crashing on startup when trying to log errors to `exceptions` channel", + "userLogin": "sampaiodiego", + "milestone": "0.65.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10928", + "title": "[FIX] Incomplete email notification link", + "userLogin": "sampaiodiego", + "milestone": "0.65.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10904", + "title": "[FIX] Image lazy load was breaking attachments", + "userLogin": "ggazzo", + "milestone": "0.65.1", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10851", + "title": "[FIX] Leave room wasn't working as expected", + "userLogin": "ggazzo", + "milestone": "0.65.1", + "contributors": [ + "ggazzo" + ] + } + ] + }, + "0.65.2": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "9534", + "title": "[FIX] i18n - add semantic markup", + "userLogin": "brylie", + "contributors": [ + "brylie", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10947", + "title": "Release 0.65.1", + "userLogin": "sampaiodiego", + "contributors": [ + "rodrigok", + "sampaiodiego", + "engelgabriel" + ] + } + ] + }, + "HEAD": { + "pull_requests": [] + }, + "0.66.0-rc.0": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11166", + "title": "[IMPROVE] Listing of apps in the admin page", + "userLogin": "gdelavald", + "milestone": "0.66.0", + "contributors": [ + "karlprieb", + "web-flow", + "gdelavald", + "engelgabriel" + ] + }, + { + "pr": "11206", + "title": "Regression: Directory css", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "karlprieb", + "ggazzo" + ] + }, + { + "pr": "11208", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10127", + "title": "[NEW] Youtube Broadcasting", + "userLogin": "gdelavald", + "milestone": "0.66.0", + "contributors": [ + "gdelavald", + "ggazzo" + ] + }, + { + "pr": "11187", + "title": "[FIX] Wordpress oauth configuration not loading properly", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "Hudell", + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "10975", + "title": "[NEW] REST API endpoints `permissions.list` and `permissions.update`. Deprecated endpoint `permissions`", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow" + ] + }, + { + "pr": "10941", + "title": "[NEW] REST API endpoint `channels.setDefault`", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10113", + "title": "IRC Federation: RFC2813 implementation (ngIRCd)", + "userLogin": "alansikora", + "milestone": "0.66.0", + "contributors": [ + "cpitman", + "lindoelio", + "alansikora", + "Hudell", + "web-flow" + ] + }, + { + "pr": "10999", + "title": "[FIX] REST API: Add more test cases for `/login`", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11191", + "title": "[FIX] Wrong font-family order", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "myfonj", + "web-flow", + "engelgabriel", + "Hudell" + ] + }, + { + "pr": "11008", + "title": "Add verification to make sure the user exists in REST insert object helper", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10799", + "title": "[BREAK] Always remove the field `services` from user data responses in REST API", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11204", + "title": "[FIX] REST endpoint `users.updateOwnBasicInfo` was not returning errors for invalid names and trying to save custom fields when empty", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "9751", + "title": "[NEW] Set Document Domain property in IFrame", + "userLogin": "kb0304", + "milestone": "0.66.0", + "contributors": [ + "kb0304", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10767", + "title": "[FIX] Livechat visitor not being prompted for transcript when himself is closing the chat", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11188", + "title": "[FIX] HipChat Cloud import fails to import rooms", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11190", + "title": "[FIX] Failure to download user data", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10447", + "title": "[FIX] Add parameter to REST chat.react endpoint, to make it work like a setter", + "userLogin": "MarcosSpessatto", + "contributors": [ + "MarcosSpessatto", + "ggazzo" + ] + }, + { + "pr": "11025", + "title": "[NEW] Custom login wallpapers", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11200", + "title": "Regression: Directory user table infinite scroll doesn't working", + "userLogin": "karlprieb", + "milestone": "0.66.0", + "contributors": [ + "karlprieb" + ] + }, + { + "pr": "10205", + "title": "[NEW] Support for dynamic slack and rocket.chat channels", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "kable-wilmoth", + "Hudell", + "web-flow" + ] + }, + { + "pr": "11150", + "title": "[FIX] Default selected language", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11026", + "title": "[IMPROVE] UI design for Tables and tabs component on Directory", + "userLogin": "karlprieb", + "milestone": "0.66.0", + "contributors": [ + "karlprieb", + "web-flow", + "engelgabriel", + "ggazzo" + ] + }, + { + "pr": "11165", + "title": "[FIX] Rendering of emails and mentions in messages", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11177", + "title": "[FIX] Livechat icon with status", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11183", + "title": "[FIX] remove sidebar on embedded view", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11173", + "title": "[FIX]Missing language constants", + "userLogin": "rw4lll", + "contributors": [ + "rw4lll", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11181", + "title": "[FIX Readme] Nodejs + Python version spicifications", + "userLogin": "mahdiyari", + "contributors": [ + "mahdiyari", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "11178", + "title": "[FIX] Room creation error due absence of subscriptions", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11132", + "title": "[FIX] Remove failed upload messages when switching rooms", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11152", + "title": "[FIX] Wordpress OAuth not providing enough info to log in ", + "userLogin": "Hudell", + "contributors": [ + "Hudell", + "sampaiodiego" + ] + }, + { + "pr": "11010", + "title": "[FIX] /groups.invite not allow a user to invite even with permission", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto", + "Hudell", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11115", + "title": "[NEW] Add prometheus port config", + "userLogin": "thaiphv", + "contributors": [ + "brylie", + "web-flow", + "stuartpb", + "engelgabriel", + "thaiphv" + ] + }, + { + "pr": "10095", + "title": "[FIX] Various lang fixes [RU]", + "userLogin": "rw4lll", + "milestone": "0.66.0", + "contributors": [ + "rw4lll", + "web-flow", + "engelgabriel", + "ggazzo" + ] + }, + { + "pr": "11109", + "title": "[FIX] set-toolbar-items postMessage", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "web-flow", + "tassoevan" + ] + }, + { + "pr": "11021", + "title": "[FIX] title and value attachments are optionals on sendMessage method", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10301", + "title": "[NEW] Button to remove closed LiveChat rooms", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "11136", + "title": "[FIX] Some typos in the error message names", + "userLogin": "vynmera", + "contributors": [ + "vynmera" + ] + }, + { + "pr": "11050", + "title": "[FIX] open conversation from room info", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "11129", + "title": "[FIX] Users model was not receiving options", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11113", + "title": "[FIX] Popover position", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11096", + "title": "[FIX] Generated random password visible to the user", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11111", + "title": "[FIX] LiveChat appearance changes not being saved", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11095", + "title": "[FIX] Confirm password on set new password user profile", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11090", + "title": "Regression: sorting direct message by asc on favorites group", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10431", + "title": "[FIX] Message_AllowedMaxSize fails for emoji sequences", + "userLogin": "c0dzilla", + "milestone": "0.66.0", + "contributors": [ + "c0dzilla", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11001", + "title": "[IMPROVE] User mentions", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11107", + "title": "Fix PR Docker image creation by splitting in two build jobs", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8402", + "title": "[NEW] Update katex to v0.9.0", + "userLogin": "pitamar", + "milestone": "0.66.0", + "contributors": [ + "pitamar" + ] + }, + { + "pr": "11027", + "title": "[NEW] WebDAV(Nextcloud/ownCloud) Storage Server Option", + "userLogin": "karakayasemi", + "milestone": "0.66.0", + "contributors": [ + "karakayasemi", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11103", + "title": "Update v126.js", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10973", + "title": "[NEW] Don't ask me again checkbox on hide room modal", + "userLogin": "karlprieb", + "milestone": "0.66.0", + "contributors": [ + "karlprieb", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11097", + "title": "Speed up the build time by removing JSON Minify from i18n package", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "10958", + "title": "[NEW] Add input to set time for avatar cache control", + "userLogin": "MarcosSpessatto", + "milestone": "0.66.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10727", + "title": "[NEW] Command /hide to hide channels", + "userLogin": "mikaelmello", + "milestone": "0.66.0", + "contributors": [ + "mikaelmello", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11089", + "title": "[FIX] Can't access the `/account/profile`", + "userLogin": "tassoevan", + "milestone": "0.66.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11087", + "title": "[NEW] Do not wait method calls response on websocket before next method call", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "11086", + "title": "[NEW] Disconnect users from websocket when away from the login screen for 10min", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11083", + "title": "[NEW] Reduce the amount of DDP API calls on login screen", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok", + "web-flow" + ] + }, + { + "pr": "11093", + "title": "Fix Docker image for develop commits", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11085", + "title": "[NEW] Option to trace Methods and Subscription calls", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11084", + "title": "[FIX] Idle time limit wasn’t working as expected", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11076", + "title": "Build Docker image on CI", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "9959", + "title": "[FIX] Rooms list sorting by activity multiple re-renders and case sensitive sorting alphabetically", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "sampaiodiego", + "web-flow", + "karlprieb", + "JoseRenan" + ] + }, + { + "pr": "11024", + "title": "[FIX] Notification not working for group mentions and not respecting ignored users", + "userLogin": "sampaiodiego", + "milestone": "0.66.0", + "contributors": [ + "sampaiodiego", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "10294", + "title": "[FIX] Overlapping of search text and cancel search icon (X)", + "userLogin": "taeven", + "milestone": "0.66.0", + "contributors": [ + "taeven", + "rodrigok", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "11063", + "title": "[FIX] Link previews not being removed from messages after removed on editing", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11074", + "title": "[FIX] avoid send presence without login", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11072", + "title": "[FIX] Exception in metrics generation", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11070", + "title": "Update issue templates", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11062", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11056", + "title": "[FIX] Build for Sandstorm missing dependence for capnp", + "userLogin": "peterlee0127", + "contributors": [ + "peterlee0127" + ] + }, + { + "pr": "11049", + "title": "[FIX] flex-tab icons missing", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11054", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11053", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11051", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11045", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11044", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11043", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "11042", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "9969", + "title": "Changed 'confirm password' placeholder text on user registration form", + "userLogin": "kumarnitj", + "milestone": "0.66.0", + "contributors": [ + null, + "kumarnitj", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11020", + "title": "[FIX] Update ja.i18n.json", + "userLogin": "noobbbbb", + "contributors": [ + "noobbbbb", + "web-flow", + "Hudell" + ] + }, + { + "pr": "11039", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + null, + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11035", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "engelgabriel" + ] + }, + { + "pr": "10954", + "title": "[NEW] Replace variable 'mergeChannels' with 'groupByType'.", + "userLogin": "mikaelmello", + "milestone": "0.66.0", + "contributors": [ + "mikaelmello", + "rodrigok", + "web-flow", + "ggazzo", + "engelgabriel" + ] + }, + { + "pr": "11012", + "title": "[FIX] Strange msg when setting room announcement, topic or description to be empty", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow" + ] + }, + { + "pr": "11009", + "title": "[FIX] Exception thrown on avatar validation", + "userLogin": "Hudell", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "10091", + "title": "[NEW] Send LiveChat visitor navigation history as messages", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + }, + { + "pr": "10673", + "title": "[NEW] Make supplying an AWS access key and secret optional for S3 uploads", + "userLogin": "saplla", + "milestone": "0.66.0", + "contributors": [ + "saplla", + "web-flow" + ] + }, + { + "pr": "10207", + "title": "Update Documentation: README.md", + "userLogin": "rakhi2104", + "contributors": [ + "rakhi2104", + "web-flow" + ] + }, + { + "pr": "10998", + "title": "[FIX] Preview of large images not resizing to fit the area and having scrollbars", + "userLogin": "vynmera", + "milestone": "0.66.0", + "contributors": [ + "vynmera", + "web-flow" + ] + }, + { + "pr": "10956", + "title": "[FIX] Allow inviting livechat managers to the same LiveChat room", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + }, + { + "pr": "10913", + "title": "NPM Dependencies Update", + "userLogin": "engelgabriel", + "milestone": "0.66.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10805", + "title": "[FIX] Cannot read property 'debug' of undefined when trying to use REST API", + "userLogin": "haffla", + "milestone": "0.66.0", + "contributors": [ + "haffla", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10131", + "title": "update meteor to 1.6.1 for sandstorm build", + "userLogin": "peterlee0127", + "contributors": [ + "peterlee0127", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "10986", + "title": "Renaming username.username to username.value for clarity", + "userLogin": "engelgabriel", + "milestone": "0.66.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10988", + "title": "[NEW] Direct Reply: separate Reply-To email from account username field", + "userLogin": "engelgabriel", + "milestone": "0.66.0", + "contributors": [ + "pkgodara", + "web-flow", + "engelgabriel" + ] + }, + { + "pr": "5", + "title": "Fix readme typo", + "userLogin": "filipealva", + "contributors": [ + "filipealva" + ] + }, + { + "pr": "10055", + "title": "[NEW] Changes all 'mergeChannels' to 'groupByType'.", + "userLogin": "mikaelmello", + "milestone": "0.66.0", + "contributors": [ + "mikaelmello", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10771", + "title": "[FIX] Icons svg xml structure", + "userLogin": "timkinnane", + "contributors": [ + "timkinnane" + ] + }, + { + "pr": "10851", + "title": "[FIX] Leave room wasn't working as expected", + "userLogin": "ggazzo", + "milestone": "0.65.1", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10807", + "title": "Remove wrong and not needed time unit", + "userLogin": "cliffparnitzky", + "contributors": [ + "cliffparnitzky" + ] + }, + { + "pr": "10934", + "title": "[FIX] Application crashing on startup when trying to log errors to `exceptions` channel", + "userLogin": "sampaiodiego", + "milestone": "0.65.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10904", + "title": "[FIX] Image lazy load was breaking attachments", + "userLogin": "ggazzo", + "milestone": "0.65.1", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "10928", + "title": "[FIX] Incomplete email notification link", + "userLogin": "sampaiodiego", + "milestone": "0.65.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10916", + "title": "[FIX] Remove outdated 2FA warning for mobile clients", + "userLogin": "cardoso", + "contributors": [ + "cardoso" + ] + }, + { + "pr": "10841", + "title": "[NEW] Update WeDeploy deployment", + "userLogin": "jonnilundy", + "contributors": [ + "jonnilundy", + "web-flow" + ] + }, + { + "pr": "10867", + "title": "[FIX] Update Sandstorm build config", + "userLogin": "ocdtrekkie", + "contributors": [ + "ocdtrekkie", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "10909", + "title": "Develop sync commits", + "userLogin": "rodrigok", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336", + "nsuchy", + "rodrigok", + "rafaelks", + "sampaiodiego" + ] + }, + { + "pr": "10908", + "title": "Develop sync2", + "userLogin": "rodrigok", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336", + "nsuchy", + "rodrigok", + "rafaelks", + "sampaiodiego" + ] + }, + { + "pr": "10903", + "title": "Merge master into develop & Set version to 0.66.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "geekgonecrazy", + "web-flow", + "graywolf336", + "nsuchy", + "rodrigok", + "rafaelks", + "sampaiodiego" + ] + }, + { + "pr": "9534", + "title": "[FIX] i18n - add semantic markup", + "userLogin": "brylie", + "contributors": [ + "brylie", + "web-flow", + "engelgabriel" + ] + } + ] + }, + "0.66.0-rc.1": { + "node_version": "8.11.1", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11223", + "title": "Regression: Fix directory table loading", + "userLogin": "karlprieb", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "karlprieb" + ] + }, + { + "pr": "11221", + "title": "[FIX] \"blank messages\" on iOS < 11", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "11215", + "title": "Regression: Fix latest and release-candidate docker images building", + "userLogin": "sampaiodiego", + "milestone": "0.66.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11199", + "title": "[FIX] \"blank\" screen on iOS < 11", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "11216", + "title": "Regression: check username or usersCount on browseChannels", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11211", + "title": "Regression: Sending message with a mention is not showing to sender", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.66.0-rc.2": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11249", + "title": "Regression: Prometheus was not being enabled in some cases", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11232", + "title": "Regression: Skip operations if no actions on livechat migration", + "userLogin": "sampaiodiego", + "milestone": "0.66.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11224", + "title": "Regression: Directory sort users, fix null results, text for empty results", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11246", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11247", + "title": "Update Meteor to 1.6.1.3", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11237", + "title": "New history source format & add Node and NPM versions", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + } + ] + }, + "0.66.0-rc.3": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10971", + "title": "Add Dockerfile with MongoDB", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok", + "engelgabriel", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "11253", + "title": "[FIX] The process was freezing in some cases when HTTP calls exceeds timeout on integrations", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11264", + "title": "[FIX] LDAP was accepting login with empty passwords for certain AD configurations", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11263", + "title": "[FIX] Update capnproto dependence for Sandstorm Build", + "userLogin": "peterlee0127", + "contributors": [ + "peterlee0127" + ] + }, + { + "pr": "11257", + "title": "[FIX] Internal Server Error on first login with CAS integration", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "Hudell" + ] + } + ] + }, + "0.66.0-rc.4": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11268", + "title": "[FIX] Armhf snap build", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy", + "web-flow", + "rodrigok" + ] + }, + { + "pr": "11273", + "title": "Regression: sidebar sorting was being wrong in some cases where the rooms records were returned before the subscriptions", + "userLogin": "ggazzo", + "milestone": "0.66.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11276", + "title": "[FIX] Reaction Toggle was not working when omitting the last parameter from the API (DDP and REST)", + "userLogin": "Hudell", + "milestone": "0.66.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11271", + "title": "Fix Docker image build on tags", + "userLogin": "sampaiodiego", + "milestone": "0.66.0", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.66.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11277", + "title": "Merge master into develop & Set version to 0.66.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "brylie", + "web-flow", + "stuartpb", + "engelgabriel", + "Hudell", + "sampaiodiego", + "rodrigok" + ] + }, + { + "pr": "9534", + "title": "[FIX] i18n - add semantic markup", + "userLogin": "brylie", + "contributors": [ + "brylie", + "web-flow", + "engelgabriel" + ] + } + ] + }, + "0.66.1": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11335", + "title": "[FIX] Some updates were returning errors when based on queries with position operators", + "userLogin": "rodrigok", + "milestone": "0.66.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11315", + "title": "[FIX] SAML attributes with periods are not properly read.", + "userLogin": "Hudell", + "milestone": "0.66.1", + "contributors": [ + "Hudell", + "web-flow" + ] + }, + { + "pr": "11333", + "title": "[FIX] Outgoing integrations were stopping the oplog tailing sometimes", + "userLogin": "rodrigok", + "milestone": "0.66.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11254", + "title": "[IMPROVE] Setup Wizard username validation, step progress and optin/optout", + "userLogin": "tassoevan", + "milestone": "0.66.1", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11267", + "title": "[FIX] Livestream muted when audio only option was enabled", + "userLogin": "gdelavald", + "milestone": "0.66.1", + "contributors": [ + "gdelavald", + "web-flow" + ] + }, + { + "pr": "11295", + "title": "[FIX] Notification preferences being lost when switching view mode", + "userLogin": "sampaiodiego", + "milestone": "0.66.1", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.66.2": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11359", + "title": "Send setting Allow_Marketing_Emails to statistics collector", + "userLogin": "rodrigok", + "milestone": "0.66.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11364", + "title": "Regression: Fix migration 125 checking for settings field", + "userLogin": "sampaiodiego", + "milestone": "0.66.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11365", + "title": "[FIX] Remove file snap store doesn't like", + "userLogin": "geekgonecrazy", + "milestone": "0.66.2", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "11266", + "title": "[FIX] Livechat not sending desktop notifications", + "userLogin": "renatobecker", + "milestone": "0.66.2", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + } + ] + }, + "0.66.3": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11398", + "title": "[FIX] All messages notifications via email were sent as mention alert", + "userLogin": "rodrigok", + "milestone": "0.66.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11406", + "title": "[FIX] Livechat taking inquiry leading to 404 page", + "userLogin": "renatobecker", + "milestone": "0.66.3", + "contributors": [ + "renatobecker" + ] + } + ] + }, + "0.67.0-rc.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "10749", + "title": "[BREAK] Remove cache layer and internal calculated property `room.usernames`", + "userLogin": "rodrigok", + "milestone": "0.66.0", + "contributors": [ + "rodrigok", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11417", + "title": "Merge master into develop & Set version to 0.67.0-develop", + "userLogin": "sampaiodiego", + "contributors": [ + "renatobecker", + "sampaiodiego", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "11406", + "title": "[FIX] Livechat taking inquiry leading to 404 page", + "userLogin": "renatobecker", + "milestone": "0.66.3", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "11398", + "title": "[FIX] All messages notifications via email were sent as mention alert", + "userLogin": "rodrigok", + "milestone": "0.66.3", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11358", + "title": "[FIX] sort fname sidenav", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11399", + "title": "Merge master into develop & Set version to 0.67.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "geekgonecrazy", + "renatobecker", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "10918", + "title": "[NEW] Additional Livechat iFrame API's", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11266", + "title": "[FIX] Livechat not sending desktop notifications", + "userLogin": "renatobecker", + "milestone": "0.66.2", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + }, + { + "pr": "11319", + "title": "[FIX] SVG icons code", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11365", + "title": "[FIX] Remove file snap store doesn't like", + "userLogin": "geekgonecrazy", + "milestone": "0.66.2", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "11364", + "title": "Regression: Fix migration 125 checking for settings field", + "userLogin": "sampaiodiego", + "milestone": "0.66.2", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11359", + "title": "Send setting Allow_Marketing_Emails to statistics collector", + "userLogin": "rodrigok", + "milestone": "0.66.2", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11313", + "title": "[FIX] Message popup responsiveness in slash commands", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "9991", + "title": "[FIX] web app manifest errors as reported by Chrome DevTools", + "userLogin": "justinribeiro", + "milestone": "0.68.0", + "contributors": [ + "justinribeiro", + "web-flow" + ] + }, + { + "pr": "11342", + "title": "[FIX] Message attachment's fields with different sizes", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11330", + "title": "[IMPROVE] Stop sort callbacks on run", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "9754", + "title": "[FIX] Parse inline code without space before initial backtick", + "userLogin": "c0dzilla", + "milestone": "0.68.0", + "contributors": [ + "c0dzilla", + "gdelavald", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11348", + "title": "Merge master into develop & Set version to 0.67.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "sampaiodiego", + "rodrigok", + "gdelavald", + "tassoevan", + "Hudell", + "web-flow" + ] + }, + { + "pr": "11335", + "title": "[FIX] Some updates were returning errors when based on queries with position operators", + "userLogin": "rodrigok", + "milestone": "0.66.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11315", + "title": "[FIX] SAML attributes with periods are not properly read.", + "userLogin": "Hudell", + "milestone": "0.66.1", + "contributors": [ + "Hudell", + "web-flow" + ] + }, + { + "pr": "11333", + "title": "[FIX] Outgoing integrations were stopping the oplog tailing sometimes", + "userLogin": "rodrigok", + "milestone": "0.66.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11254", + "title": "[IMPROVE] Setup Wizard username validation, step progress and optin/optout", + "userLogin": "tassoevan", + "milestone": "0.66.1", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11267", + "title": "[FIX] Livestream muted when audio only option was enabled", + "userLogin": "gdelavald", + "milestone": "0.66.1", + "contributors": [ + "gdelavald", + "web-flow" + ] + }, + { + "pr": "11295", + "title": "[FIX] Notification preferences being lost when switching view mode", + "userLogin": "sampaiodiego", + "milestone": "0.66.1", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11290", + "title": "Merge master into develop & Set version to 0.67.0-develop", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.67.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11497", + "title": "Fix dependency issue in redhat image", + "userLogin": "geekgonecrazy", + "contributors": [ + "geekgonecrazy" + ] + } + ] + }, + "0.68.0-rc.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11328", + "title": "[NEW] Setting to disable 2FA globally", + "userLogin": "Hudell", + "contributors": [ + "Hudell", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11524", + "title": "[FIX] New favicons size too small", + "userLogin": "brunosquadros", + "contributors": [ + "brunosquadros", + "web-flow" + ] + }, + { + "pr": "11534", + "title": "[FIX] Render reply preview with message as a common message", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11537", + "title": "Revert: Mixed case channel slugs #9449", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11536", + "title": "Merge master into develop & Set version to 0.68.0-develop", + "userLogin": "sampaiodiego", + "contributors": [ + "rodrigok", + "geekgonecrazy", + "engelgabriel", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11531", + "title": "[FIX] Unreads counter for new rooms on /channels.counters REST endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11488", + "title": "[NEW] Add /users.deleteOwnAccount REST endpoint to an user delete his own account", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11357", + "title": "[FIX] Marked parser breaking announcements and mentions at the start of messages", + "userLogin": "vynmera", + "contributors": [ + "vynmera" + ] + }, + { + "pr": "11500", + "title": "[NEW] Add /roles.list REST endpoint to retrieve all server roles", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10731", + "title": "[FIX] Send Livechat back to Guest Pool", + "userLogin": "renatobecker", + "milestone": "0.68.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11496", + "title": "[FIX] Add customFields property to /me REST endpoint response", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11507", + "title": "[FIX] Invalid permalink URLs for Direct Messages", + "userLogin": "Hudell", + "contributors": [ + "Hudell", + "sampaiodiego" + ] + }, + { + "pr": "11471", + "title": "[FIX] Unlimited upload file size not working", + "userLogin": "Hudell", + "milestone": "0.68.0", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11493", + "title": "[BREAK] Remove deprecated /user.roles endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11423", + "title": "Regression: Add missing LiveChat permission to allow removing closed rooms", + "userLogin": "renatobecker", + "milestone": "0.68.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "9449", + "title": "[FIX] Mixed case channel slugs", + "userLogin": "soundstorm", + "milestone": "0.68.0", + "contributors": [ + "soundstorm", + "web-flow" + ] + }, + { + "pr": "11135", + "title": "[FIX] SAML issues", + "userLogin": "Hudell", + "milestone": "0.68.0", + "contributors": [ + "arminfelder", + "web-flow", + "engelgabriel", + "Hudell" + ] + }, + { + "pr": "11363", + "title": "[FIX] Loading and setting fixes for i18n and RTL", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11527", + "title": "[FIX] Check for channels property on message object before parsing mentions", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11526", + "title": "[FIX] empty blockquote", + "userLogin": "ggazzo", + "milestone": "0.68.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11514", + "title": "[FIX] Snap font issue for sharp", + "userLogin": "geekgonecrazy", + "milestone": "0.68.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "11236", + "title": "[NEW] Message retention policy and pruning", + "userLogin": "vynmera", + "contributors": [ + "vynmera", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11327", + "title": "[IMPROVE] Set default max upload size to 100mb", + "userLogin": "cardoso", + "milestone": "0.68.0", + "contributors": [ + "cardoso", + "web-flow" + ] + }, + { + "pr": "11499", + "title": "Update release issue template to use Houston CLI", + "userLogin": "rodrigok", + "milestone": "0.68.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11508", + "title": "Regression: Remove safe area margins from logos", + "userLogin": "brunosquadros", + "contributors": [ + "brunosquadros", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "11164", + "title": "[IMPROVE] Typing indicators now use Real Names", + "userLogin": "vynmera", + "milestone": "0.68.0", + "contributors": [ + "vynmera", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11487", + "title": "[FIX] RocketChat.settings.get causing memory leak (sometimes)", + "userLogin": "ggazzo", + "milestone": "0.68.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11430", + "title": "[BREAK] Update GraphQL dependencies", + "userLogin": "engelgabriel", + "milestone": "0.68.0", + "contributors": [ + "engelgabriel", + "MarcosSpessatto", + "web-flow" + ] + }, + { + "pr": "11303", + "title": "[NEW] Send user status to client", + "userLogin": "HappyTobi", + "contributors": [ + "HappyTobi", + "web-flow" + ] + }, + { + "pr": "11486", + "title": "[NEW] Room files search form", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11441", + "title": "[FIX] Refinements in message popup mentions", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "10017", + "title": "[NEW] search only default tone emoji Popup search", + "userLogin": "Joe-mcgee", + "milestone": "0.68.0", + "contributors": [ + "Joe-mcgee", + "web-flow", + "engelgabriel", + "ggazzo" + ] + }, + { + "pr": "11332", + "title": "[NEW] Privacy for custom user fields", + "userLogin": "vynmera", + "contributors": [ + "vynmera", + "ggazzo" + ] + }, + { + "pr": "11450", + "title": "[FIX] Decrease room leader bar z-index", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11491", + "title": "[NEW] Replaced old logo with the new ones", + "userLogin": "brunosquadros", + "contributors": [ + "brunosquadros", + "web-flow" + ] + }, + { + "pr": "9972", + "title": "[NEW] Sorting channels by number of users in directory", + "userLogin": "arungalva", + "milestone": "0.68.0", + "contributors": [ + "arungalva", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11408", + "title": "[IMPROVE] Allow markdown in room topic, announcement, and description including single quotes", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11298", + "title": "[FIX] Remove title attribute from sidebar items", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11459", + "title": "[FIX] Only escape HTML from details in toast error messages", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11462", + "title": "[FIX] broadcast channel reply", + "userLogin": "ggazzo", + "milestone": "0.68.0", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11416", + "title": "[FIX] Fixed svg for older chrome browsers bug #11414", + "userLogin": "tpDBL", + "milestone": "0.68.0", + "contributors": [ + "tpDBL", + "web-flow" + ] + }, + { + "pr": "10119", + "title": "[FIX] Wrap custom fields in user profile to new line", + "userLogin": "PhpXp", + "milestone": "0.68.0", + "contributors": [ + "PhpXp", + "karlprieb", + "web-flow" + ] + }, + { + "pr": "11349", + "title": "[FIX] Record popup", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11489", + "title": "[NEW] Make WebRTC not enabled by default", + "userLogin": "MartinSchoeler", + "contributors": [ + "MartinSchoeler" + ] + }, + { + "pr": "11443", + "title": "[NEW] Accept resumeToken as query param to log in", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "10514", + "title": "[NEW] Livechat File Upload", + "userLogin": "renatobecker", + "milestone": "0.66.0", + "contributors": [ + "renatobecker", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.68.0-rc.1": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11561", + "title": "Regression: Update cachedCollection version", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11550", + "title": "Regression: nonReactive to nonreactive", + "userLogin": "ggazzo", + "milestone": "0.68.0", + "contributors": [ + "ggazzo" + ] + } + ] + }, + "0.68.0-rc.2": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11587", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11567", + "title": "Regression: Make message popup user mentions reactive again", + "userLogin": "tassoevan", + "milestone": "0.68.0", + "contributors": [ + "tassoevan", + "rodrigok", + "web-flow" + ] + } + ] + }, + "0.68.0-rc.3": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11590", + "title": "Regression: Fix purge message's translations", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.68.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [] + }, + "0.68.1": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11616", + "title": "Release 0.68.1", + "userLogin": "sampaiodiego", + "contributors": [ + "engelgabriel", + "sampaiodiego", + "tassoevan", + "rodrigok" + ] + }, + { + "pr": "11613", + "title": "[FIX] `Jump to message` search result action", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11597", + "title": "[FIX] HipChat importer wasn’t compatible with latest exports", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.68.2": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11630", + "title": "Release 0.68.2", + "userLogin": "sampaiodiego", + "contributors": [ + "c0dzilla", + "sampaiodiego" + ] + }, + { + "pr": "11544", + "title": "[FIX] Incorrect migration version in v130.js", + "userLogin": "c0dzilla", + "contributors": [ + "c0dzilla", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.68.3": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11650", + "title": "Release 0.68.3", + "userLogin": "sampaiodiego", + "contributors": [ + "Hudell", + "sampaiodiego", + "rndmh3ro", + "MarcosSpessatto" + ] + }, + { + "pr": "11639", + "title": "[FIX] Missing chat history for users without permission `preview-c-room`", + "userLogin": "Hudell", + "milestone": "0.68.3", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11625", + "title": "[FIX] User info APIs not returning customFields correctly", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.3", + "contributors": [ + "MarcosSpessatto", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11631", + "title": "[FIX] Prune translations in German", + "userLogin": "rndmh3ro", + "milestone": "0.68.3", + "contributors": [ + "rndmh3ro", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11635", + "title": "[FIX] Prune translation on room info panel", + "userLogin": "sampaiodiego", + "milestone": "0.68.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11642", + "title": "[FIX] SAML login not working when user has multiple emails", + "userLogin": "Hudell", + "milestone": "0.68.3", + "contributors": [ + "Hudell", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.68.4": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11719", + "title": "[FIX] Default server language not being applied", + "userLogin": "sampaiodiego", + "milestone": "0.68.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11708", + "title": "[FIX] Broken logo on setup wizard", + "userLogin": "sampaiodiego", + "milestone": "0.68.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11646", + "title": "[FIX] Regression in prune by user, and update lastMessage", + "userLogin": "vynmera", + "milestone": "0.68.4", + "contributors": [ + "vynmera", + "ggazzo" + ] + } + ] + }, + "0.68.5": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11830", + "title": "[FIX] Livechat open room method", + "userLogin": "renatobecker", + "milestone": "0.69.0", + "contributors": [ + "renatobecker" + ] + } + ] + }, + "0.69.0-rc.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11852", + "title": "Release 0.68.5", + "userLogin": "sampaiodiego", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + }, + { + "pr": "11613", + "title": "[FIX] `Jump to message` search result action", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11597", + "title": "[FIX] HipChat importer wasn’t compatible with latest exports", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "10700", + "title": "[FIX] Delete removed user's subscriptions", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "Hudell", + "MarcosSpessatto" + ] + }, + { + "pr": "11837", + "title": "[NEW] Beta support for Big Blue Button video conferencing system", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "ggazzo", + "rodrigok" + ] + }, + { + "pr": "11011", + "title": "[FIX] LiveChat switch department not working", + "userLogin": "renatobecker", + "milestone": "Short-term", + "contributors": [ + "renatobecker", + "ggazzo", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "10269", + "title": "[NEW] Slackbridge: send attachment notifications", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "kable-wilmoth", + "Hudell", + "web-flow" + ] + }, + { + "pr": "11796", + "title": "[FIX] Some assets were pointing to nonexistent path", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11733", + "title": "[IMPROVE] Start storing Livechat department within rooms", + "userLogin": "renatobecker", + "milestone": "0.69.0", + "contributors": [ + "renatobecker", + "web-flow" + ] + }, + { + "pr": "11638", + "title": "[NEW] Personal access tokens for users to create API tokens", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto", + "sampaiodiego", + "ggazzo" + ] + }, + { + "pr": "11522", + "title": "[FIX] Revoked `view-d-room` permission logics", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "Hudell", + "web-flow" + ] + }, + { + "pr": "11821", + "title": "[FIX] REST `im.members` endpoint not working without sort parameter", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11697", + "title": "[NEW] REST endpoint to manage server assets", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "10217", + "title": "[NEW] Setting to enable/disable slack bridge reactions", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "kable-wilmoth", + "Hudell", + "web-flow" + ] + }, + { + "pr": "11691", + "title": "Fixed deutsch message pruning translations", + "userLogin": "TheReal1604", + "milestone": "0.69.0", + "contributors": [ + "TheReal1604", + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11794", + "title": "Fixed the Finnish translation and removed some profanities", + "userLogin": "jukper", + "milestone": "0.69.0", + "contributors": [ + "jukper" + ] + }, + { + "pr": "11834", + "title": "[FIX] Livechat rooms starting with two unread message counter", + "userLogin": "renatobecker", + "milestone": "0.69.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "11551", + "title": "[FIX] Results pagination on /directory REST endpoint", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto", + "sampaiodiego" + ] + }, + { + "pr": "11838", + "title": "LingoHub based on develop", + "userLogin": "engelgabriel", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11778", + "title": "[FIX] re-adding margin to menu icon on header", + "userLogin": "rssilva", + "milestone": "0.69.0", + "contributors": [ + "rssilva" + ] + }, + { + "pr": "11797", + "title": "[FIX] minor fixes in hungarian i18n ", + "userLogin": "Atisom", + "contributors": [ + "Atisom", + "web-flow" + ] + }, + { + "pr": "11836", + "title": "[FIX] permissions name no break", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11657", + "title": "[FIX] Searching by `undefined` via REST when using `query` param", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto" + ] + }, + { + "pr": "11781", + "title": "[FIX] Fix permalink of message when running system with subdir", + "userLogin": "ura14h", + "milestone": "0.69.0", + "contributors": [ + "ura14h", + "web-flow", + "tassoevan", + "ggazzo" + ] + }, + { + "pr": "11543", + "title": "[FIX] Fix links in `onTableItemClick` of the directroy page", + "userLogin": "ura14h", + "milestone": "0.69.0", + "contributors": [ + "ura14h", + "web-flow", + "ggazzo" + ] + }, + { + "pr": "11830", + "title": "[FIX] Livechat open room method", + "userLogin": "renatobecker", + "milestone": "0.69.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "11473", + "title": "[NEW] Rich message text and image buttons", + "userLogin": "ubarsaiyan", + "milestone": "0.69.0", + "contributors": [ + "ubarsaiyan", + "ggazzo", + "rodrigok", + "web-flow" + ] + }, + { + "pr": "11802", + "title": "[FIX] App's i18nAlert is only being displayed as \"i18nAlert\"", + "userLogin": "graywolf336", + "milestone": "0.69.0", + "contributors": [ + "graywolf336" + ] + }, + { + "pr": "11627", + "title": "[FIX] Removed hardcoded values.", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "Hudell", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "9749", + "title": "[NEW] Setting to block unauthenticated access to avatars", + "userLogin": "Hudell", + "milestone": "Short-term", + "contributors": [ + "Hudell", + "web-flow", + "sampaiodiego" + ] + }, + { + "pr": "11643", + "title": "[FIX] SAML is flooding logfile", + "userLogin": "Hudell", + "milestone": "0.69.0", + "contributors": [ + "Hudell", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11809", + "title": " [FIX] directory search table not clickable lines", + "userLogin": "tassoevan", + "milestone": "0.69.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11814", + "title": "Regression: Fix livechat code issues after new lint rules", + "userLogin": "sampaiodiego", + "milestone": "0.69.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11816", + "title": "Do not remove package-lock.json of livechat package", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11815", + "title": "Run eslint and unit tests on pre-push hook", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11474", + "title": "[FIX] REST endpoints to update user not respecting some settings", + "userLogin": "MarcosSpessatto", + "milestone": "0.69.0", + "contributors": [ + "MarcosSpessatto", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11779", + "title": "[NEW] Setting to set a JS/CSS CDN", + "userLogin": "geekgonecrazy", + "milestone": "0.69.0", + "contributors": [ + "geekgonecrazy", + "web-flow" + ] + }, + { + "pr": "11804", + "title": "Additional eslint rules ", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11807", + "title": "[FIX] Apply Cordova fix in lazy-loaded images sources", + "userLogin": "tassoevan", + "milestone": "0.69.0", + "contributors": [ + "tassoevan", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11800", + "title": "Add new eslint rules (automatically fixed)", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "8602", + "title": "[NEW] Make font of unread items bolder for better contrast", + "userLogin": "ausminternet", + "milestone": "0.69.0", + "contributors": [ + "ausminternet", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11775", + "title": "[FIX] Cannot set property 'input' of undefined", + "userLogin": "ggazzo", + "milestone": "0.69.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11644", + "title": "[IMPROVE] Escape parameters before send them to email template", + "userLogin": "tassoevan", + "milestone": "0.69.0", + "contributors": [ + "tassoevan", + "web-flow" + ] + }, + { + "pr": "11784", + "title": "[IMPROVE] Warn about push settings that need server restart", + "userLogin": "tassoevan", + "milestone": "0.69.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11687", + "title": "[FIX] Missing twitter:image and og:image tags", + "userLogin": "engelgabriel", + "milestone": "0.69.0", + "contributors": [ + "engelgabriel", + "web-flow" + ] + }, + { + "pr": "11674", + "title": "[IMPROVE] Role tag UI", + "userLogin": "timkinnane", + "milestone": "0.69.0", + "contributors": [ + "timkinnane" + ] + }, + { + "pr": "11703", + "title": "[FIX] Return room ID for groups where user joined", + "userLogin": "timkinnane", + "contributors": [ + "timkinnane" + ] + }, + { + "pr": "11670", + "title": "[FIX] \"User is typing\" not working in new Livechat session", + "userLogin": "renatobecker", + "milestone": "0.69.0", + "contributors": [ + "renatobecker" + ] + }, + { + "pr": "11682", + "title": "[FIX] wrong create date of channels and users on directory view", + "userLogin": "gsperezb", + "milestone": "0.69.0", + "contributors": [ + "gsperezb", + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11730", + "title": "[FIX] Escape meta data before inject in head tag", + "userLogin": "tassoevan", + "milestone": "0.69.0", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11761", + "title": "[FIX] minor fixes in i18n", + "userLogin": "Atisom", + "milestone": "0.69.0", + "contributors": [ + "Atisom", + "web-flow" + ] + }, + { + "pr": "11467", + "title": "[FIX] Code tag duplicating characters", + "userLogin": "vynmera", + "milestone": "0.69.0", + "contributors": [ + "vynmera", + "web-flow" + ] + }, + { + "pr": "11139", + "title": "[FIX] Custom sound uploader not working in Firefox and IE", + "userLogin": "vynmera", + "milestone": "0.69.0", + "contributors": [ + "vynmera" + ] + }, + { + "pr": "11728", + "title": "[FIX] Fixing timeAgo function on directory", + "userLogin": "rssilva", + "milestone": "0.69.0", + "contributors": [ + "rssilva" + ] + }, + { + "pr": "11578", + "title": "[FIX] Render Attachment Pretext When Markdown Specified", + "userLogin": "glstewart17", + "milestone": "0.69.0", + "contributors": [ + "glstewart17" + ] + }, + { + "pr": "11686", + "title": "[IMPROVE] Messagebox fix performance", + "userLogin": "ggazzo", + "milestone": "0.69.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11740", + "title": "[FIX] Message attachments was not respecting sort and lost spacing", + "userLogin": "ggazzo", + "milestone": "0.69.0", + "contributors": [ + "ggazzo" + ] + }, + { + "pr": "11662", + "title": "[IMPROVE] Add template tag #{userdn} to filter LDAP group member format", + "userLogin": "crazy-max", + "milestone": "0.69.0", + "contributors": [ + "crazy-max" + ] + }, + { + "pr": "11719", + "title": "[FIX] Default server language not being applied", + "userLogin": "sampaiodiego", + "milestone": "0.68.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11709", + "title": "[FIX] Closed connections being storing on db", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11708", + "title": "[FIX] Broken logo on setup wizard", + "userLogin": "sampaiodiego", + "milestone": "0.68.4", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11646", + "title": "[FIX] Regression in prune by user, and update lastMessage", + "userLogin": "vynmera", + "milestone": "0.68.4", + "contributors": [ + "vynmera", + "ggazzo" + ] + }, + { + "pr": "11626", + "title": "[FIX] Login logo now centered on small screens", + "userLogin": "wreiske", + "milestone": "0.69.0", + "contributors": [ + "wreiske", + "web-flow" + ] + }, + { + "pr": "11667", + "title": "[FIX] Push notifications stuck after db failure", + "userLogin": "sampaiodiego", + "milestone": "0.69.0", + "contributors": [ + "sampaiodiego" + ] + }, + { + "pr": "11684", + "title": "[IMPROVE] Add nyan rocket on Rocket.Chat preview Docker image", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "web-flow" + ] + }, + { + "pr": "11645", + "title": "[IMPROVE] Reducing `saveUser` code complexity", + "userLogin": "Hudell", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11642", + "title": "[FIX] SAML login not working when user has multiple emails", + "userLogin": "Hudell", + "milestone": "0.68.3", + "contributors": [ + "Hudell", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11635", + "title": "[FIX] Prune translation on room info panel", + "userLogin": "sampaiodiego", + "milestone": "0.68.3", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11631", + "title": "[FIX] Prune translations in German", + "userLogin": "rndmh3ro", + "milestone": "0.68.3", + "contributors": [ + "rndmh3ro", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11625", + "title": "[FIX] User info APIs not returning customFields correctly", + "userLogin": "MarcosSpessatto", + "milestone": "0.68.3", + "contributors": [ + "MarcosSpessatto", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11639", + "title": "[FIX] Missing chat history for users without permission `preview-c-room`", + "userLogin": "Hudell", + "milestone": "0.68.3", + "contributors": [ + "Hudell" + ] + }, + { + "pr": "11544", + "title": "[FIX] Incorrect migration version in v130.js", + "userLogin": "c0dzilla", + "contributors": [ + "c0dzilla", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11597", + "title": "[FIX] HipChat importer wasn’t compatible with latest exports", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11613", + "title": "[FIX] `Jump to message` search result action", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11606", + "title": "Merge master into develop & Set version to 0.69.0-develop", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "11590", + "title": "Regression: Fix purge message's translations", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "0.69.0-rc.1": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11835", + "title": "App engine merge", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11864", + "title": "[NEW] Internal marketplace for apps", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "gdelavald", + "rssilva", + "rodrigok", + "ggazzo" + ] + }, + { + "pr": "11878", + "title": "[FIX] Translations were not unique per app allowing conflicts among apps", + "userLogin": "rodrigok", + "milestone": "0.69.0", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11861", + "title": "Regression: role tag background, unread item font and message box autogrow", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo", + "sampaiodiego" + ] + } + ] + }, + "0.69.0": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11852", + "title": "Release 0.68.5", + "userLogin": "sampaiodiego", + "contributors": [ + "renatobecker", + "sampaiodiego" + ] + }, + { + "pr": "11613", + "title": "[FIX] `Jump to message` search result action", + "userLogin": "tassoevan", + "contributors": [ + "tassoevan" + ] + }, + { + "pr": "11597", + "title": "[FIX] HipChat importer wasn’t compatible with latest exports", + "userLogin": "rodrigok", + "contributors": [ + "rodrigok", + "sampaiodiego", + "web-flow" + ] + } + ] + }, + "0.69.1": { + "node_version": "8.11.3", + "npm_version": "5.6.0", + "pull_requests": [ + { + "pr": "11892", + "title": "[FIX] Hipchat import was failing when importing messages from a non existent user", + "userLogin": "rodrigok", + "milestone": "0.69.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11910", + "title": "[FIX] Hipchat importer was not importing users without emails and uploaded files", + "userLogin": "rodrigok", + "milestone": "0.69.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11893", + "title": " [FIX] App updates were not being shown correctly", + "userLogin": "rodrigok", + "milestone": "0.69.1", + "contributors": [ + "rodrigok" + ] + }, + { + "pr": "11853", + "title": "[FIX] Duplicated message buttons", + "userLogin": "ubarsaiyan", + "milestone": "0.69.1", + "contributors": [ + "ubarsaiyan", + "web-flow" + ] + } + ] + } + } +} \ No newline at end of file diff --git a/.github/templates/commit.hbs b/.github/templates/commit.hbs new file mode 100755 index 000000000000..1781268b2777 --- /dev/null +++ b/.github/templates/commit.hbs @@ -0,0 +1,40 @@ +{{!-- pr reference --}}- {{#if pr}}[#{{pr}}]({{pr_url}}){{/if}} + +{{~!-- subject --}} {{subject}} + +{{~!-- commit references --}} +{{~#if references~}} + , closes + {{~#each references}} {{#if @root.linkReferences~}} + [ + {{~#if this.owner}} + {{~this.owner}}/ + {{~/if}} + {{~this.repository}}#{{this.issue}}]( + {{~#if @root.repository}} + {{~#if @root.host}} + {{~@root.host}}/ + {{~/if}} + {{~#if this.repository}} + {{~#if this.owner}} + {{~this.owner}}/ + {{~/if}} + {{~this.repository}} + {{~else}} + {{~#if @root.owner}} + {{~@root.owner}}/ + {{~/if}} + {{~@root.repository}} + {{~/if}} + {{~else}} + {{~@root.repoUrl}} + {{~/if}}/ + {{~@root.issue}}/{{this.issue}}) + {{~else}} + {{~#if this.owner}} + {{~this.owner}}/ + {{~/if}} + {{~this.repository}}#{{this.issue}} + {{~/if}}{{/each}} +{{~/if}} + diff --git a/.github/templates/footer.hbs b/.github/templates/footer.hbs new file mode 100755 index 000000000000..2aa774f53674 --- /dev/null +++ b/.github/templates/footer.hbs @@ -0,0 +1,11 @@ +{{#if noteGroups}} +{{#each noteGroups}} + +### {{title}} + +{{#each notes}} +* {{#if commit.scope}}**{{commit.scope}}:** {{/if}}{{text}} +{{/each}} +{{/each}} + +{{/if}} diff --git a/.github/templates/header.hbs b/.github/templates/header.hbs new file mode 100755 index 000000000000..313fd6528043 --- /dev/null +++ b/.github/templates/header.hbs @@ -0,0 +1,26 @@ + +{{#if isPatch~}} + ## +{{~else~}} + # +{{~/if}} {{#if @root.linkCompare~}} + [{{version}}]( + {{~#if @root.repository~}} + {{~#if @root.host}} + {{~@root.host}}/ + {{~/if}} + {{~#if @root.owner}} + {{~@root.owner}}/ + {{~/if}} + {{~@root.repository}} + {{~else}} + {{~@root.repoUrl}} + {{~/if~}} + /compare/{{previousTag}}...{{currentTag}}) +{{~else}} + {{~version}} +{{~/if}} +{{~#if title}} "{{title}}" +{{~/if}} +{{~#if date}} ({{date}}) +{{/if}} diff --git a/.github/templates/template.hbs b/.github/templates/template.hbs new file mode 100755 index 000000000000..0705b78e3a3e --- /dev/null +++ b/.github/templates/template.hbs @@ -0,0 +1,22 @@ +{{> header}} + +{{#each commitGroups}} + +{{#if collapse}} +
+{{title}} +{{else}} +### {{title}} +{{/if}} + +{{#each commits}} +{{> commit root=@root}} +{{/each}} +{{#if collapse}} +
+{{/if}} + +{{/each}} +{{> footer}} + + diff --git a/.gitignore b/.gitignore index a342721459ce..ae7a0245e404 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ **/build/* **/node_modules/* **/tmp/* +**/.meteor/.id +**/.meteor/dev_bundle +**/.meteor/local* +**/.meteor/meteorite /private/certs/* *.bak *.iml @@ -11,6 +15,7 @@ *.log *.pydevproject *.sublime-project +*.sublime-workspace *.swp *.tmp *.tokens @@ -32,21 +37,21 @@ .env .externalToolBuilders .idea +.vscode .loadpath .map .metadata -.meteor/local -.meteor/meteorite +packages/rocketchat-livechat/assets/rocketchat-livechat.min.js .mule .pmd .project .sass-cache .settings .Spotlight-V100 +tatus .Trashes .wtpmodules \#*\# -BuildInfo.js Desktop.ini ehthumbs.db example.css @@ -67,3 +72,6 @@ tramp ecosystem.json pm2.json settings.json +build.sh +/public/livechat +packages/rocketchat-i18n/i18n/livechat.* diff --git a/.meteor/.finished-upgraders b/.meteor/.finished-upgraders index 61ee31323076..8f397c7dad01 100644 --- a/.meteor/.finished-upgraders +++ b/.meteor/.finished-upgraders @@ -10,3 +10,10 @@ notices-for-facebook-graph-api-2 1.2.0-meteor-platform-split 1.2.0-cordova-changes 1.2.0-breaking-changes +1.3.0-split-minifiers-package +1.3.5-remove-old-dev-bundle-link +1.4.0-remove-old-dev-bundle-link +1.4.1-add-shell-server-package +1.4.3-split-account-service-packages +1.5-add-dynamic-import-package +1.7-split-underscore-from-meteor-base diff --git a/.meteor/.gitignore b/.meteor/.gitignore index 40830374235d..501f92e4b5eb 100644 --- a/.meteor/.gitignore +++ b/.meteor/.gitignore @@ -1 +1,2 @@ +dev_bundle local diff --git a/.meteor/.id b/.meteor/.id deleted file mode 100644 index bf888b12702f..000000000000 --- a/.meteor/.id +++ /dev/null @@ -1,7 +0,0 @@ -# This file contains a token that is unique to your project. -# Check it into your repository along with the rest of this directory. -# It can be used for purposes such as: -# - ensuring you don't accidentally deploy one app on top of another -# - providing package authors with aggregated statistics - -1d10m9yd7fq1hsv663c diff --git a/.meteor/cordova-plugins b/.meteor/cordova-plugins deleted file mode 100644 index 78573be10dc7..000000000000 --- a/.meteor/cordova-plugins +++ /dev/null @@ -1,2 +0,0 @@ -ionic-plugin-keyboard@1.0.7 -phonegap-facebook-plugin@https://github.com/Sing-Li/phonegap-facebook-plugin.git#667dda292cf70d8fb725f512cedef3fe0dd55ac3 diff --git a/.meteor/packages b/.meteor/packages index 164b3e945ae9..e87a8cd84f31 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -3,89 +3,168 @@ # 'meteor add' and 'meteor remove' will edit this file for you, # but you can also edit it by hand. -accounts-facebook -accounts-github -accounts-google -accounts-meteor-developer -accounts-password -accounts-twitter +rocketchat:cors + +accounts-facebook@1.3.1 +accounts-github@1.4.1 +accounts-google@1.3.1 +accounts-meteor-developer@1.4.1 +accounts-password@1.5.0 +accounts-twitter@1.4.1 blaze-html-templates -check -coffeescript -ddp-rate-limiter -ejson -email -fastclick -http -jquery -less -logging -meteor-base -mobile-experience -mongo -random -reactive-dict -reactive-var -reload -service-configuration -session +check@1.3.0 +ddp-rate-limiter@1.0.7 +ddp-common@1.4.0 +dynamic-import@0.3.0 +ecmascript@0.10.6 +ejson@1.1.0 +email@1.2.3 +fastclick@1.0.13 +http@1.4.0 +jquery@1.11.10 +logging@1.1.19 +meteor-base@1.3.0 +mobile-experience@1.0.5 +mongo@1.4.2 +random@1.1.0 +rate-limit@1.0.8 +reactive-dict@1.2.0 +reactive-var@1.0.11 +reload@1.2.0 +service-configuration@1.0.11 +session@1.1.7 +shell-server@0.3.1 spacebars -standard-minifiers -tracker - -arunoda:streams -rocketchat:lib +standard-minifier-js@2.3.1 +tracker@1.1.3 +rocketchat:2fa +rocketchat:action-links +rocketchat:accounts +rocketchat:analytics +rocketchat:api +rocketchat:assets rocketchat:authorization rocketchat:autolinker +rocketchat:autotranslate +rocketchat:bot-helpers +rocketchat:cas rocketchat:channel-settings +rocketchat:channel-settings-mail-messages rocketchat:colors +rocketchat:crowd rocketchat:custom-oauth -rocketchat:emojione +rocketchat:custom-sounds +rocketchat:dolphin +rocketchat:drupal +rocketchat:emoji +rocketchat:emoji-custom +rocketchat:emoji-emojione +rocketchat:error-handler rocketchat:favico rocketchat:file +rocketchat:file-upload rocketchat:github-enterprise rocketchat:gitlab -rocketchat:highlight +#rocketchat:google-natural-language +rocketchat:google-vision +rocketchat:grant +rocketchat:grant-facebook +rocketchat:grant-github +rocketchat:grant-google +rocketchat:graphql +rocketchat:highlight-words +rocketchat:iframe-login +rocketchat:importer +rocketchat:importer-csv +rocketchat:importer-hipchat +rocketchat:importer-hipchat-enterprise +rocketchat:importer-slack +rocketchat:importer-slack-users +rocketchat:integrations +rocketchat:internal-hubot +rocketchat:irc +rocketchat:issuelinks +rocketchat:katex rocketchat:ldap +rocketchat:lib +rocketchat:livechat +rocketchat:livestream rocketchat:logger +rocketchat:login-token rocketchat:mailer +rocketchat:mapview rocketchat:markdown -rocketchat:me rocketchat:mentions +rocketchat:mentions-flextab +rocketchat:message-action +rocketchat:message-attachments +rocketchat:message-mark-as-unread rocketchat:message-pin +rocketchat:message-snippet rocketchat:message-star +rocketchat:migrations +rocketchat:monitoring +rocketchat:oauth2-server-config rocketchat:oembed +rocketchat:otr +rocketchat:postcss +rocketchat:push-notifications +rocketchat:reactions +rocketchat:retention-policy +rocketchat:apps +rocketchat:sandstorm +rocketchat:setup-wizard +rocketchat:slackbridge +rocketchat:slashcommands-archive +rocketchat:slashcommands-asciiarts +rocketchat:slashcommands-create +rocketchat:slashcommands-help +rocketchat:slashcommands-hide rocketchat:slashcommands-invite +rocketchat:slashcommands-invite-all rocketchat:slashcommands-join +rocketchat:slashcommands-kick rocketchat:slashcommands-leave +rocketchat:slashcommands-me +rocketchat:slashcommands-msg +rocketchat:slashcommands-mute +rocketchat:slashcommands-open +rocketchat:slashcommands-topic +rocketchat:slashcommands-unarchive +rocketchat:slider +rocketchat:smarsh-connector rocketchat:spotify rocketchat:statistics +rocketchat:streamer rocketchat:theme +rocketchat:tokenpass +rocketchat:tooltip rocketchat:tutum rocketchat:ui rocketchat:ui-account rocketchat:ui-admin +rocketchat:ui-clean-history rocketchat:ui-flextab rocketchat:ui-login rocketchat:ui-master rocketchat:ui-message rocketchat:ui-sidenav +rocketchat:ui-vrecord +rocketchat:user-data-download +rocketchat:version +rocketchat:videobridge rocketchat:webrtc rocketchat:wordpress -#rocketchat:chatops -#rocketchat:hubot -#rocketchat:irc -#rocketchat:livechat +rocketchat:nrr konecty:change-case konecty:delayed-task konecty:mongo-counter konecty:multiple-instances-status -konecty:nrr konecty:user-presence -chrismbeckett:toastr +deepwell:bootstrap-datepicker2 dispatch:run-as-user francocatena:status jalik:ufs @@ -93,31 +172,29 @@ jalik:ufs-gridfs jparker:gravatar kadira:blaze-layout kadira:flow-router +keepnox:perfect-scrollbar kenton:accounts-sandstorm -kevohagan:sweetalert -meteorhacks:kadira mizzao:autocomplete mizzao:timesync -momentjs:moment -monbro:mongodb-mapreduce-aggregation mrt:reactive-store mystor:device-detection nimble:restivus nooitaf:colors +ostrio:cookies pauli:accounts-linkedin -perak:codemirror -percolate:migrations percolate:synced-cron raix:handlebar-helpers -raix:push +rocketchat:push raix:ui-dropped-event steffo:meteor-accounts-saml -tap:i18n -tmeasday:crypto-md5 -tmeasday:errors todda00:friendly-slugs -underscorestring:underscore.string yasaricli:slugify yasinuslu:blaze-meta -# sanjo:jasmine -# velocity:html-reporter +rocketchat:version-check + +rocketchat:search +chatpal:search +rocketchat:lazy-load +tap:i18n +underscore +rocketchat:bigbluebutton diff --git a/.meteor/release b/.meteor/release index 3a05e0a2f701..8fed0e8ee874 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.2.1 +METEOR@1.6.1.3 diff --git a/.meteor/versions b/.meteor/versions index 3bbb02db1b0f..655f5b396da4 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -1,189 +1,282 @@ -accounts-base@1.2.2 -accounts-facebook@1.0.6 -accounts-github@1.0.6 -accounts-google@1.0.6 -accounts-meteor-developer@1.0.6 -accounts-oauth@1.1.8 -accounts-password@1.1.4 -accounts-twitter@1.0.6 -alanning:roles@1.2.14 -aldeed:simple-schema@1.3.3 -arunoda:streams@0.1.17 -autoupdate@1.2.4 -babel-compiler@5.8.24_1 -babel-runtime@0.1.4 -base64@1.0.4 -binary-heap@1.0.4 -blaze@2.1.3 -blaze-html-templates@1.0.1 -blaze-tools@1.0.4 -boilerplate-generator@1.0.4 -caching-compiler@1.0.0 -caching-html-compiler@1.0.2 -callback-hook@1.0.4 -cfs:http-methods@0.0.30 -check@1.1.0 -chrismbeckett:toastr@2.1.2_1 -coffeescript@1.0.11 -cosmos:browserify@0.9.0 +accounts-base@1.4.2 +accounts-facebook@1.3.1 +accounts-github@1.4.1 +accounts-google@1.3.1 +accounts-meteor-developer@1.4.1 +accounts-oauth@1.1.15 +accounts-password@1.5.1 +accounts-twitter@1.4.1 +aldeed:simple-schema@1.5.4 +allow-deny@1.1.0 +autoupdate@1.4.0 +babel-compiler@7.0.9 +babel-runtime@1.2.2 +base64@1.0.11 +binary-heap@1.0.10 +blaze@2.3.2 +blaze-html-templates@1.1.2 +blaze-tools@1.0.10 +boilerplate-generator@1.4.0 +caching-compiler@1.1.12 +caching-html-compiler@1.1.2 +callback-hook@1.1.0 +cfs:http-methods@0.0.32 +chatpal:search@0.0.1 +check@1.3.1 +coffeescript@1.0.17 dandv:caret-position@2.1.1 -ddp@1.2.2 -ddp-client@1.2.1 -ddp-common@1.2.2 -ddp-rate-limiter@1.0.0 -ddp-server@1.2.2 -deps@1.0.9 -diff-sequence@1.0.1 +ddp@1.4.0 +ddp-client@2.3.2 +ddp-common@1.4.0 +ddp-rate-limiter@1.0.7 +ddp-server@2.1.2 +deepwell:bootstrap-datepicker2@1.3.0 +deps@1.0.12 +diff-sequence@1.1.0 dispatch:run-as-user@1.1.1 -ecmascript@0.1.6 -ecmascript-runtime@0.2.6 -ejson@1.0.7 -email@1.0.8 -emojione:emojione@1.5.2 -facebook@1.2.2 -fastclick@1.0.7 -francocatena:status@1.5.0 -geojson-utils@1.0.4 -github@1.1.4 -google@1.1.7 -hot-code-push@1.0.0 -html-tools@1.0.5 -htmljs@1.0.5 -http@1.1.1 -id-map@1.0.4 -idorecall:email-normalize@1.0.0 -jalik:ufs@0.3.3 -jalik:ufs-gridfs@0.1.1 +dynamic-import@0.3.0 +ecmascript@0.10.9 +ecmascript-runtime@0.5.0 +ecmascript-runtime-client@0.6.2 +ecmascript-runtime-server@0.5.0 +edgee:slingshot@0.7.1 +ejson@1.1.0 +email@1.2.3 +emojione:emojione@2.2.6 +es5-shim@4.7.3 +facebook-oauth@1.4.1 +fastclick@1.0.13 +francocatena:status@1.5.3 +geojson-utils@1.0.10 +github-oauth@1.2.0 +google-oauth@1.2.5 +hot-code-push@1.0.4 +html-tools@1.0.11 +htmljs@1.0.11 +http@1.4.1 +id-map@1.1.0 +jalik:ufs@0.7.5 +jalik:ufs-gridfs@0.2.1 +jalik:ufs-local@0.2.9 jparker:crypto-core@0.1.0 jparker:crypto-md5@0.1.1 -jparker:gravatar@0.4.1 -jquery@1.11.4 -kadira:blaze-layout@2.2.0 -kadira:flow-router@2.9.0 -kenton:accounts-sandstorm@0.1.8 -kevohagan:sweetalert@1.0.0 -konecty:autolinker@1.0.3 +jparker:gravatar@0.5.1 +jquery@1.11.11 +kadira:blaze-layout@2.3.0 +kadira:flow-router@2.12.1 +keepnox:perfect-scrollbar@0.6.8 +kenton:accounts-sandstorm@0.7.0 konecty:change-case@2.3.0 konecty:delayed-task@1.0.0 -konecty:mongo-counter@0.0.3 -konecty:multiple-instances-status@1.0.3 -konecty:nrr@2.0.2 -konecty:user-presence@1.2.6 -launch-screen@1.0.4 -less@2.5.1 -livedata@1.0.15 -localstorage@1.0.5 -logging@1.0.8 -matb33:collection-hooks@0.8.1 -meteor@1.1.10 -meteor-base@1.0.1 -meteor-developer@1.1.5 -meteorhacks:kadira@2.26.3 +konecty:mongo-counter@0.0.5_3 +konecty:multiple-instances-status@1.1.0 +konecty:user-presence@2.2.0 +launch-screen@1.1.1 +less@2.7.12 +livedata@1.0.18 +localstorage@1.2.0 +logging@1.1.20 +matb33:collection-hooks@0.8.4 +mdg:validation-error@0.5.1 +meteor@1.8.6 +meteor-base@1.3.0 +meteor-developer-oauth@1.2.0 +meteorhacks:inject-initial@1.0.4 meteorhacks:meteorx@1.4.1 meteorspark:util@0.2.0 -minifiers@1.1.7 -minimongo@1.0.10 +minifier-css@1.3.1 +minifier-js@2.3.5 +minimongo@1.4.4 mizzao:autocomplete@0.5.1 mizzao:timesync@0.3.4 -mobile-experience@1.0.1 -mobile-status-bar@1.0.6 -momentjs:moment@2.10.6 -monbro:mongodb-mapreduce-aggregation@1.0.1 -mongo@1.1.3 -mongo-id@1.0.1 -mongo-livedata@1.0.9 +mobile-experience@1.0.5 +mobile-status-bar@1.0.14 +modules@0.11.8 +modules-runtime@0.9.2 +mongo@1.4.7 +mongo-dev-server@1.1.0 +mongo-id@1.0.7 +mongo-livedata@1.0.12 mrt:reactive-store@0.0.1 mystor:device-detection@0.2.0 -nimble:restivus@0.8.4 -nooitaf:colors@0.0.2 -npm-bcrypt@0.7.8_2 -npm-mongo@1.4.39_1 -oauth@1.1.6 -oauth1@1.1.5 -oauth2@1.1.5 -observe-sequence@1.0.7 -ordered-dict@1.0.4 -pauli:accounts-linkedin@1.2.0 -pauli:linkedin@1.2.0 -perak:codemirror@1.2.8 -percolate:migrations@0.9.6 -percolate:synced-cron@1.3.0 -pntbr:js-yaml-client@0.0.1 -promise@0.5.1 +nimble:restivus@0.8.12 +nooitaf:colors@1.1.2_1 +npm-bcrypt@0.9.3 +npm-mongo@2.2.34 +oauth@1.2.3 +oauth1@1.2.0 +oauth2@1.2.0 +observe-sequence@1.0.16 +ordered-dict@1.1.0 +ostrio:cookies@2.2.4 +pauli:accounts-linkedin@2.1.5 +pauli:linkedin-oauth@1.2.0 +percolate:synced-cron@1.3.2 +promise@0.10.2 raix:eventemitter@0.1.3 raix:eventstate@0.0.4 raix:handlebar-helpers@0.2.5 -raix:push@3.0.2 raix:ui-dropped-event@0.0.7 -random@1.0.5 -rate-limit@1.0.0 -reactive-dict@1.1.3 -reactive-var@1.0.6 -reload@1.1.4 -retry@1.0.4 +random@1.1.0 +rate-limit@1.0.9 +reactive-dict@1.2.0 +reactive-var@1.0.11 +reload@1.2.0 +retry@1.1.0 +rocketchat:2fa@0.0.1 +rocketchat:accounts@0.0.1 +rocketchat:action-links@0.0.1 +rocketchat:analytics@0.0.2 +rocketchat:api@0.0.1 +rocketchat:apps@1.0.0 +rocketchat:assets@0.0.1 rocketchat:authorization@0.0.1 rocketchat:autolinker@0.0.1 +rocketchat:autotranslate@0.0.1 +rocketchat:bigbluebutton@0.0.1 +rocketchat:bot-helpers@0.0.1 +rocketchat:cas@1.0.0 rocketchat:channel-settings@0.0.1 +rocketchat:channel-settings-mail-messages@0.0.1 rocketchat:colors@0.0.1 +rocketchat:cors@0.0.1 +rocketchat:crowd@1.0.0 rocketchat:custom-oauth@1.0.0 -rocketchat:emojione@0.0.1 +rocketchat:custom-sounds@1.0.0 +rocketchat:dolphin@0.0.2 +rocketchat:drupal@0.0.1 +rocketchat:emoji@1.0.0 +rocketchat:emoji-custom@1.0.0 +rocketchat:emoji-emojione@0.0.1 +rocketchat:error-handler@1.0.0 rocketchat:favico@0.0.1 rocketchat:file@0.0.1 +rocketchat:file-upload@0.0.1 rocketchat:github-enterprise@0.0.1 rocketchat:gitlab@0.0.1 -rocketchat:highlight@0.0.1 +rocketchat:google-vision@0.0.1 +rocketchat:grant@0.0.1 +rocketchat:grant-facebook@0.0.1 +rocketchat:grant-github@0.0.1 +rocketchat:grant-google@0.0.1 +rocketchat:graphql@0.0.1 +rocketchat:highlight-words@0.0.1 +rocketchat:i18n@0.0.1 +rocketchat:iframe-login@1.0.0 +rocketchat:importer@0.0.1 +rocketchat:importer-csv@1.0.0 +rocketchat:importer-hipchat@0.0.1 +rocketchat:importer-hipchat-enterprise@1.0.0 +rocketchat:importer-slack@0.0.1 +rocketchat:importer-slack-users@1.0.0 +rocketchat:integrations@0.0.1 +rocketchat:internal-hubot@0.0.1 +rocketchat:irc@0.0.1 +rocketchat:issuelinks@0.0.1 +rocketchat:katex@0.0.1 +rocketchat:lazy-load@0.0.1 rocketchat:ldap@0.0.1 rocketchat:lib@0.0.1 +rocketchat:livechat@0.0.1 +rocketchat:livestream@0.0.5 rocketchat:logger@0.0.1 +rocketchat:login-token@1.0.0 rocketchat:mailer@0.0.1 -rocketchat:markdown@0.0.1 -rocketchat:me@0.0.1 +rocketchat:mapview@0.0.1 +rocketchat:markdown@0.0.2 rocketchat:mentions@0.0.1 +rocketchat:mentions-flextab@0.0.1 +rocketchat:message-action@0.0.1 +rocketchat:message-attachments@0.0.1 +rocketchat:message-mark-as-unread@0.0.1 rocketchat:message-pin@0.0.1 +rocketchat:message-snippet@0.0.1 rocketchat:message-star@0.0.1 +rocketchat:migrations@0.0.1 +rocketchat:monitoring@2.30.2_3 +rocketchat:nrr@1.0.0 +rocketchat:oauth2-server@2.0.0 +rocketchat:oauth2-server-config@1.0.0 rocketchat:oembed@0.0.1 +rocketchat:otr@0.0.1 +rocketchat:postcss@1.0.0 +rocketchat:push@3.3.1 +rocketchat:push-notifications@0.0.1 +rocketchat:reactions@0.0.1 +rocketchat:retention-policy@0.0.1 +rocketchat:sandstorm@0.0.1 +rocketchat:search@0.0.1 +rocketchat:setup-wizard@0.0.1 +rocketchat:slackbridge@0.0.1 +rocketchat:slashcommands-archive@0.0.1 +rocketchat:slashcommands-asciiarts@0.0.1 +rocketchat:slashcommands-create@0.0.1 +rocketchat:slashcommands-help@0.0.1 +rocketchat:slashcommands-hide@0.0.1 rocketchat:slashcommands-invite@0.0.1 +rocketchat:slashcommands-invite-all@0.0.1 rocketchat:slashcommands-join@0.0.1 +rocketchat:slashcommands-kick@0.0.1 rocketchat:slashcommands-leave@0.0.1 +rocketchat:slashcommands-me@0.0.1 +rocketchat:slashcommands-msg@0.0.1 +rocketchat:slashcommands-mute@0.0.1 +rocketchat:slashcommands-open@0.0.1 +rocketchat:slashcommands-topic@0.0.1 +rocketchat:slashcommands-unarchive@0.0.1 +rocketchat:slider@0.0.1 +rocketchat:smarsh-connector@0.0.1 +rocketchat:sms@0.0.1 rocketchat:spotify@0.0.1 rocketchat:statistics@0.0.1 +rocketchat:streamer@0.6.2 rocketchat:theme@0.0.1 +rocketchat:tokenpass@0.0.1 +rocketchat:tooltip@0.0.1 rocketchat:tutum@0.0.1 rocketchat:ui@0.1.0 rocketchat:ui-account@0.1.0 rocketchat:ui-admin@0.1.0 +rocketchat:ui-clean-history@0.0.1 rocketchat:ui-flextab@0.1.0 rocketchat:ui-login@0.1.0 rocketchat:ui-master@0.1.0 rocketchat:ui-message@0.1.0 rocketchat:ui-sidenav@0.1.0 +rocketchat:ui-vrecord@0.0.1 +rocketchat:user-data-download@1.0.0 +rocketchat:version@1.0.0 +rocketchat:version-check@0.0.1 +rocketchat:videobridge@0.2.0 rocketchat:webrtc@0.0.1 rocketchat:wordpress@0.0.1 -routepolicy@1.0.6 -service-configuration@1.0.5 -session@1.1.1 -sha@1.0.4 -simple:highlight.js@1.2.0 -simple:json-routes@1.0.4 -spacebars@1.0.7 -spacebars-compiler@1.0.7 -srp@1.0.4 -standard-minifiers@1.0.2 +routepolicy@1.0.13 +server-render@0.3.1 +service-configuration@1.0.11 +session@1.1.7 +sha@1.0.9 +shell-server@0.3.1 +shim-common@0.1.0 +simple:json-routes@2.1.0 +socket-stream-client@0.1.0 +spacebars@1.0.15 +spacebars-compiler@1.1.3 +srp@1.0.10 +standard-minifier-js@2.3.4 steffo:meteor-accounts-saml@0.0.1 -tap:i18n@1.7.0 -templating@1.1.5 -templating-tools@1.0.0 -tmeasday:crypto-base@3.1.2 -tmeasday:crypto-md5@3.1.2 -tmeasday:errors@2.0.0 -todda00:friendly-slugs@0.3.6 -tracker@1.0.9 -twitter@1.1.5 -ui@1.0.8 -underscore@1.0.4 -underscorestring:underscore.string@3.2.2 -url@1.0.5 -webapp@1.2.3 -webapp-hashing@1.0.5 +swydo:graphql@0.4.0 +tap:i18n@1.8.2 +templating@1.3.2 +templating-compiler@1.3.3 +templating-runtime@1.3.2 +templating-tools@1.1.2 +todda00:friendly-slugs@0.6.0 +tracker@1.1.3 +twitter-oauth@1.2.0 +ui@1.0.13 +underscore@1.0.10 +url@1.2.0 +webapp@1.5.0 +webapp-hashing@1.0.9 yasaricli:slugify@0.0.7 yasinuslu:blaze-meta@0.3.3 diff --git a/.openshift/rocket-chat-ephemeral.json b/.openshift/rocket-chat-ephemeral.json new file mode 100644 index 000000000000..dd25e870ff64 --- /dev/null +++ b/.openshift/rocket-chat-ephemeral.json @@ -0,0 +1,443 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "name": "rocket-chat-ephemeral", + "annotations": { + "description": "Rocket.Chat with a MongoDB database running with an Ephemeral storage.", + "tags": "quickstart,nodejs,mongodb,instant-app", + "iconClass": "icon-nodejs" + } + }, + "objects": [ + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "mongodb", + "labels": { + "template": "mongodb-ephemeral-template" + } + }, + "spec": { + "strategy": { + "type": "Recreate", + "recreateParams": { + "timeoutSeconds": 600 + } + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "mongodb" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "mongodb:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "test": false, + "selector": { + "name": "mongodb" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "mongodb" + } + }, + "spec": { + "volumes": [ + { + "name": "mongodb-data", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "mongodb", + "image": "registry.access.redhat.com/rhscl/mongodb-26-rhel7:latest", + "ports": [ + { + "containerPort": 27017, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "MONGODB_USER", + "value": "${MONGODB_USER}" + }, + { + "name": "MONGODB_PASSWORD", + "value": "${MONGODB_PASSWORD}" + }, + { + "name": "MONGODB_DATABASE", + "value": "${MONGODB_DATABASE}" + }, + { + "name": "MONGODB_ADMIN_PASSWORD", + "value": "${MONGODB_ADMIN_PASSWORD}" + } + ], + "resources": { + "limits": { + "memory": "${MEMORY_LIMIT}" + } + }, + "volumeMounts": [ + { + "name": "mongodb-data", + "mountPath": "/var/lib/mongodb/data" + } + ], + "livenessProbe": { + "tcpSocket": { + "port": 27017 + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD --eval=\"quit()\"" + ] + }, + "initialDelaySeconds": 3, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "capabilities": {}, + "privileged": false + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {} + } + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat" + }, + "spec": { + "dockerImageRepository": "${ROCKETCHAT_IMAGE}", + "tags": [ + { + "name": "latest", + "annotations": { + "description": "Provides a Rocket.Chat application", + "iconClass": "icon-nodejs", + "tags": "rocketchat" + }, + "from": { + "kind": "ImageStreamTag", + "name": "latest" + }, + "generation": 1, + "importPolicy": {} + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 600, + "maxUnavailable": "25%", + "maxSurge": "25%" + }, + "resources": {} + }, + "triggers": [ + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "rocketchat" + ], + "from": { + "kind": "ImageStreamTag", + "name": "rocketchat:latest" + } + } + } + ], + "replicas": 1, + "test": false, + "selector": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "annotations": { + "openshift.io/container.rocketchat.image.entrypoint": "[\"node\",\"main.js\"]", + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "volumes": [ + { + "name": "rocketchat-volume-1", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "rocketchat", + "image": "${ROCKETCHAT_IMAGE}:latest", + "ports": [ + { + "containerPort": 3000, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "MONGO_URL", + "value": "mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@mongodb:27017/${MONGODB_DATABASE}" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "rocketchat-volume-1", + "mountPath": "/app/uploads" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/api/v1/info", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "livenessProbe": { + "httpGet": { + "path": "/api/v1/info", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {} + } + } + }, + "status": {} + }, + { + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/host.generated": "true" + } + }, + "spec": { + "to": { + "kind": "Service", + "name": "rocketchat" + }, + "port": { + "targetPort": "3000-tcp" + } + }, + "status": { + "ingress": null + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "mongodb", + "creationTimestamp": null, + "labels": { + "template": "mongodb-ephemeral-template" + } + }, + "spec": { + "ports": [ + { + "name": "mongo", + "protocol": "TCP", + "port": 27017, + "targetPort": 27017 + } + ], + "selector": { + "name": "mongodb" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "ports": [ + { + "name": "3000-tcp", + "protocol": "TCP", + "port": 3000, + "targetPort": 3000 + } + ], + "selector": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + } + ], + "parameters": [ + { + "name": "MEMORY_LIMIT", + "displayName": "Memory Limit", + "description": "Maximum amount of memory the container can use.", + "value": "512Mi" + }, + { + "name": "DATABASE_SERVICE_NAME", + "displayName": "Database Service Name", + "description": "The name of the OpenShift Service exposed for the database.", + "value": "mongodb", + "required": true + }, + { + "name": "MONGODB_USER", + "displayName": "MongoDB User", + "description": "Username for MongoDB user that will be used for accessing the database.", + "generate": "expression", + "from": "user[A-Z0-9]{3}", + "required": true + }, + { + "name": "MONGODB_PASSWORD", + "displayName": "MongoDB Password", + "description": "Password for the MongoDB user.", + "generate": "expression", + "from": "[a-zA-Z0-9]{16}", + "required": true + }, + { + "name": "MONGODB_DATABASE", + "displayName": "MongoDB Database Name", + "description": "Name of the MongoDB database accessed.", + "value": "rocketchatdb", + "required": true + }, + { + "name": "ROCKETCHAT_IMAGE", + "displayName": "RocketChat Image", + "description": "The RocketChat image to use for this deployment", + "required": true, + "value": "rocketchat/rocket.chat" + }, + { + "name": "MONGODB_ADMIN_PASSWORD", + "displayName": "MongoDB Admin Password", + "description": "Password for the database admin user.", + "generate": "expression", + "from": "[a-zA-Z0-9]{16}", + "required": true + } + ] +} diff --git a/.openshift/rocket-chat-persistent.json b/.openshift/rocket-chat-persistent.json new file mode 100644 index 000000000000..fe2a992ef232 --- /dev/null +++ b/.openshift/rocket-chat-persistent.json @@ -0,0 +1,470 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "name": "rocket-chat", + "annotations": { + "description": "Rocket.Chat with a MongoDB database running with a Persistent storage. Use this template if you want to run Rocket.Chat in production.", + "tags": "quickstart,nodejs,mongodb,instant-app", + "iconClass": "icon-nodejs" + } + }, + "objects": [ + { + "kind": "PersistentVolumeClaim", + "apiVersion": "v1", + "metadata": { + "name": "${DATABASE_SERVICE_NAME}" + }, + "spec": { + "accessModes": [ + "ReadWriteOnce" + ], + "resources": { + "requests": { + "storage": "${VOLUME_CAPACITY}" + } + } + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "mongodb", + "labels": { + "template": "mongodb-persistent-template" + } + }, + "spec": { + "strategy": { + "type": "Recreate", + "recreateParams": { + "timeoutSeconds": 600 + } + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "mongodb" + ], + "from": { + "kind": "ImageStreamTag", + "namespace": "openshift", + "name": "mongodb:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "test": false, + "selector": { + "name": "mongodb" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "mongodb" + } + }, + "spec": { + "containers": [ + { + "name": "mongodb", + "image": "registry.access.redhat.com/rhscl/mongodb-26-rhel7:latest", + "ports": [ + { + "containerPort": 27017, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "MONGODB_USER", + "value": "${MONGODB_USER}" + }, + { + "name": "MONGODB_PASSWORD", + "value": "${MONGODB_PASSWORD}" + }, + { + "name": "MONGODB_DATABASE", + "value": "${MONGODB_DATABASE}" + }, + { + "name": "MONGODB_ADMIN_PASSWORD", + "value": "${MONGODB_ADMIN_PASSWORD}" + } + ], + "resources": { + "limits": { + "memory": "${MEMORY_LIMIT}" + } + }, + "volumeMounts": [ + { + "name": "mongodb-data", + "mountPath": "/var/lib/mongodb/data" + } + ], + "livenessProbe": { + "tcpSocket": { + "port": 27017 + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "mongo 127.0.0.1:27017/$MONGODB_DATABASE -u $MONGODB_USER -p $MONGODB_PASSWORD --eval=\"quit()\"" + ] + }, + "initialDelaySeconds": 3, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "IfNotPresent", + "securityContext": { + "capabilities": {}, + "privileged": false + } + } + ], + "volumes": [ + { + "name": "${DATABASE_SERVICE_NAME}-data", + "persistentVolumeClaim": { + "claimName": "${DATABASE_SERVICE_NAME}" + } + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {} + } + } + }, + "status": {} + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat" + }, + "spec": { + "dockerImageRepository": "${ROCKETCHAT_IMAGE}", + "tags": [ + { + "name": "latest", + "annotations": { + "description": "Provides a Rocket.Chat application", + "iconClass": "icon-nodejs", + "tags": "rocketchat" + }, + "from": { + "kind": "ImageStreamTag", + "name": "latest" + }, + "generation": 1, + "importPolicy": {} + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 600, + "maxUnavailable": "25%", + "maxSurge": "25%" + }, + "resources": {} + }, + "triggers": [ + { + "type": "ConfigChange" + }, + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "rocketchat" + ], + "from": { + "kind": "ImageStreamTag", + "name": "rocketchat:latest" + } + } + } + ], + "replicas": 1, + "test": false, + "selector": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "annotations": { + "openshift.io/container.rocketchat.image.entrypoint": "[\"node\",\"main.js\"]", + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "volumes": [ + { + "name": "rocketchat-volume-1", + "emptyDir": {} + } + ], + "containers": [ + { + "name": "rocketchat", + "image": "${ROCKETCHAT_IMAGE}:latest", + "ports": [ + { + "containerPort": 3000, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "MONGO_URL", + "value": "mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@mongodb:27017/${MONGODB_DATABASE}" + } + ], + "resources": {}, + "volumeMounts": [ + { + "name": "rocketchat-volume-1", + "mountPath": "/app/uploads" + } + ], + "readinessProbe": { + "httpGet": { + "path": "/api/v1/info", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "livenessProbe": { + "httpGet": { + "path": "/api/v1/info", + "port": 3000, + "scheme": "HTTP" + }, + "initialDelaySeconds": 30, + "timeoutSeconds": 1, + "periodSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "Always" + } + ], + "restartPolicy": "Always", + "terminationGracePeriodSeconds": 30, + "dnsPolicy": "ClusterFirst", + "securityContext": {} + } + } + }, + "status": {} + }, + { + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/host.generated": "true" + } + }, + "spec": { + "to": { + "kind": "Service", + "name": "rocketchat" + }, + "port": { + "targetPort": "3000-tcp" + } + }, + "status": { + "ingress": null + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "mongodb", + "creationTimestamp": null, + "labels": { + "template": "mongodb-persistent-template" + } + }, + "spec": { + "ports": [ + { + "name": "mongo", + "protocol": "TCP", + "port": 27017, + "targetPort": 27017 + } + ], + "selector": { + "name": "mongodb" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "rocketchat", + "creationTimestamp": null, + "labels": { + "app": "rocketchat" + }, + "annotations": { + "openshift.io/generated-by": "OpenShiftNewApp" + } + }, + "spec": { + "ports": [ + { + "name": "3000-tcp", + "protocol": "TCP", + "port": 3000, + "targetPort": 3000 + } + ], + "selector": { + "app": "rocketchat", + "deploymentconfig": "rocketchat" + }, + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + } + ], + "parameters": [ + { + "name": "MEMORY_LIMIT", + "displayName": "Memory Limit", + "description": "Maximum amount of memory the container can use.", + "value": "512Mi" + }, + { + "name": "DATABASE_SERVICE_NAME", + "displayName": "Database Service Name", + "description": "The name of the OpenShift Service exposed for the database.", + "value": "mongodb", + "required": true + }, + { + "name": "MONGODB_USER", + "displayName": "MongoDB User", + "description": "Username for MongoDB user that will be used for accessing the database.", + "generate": "expression", + "from": "user[A-Z0-9]{3}", + "required": true + }, + { + "name": "MONGODB_PASSWORD", + "displayName": "MongoDB Password", + "description": "Password for the MongoDB user.", + "generate": "expression", + "from": "[a-zA-Z0-9]{16}", + "required": true + }, + { + "name": "MONGODB_DATABASE", + "displayName": "MongoDB Database Name", + "description": "Name of the MongoDB database accessed.", + "value": "rocketchatdb", + "required": true + }, + { + "name": "MONGODB_ADMIN_PASSWORD", + "displayName": "MongoDB Admin Password", + "description": "Password for the database admin user.", + "generate": "expression", + "from": "[a-zA-Z0-9]{16}", + "required": true + }, + { + "name": "ROCKETCHAT_IMAGE", + "displayName": "RocketChat Image", + "description": "The RocketChat image to use for this deployment", + "required": true, + "value": "rocketchat/rocket.chat" + }, + { + "name": "VOLUME_CAPACITY", + "displayName": "Volume Capacity", + "description": "Volume space available for data, e.g. 512Mi, 2Gi.", + "value": "1Gi", + "required": true + } + ] +} diff --git a/.postcssrc b/.postcssrc new file mode 100644 index 000000000000..f0e4aa4b697e --- /dev/null +++ b/.postcssrc @@ -0,0 +1,26 @@ +{ + "plugins": { + "postcss-import": {}, + "postcss-custom-properties": { + "preserve": true + }, + "postcss-media-minmax": {}, + "postcss-selector-not": {}, + "postcss-nested": {}, + "autoprefixer": { + "browsers": [ + "ie > 10", + "last 2 Edge versions", + "last 2 Firefox versions", + "last 1 FirefoxAndroid versions", + "last 2 Chrome versions", + "last 1 ChromeAndroid versions", + "Safari > 7", + "last 2 Opera versions", + "last 2 iOS versions", + "last 1 Android version" + ] + } + }, + "excludedPackages": ["deepwell:bootstrap-datepicker2", "smoral:sweetalert"] +} diff --git a/.sandstorm/README.md b/.sandstorm/README.md new file mode 100644 index 000000000000..17e5bc5bc534 --- /dev/null +++ b/.sandstorm/README.md @@ -0,0 +1,14 @@ +# Publish commands + +``` +cd Rocket.Chat +vagrant-spk vm up && vagrant-spk dev +^C +vagrant-spk pack ../rocketchat.spk && vagrant-spk publish ../rocketchat.spk && vagrant-spk vm halt +``` + +# Reset commands + +``` +vagrant-spk vm halt && vagrant-spk vm destroy +``` diff --git a/.sandstorm/Vagrantfile b/.sandstorm/Vagrantfile index 579a4395c105..c7eee5ae79ea 100644 --- a/.sandstorm/Vagrantfile +++ b/.sandstorm/Vagrantfile @@ -9,9 +9,17 @@ VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Ti # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" +# ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442 +# this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3, +# remove entirely when confident nobody uses vagrant 1.x for anything. +unless Vagrant::DEFAULT_SERVER_URL.frozen? + Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com') +end + Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - # We base ourselves off Debian Jessie - config.vm.box = "debian/jessie64" + # Base on the Sandstorm snapshots of the official Debian 9 (stretch) box with vboxsf support. + config.vm.box = "debian/contrib-stretch64" + config.vm.box_version = "9.3.0" if Vagrant.has_plugin?("vagrant-vbguest") then # vagrant-vbguest is a Vagrant plugin that upgrades @@ -29,9 +37,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # Use a shell script to "provision" the box. This installs Sandstorm using # the bundled installer. - config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/global-setup.sh" + config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/global-setup.sh", keep_color: true # Then, do stack-specific and app-specific setup. - config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/setup.sh" + config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/setup.sh", keep_color: true # Shared folders are configured per-provider since vboxsf can't handle >4096 open files, # NFS requires privilege escalation every time you bring a VM up, @@ -82,7 +90,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| override.vm.synced_folder "..", "/opt/app" override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm" - override.vm.synced_folder "..", "/vagrant" + override.vm.synced_folder "..", "/vagrant", disabled: true end config.vm.provider :libvirt do |libvirt, override| libvirt.cpus = cpus @@ -91,6 +99,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| override.vm.synced_folder "..", "/opt/app", type: "9p", accessmode: "passthrough" override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm", type: "9p", accessmode: "passthrough" - override.vm.synced_folder "..", "/vagrant", type: "9p", accessmode: "passthrough" + override.vm.synced_folder "..", "/vagrant", type: "9p", accessmode: "passthrough", disabled: true end end diff --git a/.sandstorm/build.sh b/.sandstorm/build.sh index 50a730f64f8a..c8a155a2a351 100755 --- a/.sandstorm/build.sh +++ b/.sandstorm/build.sh @@ -1,14 +1,22 @@ #!/bin/bash -set -euo pipefail +set -x +set -euvo pipefail # Make meteor bundle - -METEOR_WAREHOUSE_DIR="${METEOR_WAREHOUSE_DIR:-$HOME/.meteor}" -METEOR_DEV_BUNDLE=$(dirname $(readlink -f "$METEOR_WAREHOUSE_DIR/meteor"))/dev_bundle - +sudo chown vagrant:vagrant /home/vagrant -R cd /opt/app +meteor npm install capnp +meteor npm install meteor build --directory /home/vagrant/ -(cd /home/vagrant/bundle/programs/server && "$METEOR_DEV_BUNDLE/bin/npm" install) + +export NODE_ENV=production +# Use npm and node from the Meteor dev bundle to install the bundle's dependencies. +TOOL_VERSION=$(meteor show --ejson $(<.meteor/release) | grep '^ *"tool":' | + sed -re 's/^.*"(meteor-tool@[^"]*)".*$/\1/g') +TOOLDIR=$(echo $TOOL_VERSION | tr @ /) +PATH=$HOME/.meteor/packages/$TOOLDIR/mt-os.linux.x86_64/dev_bundle/bin:$PATH +cd /home/vagrant/bundle/programs/server +npm install --production # Copy our launcher script into the bundle so the grain can start up. mkdir -p /home/vagrant/bundle/opt/app/.sandstorm/ diff --git a/.sandstorm/global-setup.sh b/.sandstorm/global-setup.sh index 3984f4445d28..af9d391aaac9 100755 --- a/.sandstorm/global-setup.sh +++ b/.sandstorm/global-setup.sh @@ -1,7 +1,12 @@ #!/bin/bash -set -euo pipefail +set -x +set -euvo pipefail + echo localhost > /etc/hostname hostname localhost +# Install curl that is needed below. +apt-get update +apt-get install -y curl curl https://install.sandstorm.io/ > /host-dot-sandstorm/caches/install.sh SANDSTORM_CURRENT_VERSION=$(curl -fs "https://install.sandstorm.io/dev?from=0&type=install") SANDSTORM_PACKAGE="sandstorm-$SANDSTORM_CURRENT_VERSION.tar.xz" @@ -15,9 +20,7 @@ modprobe ip_tables # `spk dev` work. usermod -a -G 'sandstorm' 'vagrant' # Bind to all addresses, so the vagrant port-forward works. -sudo sed --in-place='' \ - --expression='s/^BIND_IP=.*/BIND_IP=0.0.0.0/' \ - /opt/sandstorm/sandstorm.conf +sudo sed --in-place='' --expression='s/^BIND_IP=.*/BIND_IP=0.0.0.0/' /opt/sandstorm/sandstorm.conf # TODO: update sandstorm installer script to ask about dev accounts, and # specify a value for this option in the default config? if ! grep --quiet --no-messages ALLOW_DEV_ACCOUNTS=true /opt/sandstorm/sandstorm.conf ; then diff --git a/.sandstorm/launcher.sh b/.sandstorm/launcher.sh index 9f62691ffeee..d63b973fdbd2 100755 --- a/.sandstorm/launcher.sh +++ b/.sandstorm/launcher.sh @@ -1,4 +1,8 @@ #!/bin/bash -set -euo pipefail +set -x +set -euvo pipefail +export METEOR_SETTINGS='{"public": {"sandstorm": true}}' +export NODE_ENV=production +export SETTINGS_HIDDEN="Email,Email_Header,Email_Footer,SMTP_Host,SMTP_Port,SMTP_Username,SMTP_Password,From_Email,SMTP_Test_Button,Invitation_Customized,Invitation_Subject,Invitation_HTML,Accounts_Enrollment_Customized,Accounts_Enrollment_Email_Subject,Accounts_Enrollment_Email,Accounts_UserAddedEmail_Customized,Accounts_UserAddedEmailSubject,Accounts_UserAddedEmail,Forgot_Password_Customized,Forgot_Password_Email_Subject,Forgot_Password_Email,Verification_Customized,Verification_Email_Subject,Verification_Email" exec node /start.js -p 8000 diff --git a/.sandstorm/rocket.chat-128.svg b/.sandstorm/rocket.chat-128.svg index ed0ba57a1584..06b1893ee1e7 100644 --- a/.sandstorm/rocket.chat-128.svg +++ b/.sandstorm/rocket.chat-128.svg @@ -6,7 +6,7 @@ + + + + +
+

+ fontello + font demo +

+
+ + +
+
+
+
+
! icon-parking0x21
+
" icon-bedroom0x22
+
# icon-elevator0x23
+
$ icon-kettle0x24
+
+
+
% icon-pan0x25
+
& icon-tap0x26
+
' icon-foxter0x27
+
( icon-left-circled20x28
+
+
+
) icon-right-circled20x29
+
* icon-football0x2a
+
+ icon-tennis0x2b
+
, icon-chrome0x2c
+
+
+
- icon-opera0x2d
+
. icon-crown0x2e
+
/ icon-ie0x2f
+
0 icon-glass0x30
+
+
+
1 icon-music0x31
+
2 icon-search0x32
+
3 icon-3600x33
+
4 icon-mail0x34
+
+
+
5 icon-mail-alt0x35
+
6 icon-heart0x36
+
7 icon-heart-empty0x37
+
8 icon-camera-tour0x38
+
+
+
9 icon-hubot0x39
+
: icon-squirrel0x3a
+
; icon-clippy0x3b
+
< icon-left-dir0x3c
+
+
+
> icon-right-dir0x3e
+
? icon-star-half0x3f
+
@ icon-star-half-alt0x40
+
A icon-marquee0x41
+
+
+
B icon-user0x42
+
C icon-users0x43
+
D icon-shower0x44
+
E icon-male0x45
+
+
+
F icon-female0x46
+
G icon-video0x47
+
H icon-videocam0x48
+
I icon-picture0x49
+
+
+
J icon-camera0x4a
+
K icon-th-large0x4b
+
L icon-th0x4c
+
M icon-th-list0x4d
+
+
+
N icon-child0x4e
+
O icon-ok0x4f
+
P icon-ok-circled0x50
+
Q icon-ok-squared0x51
+
+
+
R icon-cancel0x52
+
S icon-plus0x53
+
T icon-plus-circled0x54
+
U icon-plus-squared0x55
+
+
+
V icon-plus-squared-alt0x56
+
W icon-minus0x57
+
X icon-minus-circled0x58
+
Y icon-minus-squared0x59
+
+
+
Z icon-minus-squared-alt0x5a
+
[ icon-left-open0x5b
+
\ icon-help-circled0x5c
+
] icon-right-open0x5d
+
+
+
^ icon-info0x5e
+
_ icon-home0x5f
+
` icon-link0x60
+
a icon-unlink0x61
+
+
+
b icon-link-ext0x62
+
c icon-link-ext-alt0x63
+
e icon-lock0x65
+
f icon-lock-open0x66
+
+
+
g icon-cancel-circled0x67
+
h icon-lock-open-alt0x68
+
i icon-meteor0x69
+
j icon-pin0x6a
+
+
+
k icon-eye0x6b
+
l icon-eye-off0x6c
+
m icon-gitlab0x6d
+
n icon-rocketchat0x6e
+
+
+
o icon-repo0x6f
+
p icon-tag0x70
+
q icon-spin0x71
+
r icon-firefox0x72
+
+
+
s icon-tags0x73
+
t icon-bookmark0x74
+
u icon-bookmark-empty0x75
+
v icon-flag0x76
+
+
+
w icon-flag-empty0x77
+
x icon-flag-checkered0x78
+
y icon-thumbs-up0x79
+
z icon-thumbs-down0x7a
+
+
+
{ icon-angle-left0x7b
+
| icon-checklist0x7c
+
} icon-angle-right0x7d
+
~ icon-upload0x7e
+
+
+
« icon-angle-circled-left0xab
+
» icon-angle-circled-right0xbb
+
icon-angle-double-left0x2039
+
icon-angle-double-right0x203a
+
+
+
icon-right0x2264
+
icon-left0x2265
+
icon-left-big0x2266
+
icon-right-big0x2267
+
+
+
icon-right-hand0x2268
+
icon-left-hand0x2269
+
icon-left-circled0x226a
+
icon-right-circled0x226b
+
+
+
icon-expand-right0x2276
+
icon-collapse-left0x2277
+
icon-right-open-small0x22a2
+
icon-left-open-small0x22a3
+
+
+
icon-download-cloud0xe800
+
icon-upload-cloud0xe801
+
icon-reply0xe802
+
icon-reply-all0xe803
+
+
+
icon-forward0xe804
+
icon-quote-left0xe805
+
icon-quote-right0xe806
+
icon-code0xe807
+
+
+
icon-export0xe808
+
icon-export-alt0xe809
+
icon-share0xe80a
+
icon-share-squared0xe80b
+
+
+
icon-pencil0xe80c
+
icon-pencil-squared0xe80d
+
icon-edit0xe80e
+
icon-print0xe80f
+
+
+
icon-retweet0xe810
+
icon-keyboard0xe811
+
icon-gamepad0xe812
+
icon-comment0xe813
+
+
+
icon-chat0xe814
+
icon-comment-empty0xe815
+
icon-chat-empty0xe816
+
icon-bell0xe817
+
+
+
icon-bell-alt0xe818
+
icon-bell-off0xe819
+
icon-bell-off-empty0xe81a
+
icon-attention-alt0xe81b
+
+
+
icon-attention0xe81c
+
icon-attention-circled0xe81d
+
icon-location0xe81e
+
icon-direction0xe81f
+
+
+
icon-compass0xe820
+
icon-trash-alt0xe821
+
icon-trash0xe822
+
icon-doc0xe823
+
+
+
icon-docs0xe824
+
icon-doc-text0xe825
+
icon-doc-inv0xe826
+
icon-doc-text-inv0xe827
+
+
+
icon-folder0xe828
+
icon-folder-open0xe829
+
icon-folder-empty0xe82a
+
icon-folder-open-empty0xe82b
+
+
+
icon-box0xe82c
+
icon-rss0xe82d
+
icon-rss-squared0xe82e
+
icon-phone0xe82f
+
+
+
icon-phone-squared0xe830
+
icon-fax0xe831
+
icon-menu0xe832
+
icon-cog0xe833
+
+
+
icon-cog-alt0xe834
+
icon-wrench0xe835
+
icon-sliders0xe836
+
icon-basket0xe837
+
+
+
icon-calendar0xe838
+
icon-calendar-empty0xe839
+
icon-login0xe83a
+
icon-logout0xe83b
+
+
+
icon-mic0xe83c
+
icon-mute0xe83d
+
icon-volume-off0xe83e
+
icon-volume-down0xe83f
+
+
+
icon-volume-up0xe840
+
icon-headphones0xe841
+
icon-clock0xe842
+
icon-lightbulb0xe843
+
+
+
icon-block0xe844
+
icon-resize-full0xe845
+
icon-resize-full-alt0xe846
+
icon-resize-small0xe847
+
+
+
icon-resize-vertical0xe848
+
icon-resize-horizontal0xe849
+
icon-move0xe84a
+
icon-zoom-in0xe84b
+
+
+
icon-zoom-out0xe84c
+
icon-down-circled20xe84d
+
icon-up-circled20xe84e
+
icon-help0xe84f
+
+
+
icon-info-circled0xe850
+
icon-down-dir0xe851
+
icon-up-dir0xe852
+
icon-star0xe853
+
+
+
icon-star-empty0xe854
+
icon-down-open0xe855
+
icon-gym0xe856
+
icon-sports0xe857
+
+
+
icon-up-open0xe858
+
icon-browser0xe859
+
icon-download0xe85a
+
icon-angle-up0xe85b
+
+
+
icon-angle-down0xe85c
+
icon-language0xe85d
+
icon-angle-circled-up0xe85f
+
icon-angle-circled-down0xe860
+
+
+
icon-angle-double-up0xe863
+
icon-angle-double-down0xe864
+
icon-down0xe865
+
icon-up0xe868
+
+
+
icon-down-big0xe869
+
icon-up-big0xe86c
+
icon-up-hand0xe86f
+
icon-down-hand0xe870
+
+
+
icon-up-circled0xe873
+
icon-down-circled0xe874
+
icon-cw0xe875
+
icon-ccw0xe876
+
+
+
icon-arrows-cw0xe877
+
icon-level-up0xe878
+
icon-level-down0xe879
+
icon-shuffle0xe87a
+
+
+
icon-exchange0xe87b
+
icon-history0xe87c
+
icon-expand0xe87d
+
icon-collapse0xe87e
+
+
+
icon-play0xe881
+
icon-play-circled0xe882
+
icon-play-circled20xe883
+
icon-stop0xe884
+
+
+
icon-pause0xe885
+
icon-to-end0xe886
+
icon-to-end-alt0xe887
+
icon-to-start0xe888
+
+
+
icon-to-start-alt0xe889
+
icon-fast-fw0xe88a
+
icon-fast-bw0xe88b
+
icon-eject0xe88c
+
+
+
icon-target0xe88d
+
icon-signal0xe88e
+
icon-award0xe88f
+
icon-desktop0xe890
+
+
+
icon-laptop0xe891
+
icon-tablet0xe892
+
icon-mobile0xe893
+
icon-inbox0xe894
+
+
+
icon-globe0xe895
+
icon-sun0xe896
+
icon-cloud0xe897
+
icon-flash0xe898
+
+
+
icon-moon0xe899
+
icon-umbrella0xe89a
+
icon-flight0xe89b
+
icon-tasklist0xe89c
+
+
+
icon-paper-plane0xe89d
+
icon-leaf0xe89e
+
icon-font0xe89f
+
icon-bold0xe8a0
+
+
+
icon-italic0xe8a1
+
icon-paragraph0xe8a2
+
icon-text-height0xe8a3
+
icon-text-width0xe8a4
+
+
+
icon-align-left0xe8a5
+
icon-align-center0xe8a6
+
icon-align-right0xe8a7
+
icon-align-justify0xe8a8
+
+
+
icon-list0xe8a9
+
icon-indent-left0xe8aa
+
icon-indent-right0xe8ab
+
icon-list-bullet0xe8ac
+
+
+
icon-list-numbered0xe8ad
+
icon-strike0xe8ae
+
icon-underline0xe8af
+
icon-superscript0xe8b0
+
+
+
icon-subscript0xe8b1
+
icon-table0xe8b2
+
icon-columns0xe8b3
+
icon-crop0xe8b4
+
+
+
icon-scissors0xe8b5
+
icon-paste0xe8b6
+
icon-briefcase0xe8b7
+
icon-suitcase0xe8b8
+
+
+
icon-ellipsis0xe8b9
+
icon-ellipsis-vert0xe8ba
+
icon-off0xe8bb
+
icon-road0xe8bc
+
+
+
icon-list-alt0xe8bd
+
icon-qrcode0xe8be
+
icon-barcode0xe8bf
+
icon-book0xe8c0
+
+
+
icon-ajust0xe8c1
+
icon-tint0xe8c2
+
icon-toggle-off0xe8c3
+
icon-toggle-on0xe8c4
+
+
+
icon-check0xe8c5
+
icon-check-empty0xe8c6
+
icon-circle0xe8c7
+
icon-circle-empty0xe8c8
+
+
+
icon-circle-notch0xe8c9
+
icon-dot-circled0xe8ca
+
icon-asterisk0xe8cb
+
icon-gift0xe8cc
+
+
+
icon-fire0xe8cd
+
icon-magnet0xe8ce
+
icon-chart-bar0xe8cf
+
icon-chart-area0xe8d0
+
+
+
icon-chart-pie0xe8d1
+
icon-chart-line0xe8d2
+
icon-ticket0xe8d3
+
icon-credit-card0xe8d4
+
+
+
icon-floppy0xe8d5
+
icon-megaphone0xe8d6
+
icon-hdd0xe8d7
+
icon-fork0xe8d9
+
+
+
icon-rocket0xe8da
+
icon-bug0xe8db
+
icon-certificate0xe8dc
+
icon-tasks0xe8dd
+
+
+
icon-filter0xe8de
+
icon-beaker0xe8df
+
icon-magic0xe8e0
+
icon-cab0xe8e1
+
+
+
icon-taxi0xe8e2
+
icon-truck0xe8e3
+
icon-bus0xe8e4
+
icon-bicycle0xe8e5
+
+
+
icon-money0xe8e6
+
icon-euro0xe8e7
+
icon-pound0xe8e8
+
icon-dollar0xe8e9
+
+
+
icon-sort0xe8ea
+
icon-sort-down0xe8eb
+
icon-sort-up0xe8ec
+
icon-sort-alt-up0xe8ed
+
+
+
icon-sort-alt-down0xe8ee
+
icon-sort-name-up0xe8ef
+
icon-sort-name-down0xe8f0
+
icon-sort-number-up0xe8f1
+
+
+
icon-sort-number-down0xe8f2
+
icon-hammer0xe8f3
+
icon-gauge0xe8f4
+
icon-sitemap0xe8f5
+
+
+
icon-spinner0xe8f6
+
icon-coffee0xe8f7
+
icon-food0xe8f8
+
icon-beer0xe8f9
+
+
+
icon-user-md0xe8fa
+
icon-stethoscope0xe8fb
+
icon-ambulance0xe8fc
+
icon-medkit0xe8fd
+
+
+
icon-h-sigh0xe8fe
+
icon-hospital0xe8ff
+
icon-building0xe900
+
icon-building-filled0xe901
+
+
+
icon-bank0xe902
+
icon-smile0xe903
+
icon-frown0xe904
+
icon-meh0xe905
+
+
+
icon-anchor0xe906
+
icon-terminal0xe907
+
icon-eraser0xe908
+
icon-puzzle0xe909
+
+
+
icon-shield0xe90a
+
icon-extinguisher0xe90b
+
icon-bullseye0xe90c
+
icon-wheelchair0xe90d
+
+
+
icon-attach0xe90e
+
icon-paw0xe90f
+
icon-spoon0xe910
+
icon-cube0xe911
+
+
+
icon-cubes0xe912
+
icon-recycle0xe913
+
icon-tree0xe914
+
icon-database0xe915
+
+
+
icon-lifebuoy0xe916
+
icon-birthday0xe917
+
icon-adn0xe918
+
icon-android0xe919
+
+
+
icon-angellist0xe91a
+
icon-apple0xe91b
+
icon-behance0xe91c
+
icon-bitbucket0xe91d
+
+
+
icon-bitbucket-squared0xe91e
+
icon-css30xe91f
+
icon-delicious0xe920
+
icon-digg0xe921
+
+
+
icon-dribbble0xe922
+
icon-dropbox0xe923
+
icon-facebook0xe924
+
icon-facebook-squared0xe925
+
+
+
icon-flickr0xe926
+
icon-foursquare0xe927
+
icon-git-squared0xe928
+
icon-github-circled0xe929
+
+
+
icon-gittip0xe92a
+
icon-google0xe92b
+
icon-gplus0xe92c
+
icon-gplus-squared0xe92d
+
+
+
icon-html50xe92e
+
icon-instagramm0xe92f
+
icon-linkedin-squared0xe930
+
icon-linux0xe931
+
+
+
icon-linkedin0xe932
+
icon-pagelines0xe933
+
icon-pied-piper-squared0xe934
+
icon-pinterest-circled0xe935
+
+
+
icon-pinterest-squared0xe936
+
icon-renren0xe937
+
icon-skype0xe938
+
icon-slideshare0xe939
+
+
+
icon-stackexchange0xe93a
+
icon-stackoverflow0xe93b
+
icon-trello0xe93c
+
icon-tumblr0xe93d
+
+
+
icon-tumblr-squared0xe93e
+
 icon-twitter-squared0xe93f
+
icon-twitter0xe940
+
icon-vimeo-squared0xe941
+
+
+
icon-windows0xe942
+
icon-wordpress0xe943
+
icon-youtube0xe944
+
icon-youtube-squared0xe945
+
+
+
icon-youtube-play0xe946
+
icon-blank0xe947
+
icon-lemon0xe948
+
icon-note0xe949
+
+
+
icon-note-beamed0xe94a
+
icon-alert0xe94c
+
icon-graduation-cap0xe94f
+
icon-water0xe950
+
+
+
icon-droplet0xe951
+
icon-key0xe952
+
icon-infinity0xe953
+
icon-at0xe956
+
+
+
icon-money-bag0xe957
+
icon-hash0xe958
+
icon-airport0xe959
+
icon-fast-food0xe95a
+
+
+
icon-fuel0xe95b
+
icon-police0xe95c
+
icon-religious-christian0xe95d
+
icon-religious-islam0xe95e
+
+
+
icon-religious-jewish0xe95f
+
icon-school0xe960
+
icon-swimming0xe961
+
icon-toilet0xe962
+
+
+
icon-universal-access0xe964
+
icon-travel0xe966
+
icon-symbols0xe967
+
icon-recent0xe968
+
+
+
icon-people0xe969
+
icon-objects0xe96a
+
icon-nature0xe96b
+
icon-foods0xe96c
+
+
+
icon-activity0xe96d
+
icon-flags0xe96e
+
icon-people-plus0xe96f
+
icon-file-pdf0xe970
+
+
+
icon-file-word0xe971
+
icon-file-excel0xe972
+
icon-file-powerpoint0xe973
+
icon-file-image0xe974
+
+
+
icon-file-archive0xe975
+
icon-file-audio0xe976
+
icon-file-video0xe977
+
icon-file-code0xe978
+
+
+
icon-issue-closed0xe979
+
icon-issue-opened0xe97a
+
icon-issue-reopened0xe97b
+
icon-milestone0xe97c
+
+
+
icon-mirror0xe97d
+
icon-plug0xe97e
+
icon-repo-forked0xe980
+
icon-repo-pull0xe981
+
+
+
icon-repo-push0xe982
+
icon-shield-key0xe983
+
icon-repo-clone0xe984
+
icon-repo-force-push0xe985
+
+
+
icon-unverified0xe986
+
icon-verified0xe987
+
icon-zap0xe988
+
icon-pulse0xe989
+
+
+
icon-versions0xe98a
+
icon-text-size0xe98b
+
icon-markdown0xe98c
+
icon-no-newline0xe98d
+
+
+
icon-tools0xe98e
+
icon-tape0xe98f
+
+
+ + + \ No newline at end of file diff --git a/packages/rocketchat-theme/client/vendor/fontello/font/fontello.eot b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.eot new file mode 100755 index 000000000000..72e4e0191fda Binary files /dev/null and b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.eot differ diff --git a/packages/rocketchat-theme/client/vendor/fontello/font/fontello.svg b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.svg new file mode 100755 index 000000000000..3c7a411f3c96 --- /dev/null +++ b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.svg @@ -0,0 +1,982 @@ + + + +Copyright (C) 2017 by original authors @ fontello.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/rocketchat-theme/client/vendor/fontello/font/fontello.ttf b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.ttf new file mode 100755 index 000000000000..00cff8162073 Binary files /dev/null and b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.ttf differ diff --git a/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff new file mode 100755 index 000000000000..a3d61addff86 Binary files /dev/null and b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff differ diff --git a/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff2 b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff2 new file mode 100755 index 000000000000..d50977328866 Binary files /dev/null and b/packages/rocketchat-theme/client/vendor/fontello/font/fontello.woff2 differ diff --git a/packages/rocketchat-theme/client/vendor/fontello/utf8-rtl.html b/packages/rocketchat-theme/client/vendor/fontello/utf8-rtl.html new file mode 100644 index 000000000000..3078f200085e --- /dev/null +++ b/packages/rocketchat-theme/client/vendor/fontello/utf8-rtl.html @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
((&lpar;&#00028;&#29;&#40;()LEFT PARENTHESIS
<<&lt; &LT;&#0003C;&#3E;&#60;<>LESS-THAN SIGN
[[&lsqb; &lbrack;&#0005B;&#5D;&#91;[]LEFT SQUARE BRACKET
{{&lcub; &lbrace;&#0007B;&#7D;&#123;{}LEFT CURLY BRACKET
««&laquo;&#000AB;&#BB;&#171;«»LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
&lsaquo;&#02039;&#203A;&#8249;SINGLE LEFT-POINTING ANGLE QUOTATION MARK
&le; &leq;&#02264;&#2265;&#8804;LESS-THAN OR EQUAL TO
&lE; &LessFullEqual; &leqq;&#02266;&#2267;&#8806;LESS-THAN OVER EQUAL TO
&lnE; &lneqq;&#02268;&#2269;&#8808;LESS-THAN BUT NOT EQUAL TO
&Lt; &NestedLessLess; &ll;&#0226A;&#226B;&#8810;MUCH LESS-THAN
&lsim; &LessTilde; &lesssim;&#02272;&#2273;&#8818;LESS-THAN OR EQUIVALENT TO
&lg; &lessgtr; &LessGreater;&#02276;&#2277;&#8822;LESS-THAN OR GREATER-THAN
&dashv; &LeftTee;&#022A3;&#22A2;&#8867;LEFT TACK
&vltri; &vartriangleleft; &LeftTriangle;&#022B2;&#22B3;&#8882;NORMAL SUBGROUP OF
&ltrie; &trianglelefteq; &LeftTriangleEqual;&#022B4;&#22B5;&#8884;NORMAL SUBGROUP OF OR EQUAL TO
&ltimes;&#022C9;&#22CA;&#8905;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT
&lthree; &leftthreetimes;&#022CB;&#22CC;&#8907;LEFT SEMIDIRECT PRODUCT
&ltdot; &lessdot;&#022D6;&#22D7;&#8918;LESS-THAN WITH DOT
&Ll;&#022D8;&#22D9;&#8920;VERY MUCH LESS-THAN
&leg; &LessEqualGreater; &lesseqgtr;&#022DA;&#22DB;&#8922;LESS-THAN EQUAL TO OR GREATER-THAN
&lnsim;&#022E6;&#22E7;&#8934;LESS-THAN BUT NOT EQUIVALENT TO
&lceil; &LeftCeiling;&#02308;&#2309;&#8968;LEFT CEILING
&lfloor; &LeftFloor;&#0230A;&#230B;&#8970;LEFT FLOOR
&lbbrk;&#02772;&#2773;&#10098;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
&lobrk; &LeftDoubleBracket;&#027E6;&#27E7;&#10214;MATHEMATICAL LEFT WHITE SQUARE BRACKET
&lang; &LeftAngleBracket; &langle;&#027E8;&#27E9;&#10216;MATHEMATICAL LEFT ANGLE BRACKET
&Lang;&#027EA;&#27EB;&#10218;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
&loang;&#027EC;&#27ED;&#10220;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
&lopar;&#02985;&#2986;&#10629;LEFT WHITE PARENTHESIS
&lbrke;&#0298B;&#298C;&#10635;LEFT SQUARE BRACKET WITH UNDERBAR
&lbrkslu;&#0298D;&#2990;&#10637;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
&lbrksld;&#0298F;&#298E;&#10639;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
&langd;&#02991;&#2992;&#10641;LEFT ANGLE BRACKET WITH DOT
&lparlt;&#02993;&#2994;&#10643;LEFT ARC LESS-THAN BRACKET
&ltrPar;&#02996;&#2995;&#10646;DOUBLE RIGHT ARC LESS-THAN BRACKET
&#2998;&#10647;
&LeftTriangleBar;&#029CF;&#29D0;&#10703;LEFT TRIANGLE BESIDE VERTICAL BAR
&loplus;&#02A2D;&#2A2E;&#10797;PLUS SIGN IN LEFT HALF CIRCLE
&lotimes;&#02A34;&#2A35;&#10804;MULTIPLICATION SIGN IN LEFT HALF CIRCLE
&ltcir;&#02A79;&#2A7A;&#10873;LESS-THAN WITH CIRCLE INSIDE
&les; &LessSlantEqual; &leqslant;&#02A7D;&#2A7E;&#10877;LESS-THAN OR SLANTED EQUAL TO
⩿⩿&lesdot;&#02A7F;&#2A80;&#10879;⩿LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE
&lesdoto;&#02A81;&#2A82;&#10881;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE
&lesdotor;&#02A83;&#2A84;&#10883;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT
&lEg; &lesseqqgtr;&#02A8B;&#2A8C;&#10891;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN
&lgE;&#02A91;&#2A92;&#10897;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL
&lesges;&#02A93;&#2A94;&#10899;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL
&LessLess;&#02AA1;&#2AA2;&#10913;DOUBLE NESTED LESS-THAN
&ltcc;&#02AA6;&#2AA7;&#10918;LESS-THAN CLOSED BY CURVE
&lescc;&#02AA8;&#2AA9;&#10920;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL
&lat;&#02AAB;&#2AAA;&#10923;LARGER THAN
&late;&#02AAD;&#2AAC;&#10925;LARGER THAN OR EQUAL TO
diff --git a/packages/rocketchat-theme/client/vendor/jscolor.js b/packages/rocketchat-theme/client/vendor/jscolor.js new file mode 100644 index 000000000000..8d65d83740ef --- /dev/null +++ b/packages/rocketchat-theme/client/vendor/jscolor.js @@ -0,0 +1,1844 @@ +/** + * jscolor - JavaScript Color Picker + * + * @link http://jscolor.com + * @license For open source use: GPLv3 + * For commercial use: JSColor Commercial License + * @author Jan Odvarko + * @version 2.0.4 + * + * See usage examples at http://jscolor.com/examples/ + */ + + +"use strict"; + + +if (!window.jscolor) { window.jscolor = (function () { + + +var jsc = { + + + register : function () { + jsc.attachDOMReadyEvent(jsc.init); + jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown); + jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart); + jsc.attachEvent(window, 'resize', jsc.onWindowResize); + }, + + + init : function () { + if (jsc.jscolor.lookupClass) { + jsc.jscolor.installByClassName(jsc.jscolor.lookupClass); + } + }, + + + tryInstallOnElements : function (elms, className) { + var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i'); + + for (var i = 0; i < elms.length; i += 1) { + if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') { + if (jsc.isColorAttrSupported) { + // skip inputs of type 'color' if supported by the browser + continue; + } + } + var m; + if (!elms[i].jscolor && elms[i].className && (m = elms[i].className.match(matchClass))) { + var targetElm = elms[i]; + var optsStr = null; + + var dataOptions = jsc.getDataAttr(targetElm, 'jscolor'); + if (dataOptions !== null) { + optsStr = dataOptions; + } else if (m[4]) { + optsStr = m[4]; + } + + var opts = {}; + if (optsStr) { + try { + opts = (new Function ('return (' + optsStr + ')'))(); + } catch(eParseError) { + jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr); + } + } + targetElm.jscolor = new jsc.jscolor(targetElm, opts); + } + } + }, + + + isColorAttrSupported : (function () { + var elm = document.createElement('input'); + if (elm.setAttribute) { + elm.setAttribute('type', 'color'); + if (elm.type.toLowerCase() == 'color') { + return true; + } + } + return false; + })(), + + + isCanvasSupported : (function () { + var elm = document.createElement('canvas'); + return !!(elm.getContext && elm.getContext('2d')); + })(), + + + fetchElement : function (mixed) { + return typeof mixed === 'string' ? document.getElementById(mixed) : mixed; + }, + + + isElementType : function (elm, type) { + return elm.nodeName.toLowerCase() === type.toLowerCase(); + }, + + + getDataAttr : function (el, name) { + var attrName = 'data-' + name; + var attrValue = el.getAttribute(attrName); + if (attrValue !== null) { + return attrValue; + } + return null; + }, + + + attachEvent : function (el, evnt, func) { + if (el.addEventListener) { + el.addEventListener(evnt, func, false); + } else if (el.attachEvent) { + el.attachEvent('on' + evnt, func); + } + }, + + + detachEvent : function (el, evnt, func) { + if (el.removeEventListener) { + el.removeEventListener(evnt, func, false); + } else if (el.detachEvent) { + el.detachEvent('on' + evnt, func); + } + }, + + + _attachedGroupEvents : {}, + + + attachGroupEvent : function (groupName, el, evnt, func) { + if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) { + jsc._attachedGroupEvents[groupName] = []; + } + jsc._attachedGroupEvents[groupName].push([el, evnt, func]); + jsc.attachEvent(el, evnt, func); + }, + + + detachGroupEvents : function (groupName) { + if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) { + for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) { + var evt = jsc._attachedGroupEvents[groupName][i]; + jsc.detachEvent(evt[0], evt[1], evt[2]); + } + delete jsc._attachedGroupEvents[groupName]; + } + }, + + + attachDOMReadyEvent : function (func) { + var fired = false; + var fireOnce = function () { + if (!fired) { + fired = true; + func(); + } + }; + + if (document.readyState === 'complete') { + setTimeout(fireOnce, 1); // async + return; + } + + if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', fireOnce, false); + + // Fallback + window.addEventListener('load', fireOnce, false); + + } else if (document.attachEvent) { + // IE + document.attachEvent('onreadystatechange', function () { + if (document.readyState === 'complete') { + document.detachEvent('onreadystatechange', arguments.callee); + fireOnce(); + } + }) + + // Fallback + window.attachEvent('onload', fireOnce); + + // IE7/8 + if (document.documentElement.doScroll && window == window.top) { + var tryScroll = function () { + if (!document.body) { return; } + try { + document.documentElement.doScroll('left'); + fireOnce(); + } catch (e) { + setTimeout(tryScroll, 1); + } + }; + tryScroll(); + } + } + }, + + + warn : function (msg) { + if (window.console && window.console.warn) { + window.console.warn(msg); + } + }, + + + preventDefault : function (e) { + if (e.preventDefault) { e.preventDefault(); } + e.returnValue = false; + }, + + + captureTarget : function (target) { + // IE + if (target.setCapture) { + jsc._capturedTarget = target; + jsc._capturedTarget.setCapture(); + } + }, + + + releaseTarget : function () { + // IE + if (jsc._capturedTarget) { + jsc._capturedTarget.releaseCapture(); + jsc._capturedTarget = null; + } + }, + + + fireEvent : function (el, evnt) { + if (!el) { + return; + } + if (document.createEvent) { + var ev = document.createEvent('HTMLEvents'); + ev.initEvent(evnt, true, true); + el.dispatchEvent(ev); + } else if (document.createEventObject) { + var ev = document.createEventObject(); + el.fireEvent('on' + evnt, ev); + } else if (el['on' + evnt]) { // alternatively use the traditional event model + el['on' + evnt](); + } + }, + + + classNameToList : function (className) { + return className.replace(/^\s+|\s+$/g, '').split(/\s+/); + }, + + + // The className parameter (str) can only contain a single class name + hasClass : function (elm, className) { + if (!className) { + return false; + } + return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' '); + }, + + + // The className parameter (str) can contain multiple class names separated by whitespace + setClass : function (elm, className) { + var classList = jsc.classNameToList(className); + for (var i = 0; i < classList.length; i += 1) { + if (!jsc.hasClass(elm, classList[i])) { + elm.className += (elm.className ? ' ' : '') + classList[i]; + } + } + }, + + + // The className parameter (str) can contain multiple class names separated by whitespace + unsetClass : function (elm, className) { + var classList = jsc.classNameToList(className); + for (var i = 0; i < classList.length; i += 1) { + var repl = new RegExp( + '^\\s*' + classList[i] + '\\s*|' + + '\\s*' + classList[i] + '\\s*$|' + + '\\s+' + classList[i] + '(\\s+)', + 'g' + ); + elm.className = elm.className.replace(repl, '$1'); + } + }, + + + getStyle : function (elm) { + return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle; + }, + + + setStyle : (function () { + var helper = document.createElement('div'); + var getSupportedProp = function (names) { + for (var i = 0; i < names.length; i += 1) { + if (names[i] in helper.style) { + return names[i]; + } + } + }; + var props = { + borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']), + boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow']) + }; + return function (elm, prop, value) { + switch (prop.toLowerCase()) { + case 'opacity': + var alphaOpacity = Math.round(parseFloat(value) * 100); + elm.style.opacity = value; + elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')'; + break; + default: + elm.style[props[prop]] = value; + break; + } + }; + })(), + + + setBorderRadius : function (elm, value) { + jsc.setStyle(elm, 'borderRadius', value || '0'); + }, + + + setBoxShadow : function (elm, value) { + jsc.setStyle(elm, 'boxShadow', value || 'none'); + }, + + + getElementPos : function (e, relativeToViewport) { + var x=0, y=0; + var rect = e.getBoundingClientRect(); + x = rect.left; + y = rect.top; + if (!relativeToViewport) { + var viewPos = jsc.getViewPos(); + x += viewPos[0]; + y += viewPos[1]; + } + return [x, y]; + }, + + + getElementSize : function (e) { + return [e.offsetWidth, e.offsetHeight]; + }, + + + // get pointer's X/Y coordinates relative to viewport + getAbsPointerPos : function (e) { + if (!e) { e = window.event; } + var x = 0, y = 0; + if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) { + // touch devices + x = e.changedTouches[0].clientX; + y = e.changedTouches[0].clientY; + } else if (typeof e.clientX === 'number') { + x = e.clientX; + y = e.clientY; + } + return { x: x, y: y }; + }, + + + // get pointer's X/Y coordinates relative to target element + getRelPointerPos : function (e) { + if (!e) { e = window.event; } + var target = e.target || e.srcElement; + var targetRect = target.getBoundingClientRect(); + + var x = 0, y = 0; + + var clientX = 0, clientY = 0; + if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) { + // touch devices + clientX = e.changedTouches[0].clientX; + clientY = e.changedTouches[0].clientY; + } else if (typeof e.clientX === 'number') { + clientX = e.clientX; + clientY = e.clientY; + } + + x = clientX - targetRect.left; + y = clientY - targetRect.top; + return { x: x, y: y }; + }, + + + getViewPos : function () { + var doc = document.documentElement; + return [ + (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0), + (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0) + ]; + }, + + + getViewSize : function () { + var doc = document.documentElement; + return [ + (window.innerWidth || doc.clientWidth), + (window.innerHeight || doc.clientHeight), + ]; + }, + + + redrawPosition : function () { + + if (jsc.picker && jsc.picker.owner) { + var thisObj = jsc.picker.owner; + + var tp, vp; + + if (thisObj.fixed) { + // Fixed elements are positioned relative to viewport, + // therefore we can ignore the scroll offset + tp = jsc.getElementPos(thisObj.targetElement, true); // target pos + vp = [0, 0]; // view pos + } else { + tp = jsc.getElementPos(thisObj.targetElement); // target pos + vp = jsc.getViewPos(); // view pos + } + + var ts = jsc.getElementSize(thisObj.targetElement); // target size + var vs = jsc.getViewSize(); // view size + var ps = jsc.getPickerOuterDims(thisObj); // picker size + var a, b, c; + switch (thisObj.position.toLowerCase()) { + case 'left': a=1; b=0; c=-1; break; + case 'right':a=1; b=0; c=1; break; + case 'top': a=0; b=1; c=-1; break; + default: a=0; b=1; c=1; break; + } + var l = (ts[b]+ps[b])/2; + + // compute picker position + if (!thisObj.smartPosition) { + var pp = [ + tp[a], + tp[b]+ts[b]-l+l*c + ]; + } else { + var pp = [ + -vp[a]+tp[a]+ps[a] > vs[a] ? + (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) : + tp[a], + -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ? + (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) : + (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c) + ]; + } + + var x = pp[a]; + var y = pp[b]; + var positionValue = thisObj.fixed ? 'fixed' : 'absolute'; + var contractShadow = + (pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) && + (pp[1] + ps[1] < tp[1] + ts[1]); + + jsc._drawPosition(thisObj, x, y, positionValue, contractShadow); + } + }, + + + _drawPosition : function (thisObj, x, y, positionValue, contractShadow) { + var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px + + jsc.picker.wrap.style.position = positionValue; + jsc.picker.wrap.style.left = x + 'px'; + jsc.picker.wrap.style.top = y + 'px'; + + jsc.setBoxShadow( + jsc.picker.boxS, + thisObj.shadow ? + new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) : + null); + }, + + + getPickerDims : function (thisObj) { + var displaySlider = !!jsc.getSliderComponent(thisObj); + var dims = [ + 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width + + (displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0), + 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height + + (thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0) + ]; + return dims; + }, + + + getPickerOuterDims : function (thisObj) { + var dims = jsc.getPickerDims(thisObj); + return [ + dims[0] + 2 * thisObj.borderWidth, + dims[1] + 2 * thisObj.borderWidth + ]; + }, + + + getPadToSliderPadding : function (thisObj) { + return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness)); + }, + + + getPadYComponent : function (thisObj) { + switch (thisObj.mode.charAt(1).toLowerCase()) { + case 'v': return 'v'; break; + } + return 's'; + }, + + + getSliderComponent : function (thisObj) { + if (thisObj.mode.length > 2) { + switch (thisObj.mode.charAt(2).toLowerCase()) { + case 's': return 's'; break; + case 'v': return 'v'; break; + } + } + return null; + }, + + + onDocumentMouseDown : function (e) { + if (!e) { e = window.event; } + var target = e.target || e.srcElement; + + if (target._jscLinkedInstance) { + if (target._jscLinkedInstance.showOnClick) { + target._jscLinkedInstance.show(); + } + } else if (target._jscControlName) { + jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse'); + } else { + // Mouse is outside the picker controls -> hide the color picker! + if (jsc.picker && jsc.picker.owner) { + jsc.picker.owner.hide(); + } + } + }, + + + onDocumentTouchStart : function (e) { + if (!e) { e = window.event; } + var target = e.target || e.srcElement; + + if (target._jscLinkedInstance) { + if (target._jscLinkedInstance.showOnClick) { + target._jscLinkedInstance.show(); + } + } else if (target._jscControlName) { + jsc.onControlPointerStart(e, target, target._jscControlName, 'touch'); + } else { + if (jsc.picker && jsc.picker.owner) { + jsc.picker.owner.hide(); + } + } + }, + + + onWindowResize : function (e) { + jsc.redrawPosition(); + }, + + + onParentScroll : function (e) { + // hide the picker when one of the parent elements is scrolled + if (jsc.picker && jsc.picker.owner) { + jsc.picker.owner.hide(); + } + }, + + + _pointerMoveEvent : { + mouse: 'mousemove', + touch: 'touchmove' + }, + _pointerEndEvent : { + mouse: 'mouseup', + touch: 'touchend' + }, + + + _pointerOrigin : null, + _capturedTarget : null, + + + onControlPointerStart : function (e, target, controlName, pointerType) { + var thisObj = target._jscInstance; + + jsc.preventDefault(e); + jsc.captureTarget(target); + + var registerDragEvents = function (doc, offset) { + jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType], + jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset)); + jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType], + jsc.onDocumentPointerEnd(e, target, controlName, pointerType)); + }; + + registerDragEvents(document, [0, 0]); + + if (window.parent && window.frameElement) { + var rect = window.frameElement.getBoundingClientRect(); + var ofs = [-rect.left, -rect.top]; + registerDragEvents(window.parent.window.document, ofs); + } + + var abs = jsc.getAbsPointerPos(e); + var rel = jsc.getRelPointerPos(e); + jsc._pointerOrigin = { + x: abs.x - rel.x, + y: abs.y - rel.y + }; + + switch (controlName) { + case 'pad': + // if the slider is at the bottom, move it up + switch (jsc.getSliderComponent(thisObj)) { + case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break; + case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break; + } + jsc.setPad(thisObj, e, 0, 0); + break; + + case 'sld': + jsc.setSld(thisObj, e, 0); + break; + } + + jsc.dispatchFineChange(thisObj); + }, + + + onDocumentPointerMove : function (e, target, controlName, pointerType, offset) { + return function (e) { + var thisObj = target._jscInstance; + switch (controlName) { + case 'pad': + if (!e) { e = window.event; } + jsc.setPad(thisObj, e, offset[0], offset[1]); + jsc.dispatchFineChange(thisObj); + break; + + case 'sld': + if (!e) { e = window.event; } + jsc.setSld(thisObj, e, offset[1]); + jsc.dispatchFineChange(thisObj); + break; + } + } + }, + + + onDocumentPointerEnd : function (e, target, controlName, pointerType) { + return function (e) { + var thisObj = target._jscInstance; + jsc.detachGroupEvents('drag'); + jsc.releaseTarget(); + // Always dispatch changes after detaching outstanding mouse handlers, + // in case some user interaction will occur in user's onchange callback + // that would intrude with current mouse events + jsc.dispatchChange(thisObj); + }; + }, + + + dispatchChange : function (thisObj) { + if (thisObj.valueElement) { + if (jsc.isElementType(thisObj.valueElement, 'input')) { + jsc.fireEvent(thisObj.valueElement, 'change'); + } + } + }, + + + dispatchFineChange : function (thisObj) { + if (thisObj.onFineChange) { + var callback; + if (typeof thisObj.onFineChange === 'string') { + callback = new Function (thisObj.onFineChange); + } else { + callback = thisObj.onFineChange; + } + callback.call(thisObj); + } + }, + + + setPad : function (thisObj, e, ofsX, ofsY) { + var pointerAbs = jsc.getAbsPointerPos(e); + var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth; + var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth; + + var xVal = x * (360 / (thisObj.width - 1)); + var yVal = 100 - (y * (100 / (thisObj.height - 1))); + + switch (jsc.getPadYComponent(thisObj)) { + case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break; + case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break; + } + }, + + + setSld : function (thisObj, e, ofsY) { + var pointerAbs = jsc.getAbsPointerPos(e); + var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth; + + var yVal = 100 - (y * (100 / (thisObj.height - 1))); + + switch (jsc.getSliderComponent(thisObj)) { + case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break; + case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break; + } + }, + + + _vmlNS : 'jsc_vml_', + _vmlCSS : 'jsc_vml_css_', + _vmlReady : false, + + + initVML : function () { + if (!jsc._vmlReady) { + // init VML namespace + var doc = document; + if (!doc.namespaces[jsc._vmlNS]) { + doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml'); + } + if (!doc.styleSheets[jsc._vmlCSS]) { + var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image']; + var ss = doc.createStyleSheet(); + ss.owningElement.id = jsc._vmlCSS; + for (var i = 0; i < tags.length; i += 1) { + ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);'); + } + } + jsc._vmlReady = true; + } + }, + + + createPalette : function () { + + var paletteObj = { + elm: null, + draw: null + }; + + if (jsc.isCanvasSupported) { + // Canvas implementation for modern browsers + + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + + var drawFunc = function (width, height, type) { + canvas.width = width; + canvas.height = height; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0); + hGrad.addColorStop(0 / 6, '#F00'); + hGrad.addColorStop(1 / 6, '#FF0'); + hGrad.addColorStop(2 / 6, '#0F0'); + hGrad.addColorStop(3 / 6, '#0FF'); + hGrad.addColorStop(4 / 6, '#00F'); + hGrad.addColorStop(5 / 6, '#F0F'); + hGrad.addColorStop(6 / 6, '#F00'); + + ctx.fillStyle = hGrad; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height); + switch (type.toLowerCase()) { + case 's': + vGrad.addColorStop(0, 'rgba(255,255,255,0)'); + vGrad.addColorStop(1, 'rgba(255,255,255,1)'); + break; + case 'v': + vGrad.addColorStop(0, 'rgba(0,0,0,0)'); + vGrad.addColorStop(1, 'rgba(0,0,0,1)'); + break; + } + ctx.fillStyle = vGrad; + ctx.fillRect(0, 0, canvas.width, canvas.height); + }; + + paletteObj.elm = canvas; + paletteObj.draw = drawFunc; + + } else { + // VML fallback for IE 7 and 8 + + jsc.initVML(); + + var vmlContainer = document.createElement('div'); + vmlContainer.style.position = 'relative'; + vmlContainer.style.overflow = 'hidden'; + + var hGrad = document.createElement(jsc._vmlNS + ':fill'); + hGrad.type = 'gradient'; + hGrad.method = 'linear'; + hGrad.angle = '90'; + hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0' + + var hRect = document.createElement(jsc._vmlNS + ':rect'); + hRect.style.position = 'absolute'; + hRect.style.left = -1 + 'px'; + hRect.style.top = -1 + 'px'; + hRect.stroked = false; + hRect.appendChild(hGrad); + vmlContainer.appendChild(hRect); + + var vGrad = document.createElement(jsc._vmlNS + ':fill'); + vGrad.type = 'gradient'; + vGrad.method = 'linear'; + vGrad.angle = '180'; + vGrad.opacity = '0'; + + var vRect = document.createElement(jsc._vmlNS + ':rect'); + vRect.style.position = 'absolute'; + vRect.style.left = -1 + 'px'; + vRect.style.top = -1 + 'px'; + vRect.stroked = false; + vRect.appendChild(vGrad); + vmlContainer.appendChild(vRect); + + var drawFunc = function (width, height, type) { + vmlContainer.style.width = width + 'px'; + vmlContainer.style.height = height + 'px'; + + hRect.style.width = + vRect.style.width = + (width + 1) + 'px'; + hRect.style.height = + vRect.style.height = + (height + 1) + 'px'; + + // Colors must be specified during every redraw, otherwise IE won't display + // a full gradient during a subsequential redraw + hGrad.color = '#F00'; + hGrad.color2 = '#F00'; + + switch (type.toLowerCase()) { + case 's': + vGrad.color = vGrad.color2 = '#FFF'; + break; + case 'v': + vGrad.color = vGrad.color2 = '#000'; + break; + } + }; + + paletteObj.elm = vmlContainer; + paletteObj.draw = drawFunc; + } + + return paletteObj; + }, + + + createSliderGradient : function () { + + var sliderObj = { + elm: null, + draw: null + }; + + if (jsc.isCanvasSupported) { + // Canvas implementation for modern browsers + + var canvas = document.createElement('canvas'); + var ctx = canvas.getContext('2d'); + + var drawFunc = function (width, height, color1, color2) { + canvas.width = width; + canvas.height = height; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + + var grad = ctx.createLinearGradient(0, 0, 0, canvas.height); + grad.addColorStop(0, color1); + grad.addColorStop(1, color2); + + ctx.fillStyle = grad; + ctx.fillRect(0, 0, canvas.width, canvas.height); + }; + + sliderObj.elm = canvas; + sliderObj.draw = drawFunc; + + } else { + // VML fallback for IE 7 and 8 + + jsc.initVML(); + + var vmlContainer = document.createElement('div'); + vmlContainer.style.position = 'relative'; + vmlContainer.style.overflow = 'hidden'; + + var grad = document.createElement(jsc._vmlNS + ':fill'); + grad.type = 'gradient'; + grad.method = 'linear'; + grad.angle = '180'; + + var rect = document.createElement(jsc._vmlNS + ':rect'); + rect.style.position = 'absolute'; + rect.style.left = -1 + 'px'; + rect.style.top = -1 + 'px'; + rect.stroked = false; + rect.appendChild(grad); + vmlContainer.appendChild(rect); + + var drawFunc = function (width, height, color1, color2) { + vmlContainer.style.width = width + 'px'; + vmlContainer.style.height = height + 'px'; + + rect.style.width = (width + 1) + 'px'; + rect.style.height = (height + 1) + 'px'; + + grad.color = color1; + grad.color2 = color2; + }; + + sliderObj.elm = vmlContainer; + sliderObj.draw = drawFunc; + } + + return sliderObj; + }, + + + leaveValue : 1<<0, + leaveStyle : 1<<1, + leavePad : 1<<2, + leaveSld : 1<<3, + + + BoxShadow : (function () { + var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) { + this.hShadow = hShadow; + this.vShadow = vShadow; + this.blur = blur; + this.spread = spread; + this.color = color; + this.inset = !!inset; + }; + + BoxShadow.prototype.toString = function () { + var vals = [ + Math.round(this.hShadow) + 'px', + Math.round(this.vShadow) + 'px', + Math.round(this.blur) + 'px', + Math.round(this.spread) + 'px', + this.color + ]; + if (this.inset) { + vals.push('inset'); + } + return vals.join(' '); + }; + + return BoxShadow; + })(), + + + // + // Usage: + // var myColor = new jscolor( [, ]) + // + + jscolor : function (targetElement, options) { + + // General options + // + this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB() + this.valueElement = targetElement; // element that will be used to display and input the color code + this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor + this.required = true; // whether the associated text can be left empty + this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace) + this.hash = true; // whether to prefix the HEX color code with # symbol + this.uppercase = true; // whether to uppercase the color code + this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code) + this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it + this.minS = 0; // min allowed saturation (0 - 100) + this.maxS = 100; // max allowed saturation (0 - 100) + this.minV = 0; // min allowed value (brightness) (0 - 100) + this.maxV = 100; // max allowed value (brightness) (0 - 100) + + // Accessing the picked color + // + this.hsv = [0, 0, 100]; // read-only [0-360, 0-100, 0-100] + this.rgb = [255, 255, 255]; // read-only [0-255, 0-255, 0-255] + + // Color Picker options + // + this.width = 181; // width of color palette (in px) + this.height = 101; // height of color palette (in px) + this.showOnClick = true; // whether to display the color picker when user clicks on its target element + this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls + this.position = 'bottom'; // left | right | top | bottom - position relative to the target element + this.smartPosition = true; // automatically change picker position when there is not enough space for it + this.sliderSize = 16; // px + this.crossSize = 8; // px + this.closable = false; // whether to display the Close button + this.closeText = 'Close'; + this.buttonColor = '#000000'; // CSS color + this.buttonHeight = 18; // px + this.padding = 8; // px + this.backgroundColor = '#FFFFFF'; // CSS color + this.borderWidth = 1; // px + this.borderColor = '#BBBBBB'; // CSS color + this.borderRadius = 4; // px + this.insetWidth = 1; // px + this.insetColor = '#BBBBBB'; // CSS color + this.shadow = false; // whether to display shadow + this.shadowBlur = 15; // px + this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color + this.pointerColor = '#4C4C4C'; // px + this.pointerBorderColor = '#FFFFFF'; // px + this.pointerBorderWidth = 1; // px + this.pointerThickness = 2; // px + this.zIndex = 1000; + this.container = null; // where to append the color picker (BODY element by default) + + + for (var opt in options) { + if (options.hasOwnProperty(opt)) { + this[opt] = options[opt]; + } + } + + + this.hide = function () { + if (isPickerOwner()) { + detachPicker(); + } + }; + + + this.show = function () { + drawPicker(); + }; + + + this.redraw = function () { + if (isPickerOwner()) { + drawPicker(); + } + }; + + + this.importColor = function () { + if (!this.valueElement) { + this.exportColor(); + } else { + if (jsc.isElementType(this.valueElement, 'input')) { + if (!this.refine) { + if (!this.fromString(this.valueElement.value, jsc.leaveValue)) { + if (this.styleElement) { + this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage; + this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor; + this.styleElement.style.color = this.styleElement._jscOrigStyle.color; + } + this.exportColor(jsc.leaveValue | jsc.leaveStyle); + } + } else if (!this.required && /^\s*$/.test(this.valueElement.value)) { + this.valueElement.value = ''; + if (this.styleElement) { + this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage; + this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor; + this.styleElement.style.color = this.styleElement._jscOrigStyle.color; + } + this.exportColor(jsc.leaveValue | jsc.leaveStyle); + + } else if (this.fromString(this.valueElement.value)) { + // managed to import color successfully from the value -> OK, don't do anything + } else { + this.exportColor(); + } + } else { + // not an input element -> doesn't have any value + this.exportColor(); + } + } + }; + + + this.exportColor = function (flags) { + if (!(flags & jsc.leaveValue) && this.valueElement) { + var value = this.toString(); + if (this.uppercase) { value = value.toUpperCase(); } + if (this.hash) { value = '#' + value; } + + if (jsc.isElementType(this.valueElement, 'input')) { + this.valueElement.value = value; + } else { + this.valueElement.innerHTML = value; + } + } + // if (!(flags & jsc.leaveStyle)) { + // if (this.styleElement) { + // this.styleElement.style.backgroundImage = 'none'; + // this.styleElement.style.backgroundColor = '#' + this.toString(); + // this.styleElement.style.color = this.isLight() ? '#000' : '#FFF'; + // } + // } + if (!(flags & jsc.leavePad) && isPickerOwner()) { + redrawPad(); + } + if (!(flags & jsc.leaveSld) && isPickerOwner()) { + redrawSld(); + } + }; + + + // h: 0-360 + // s: 0-100 + // v: 0-100 + // + this.fromHSV = function (h, s, v, flags) { // null = don't change + if (h !== null) { + if (isNaN(h)) { return false; } + h = Math.max(0, Math.min(360, h)); + } + if (s !== null) { + if (isNaN(s)) { return false; } + s = Math.max(0, Math.min(100, this.maxS, s), this.minS); + } + if (v !== null) { + if (isNaN(v)) { return false; } + v = Math.max(0, Math.min(100, this.maxV, v), this.minV); + } + + this.rgb = HSV_RGB( + h===null ? this.hsv[0] : (this.hsv[0]=h), + s===null ? this.hsv[1] : (this.hsv[1]=s), + v===null ? this.hsv[2] : (this.hsv[2]=v) + ); + + this.exportColor(flags); + }; + + + // r: 0-255 + // g: 0-255 + // b: 0-255 + // + this.fromRGB = function (r, g, b, flags) { // null = don't change + if (r !== null) { + if (isNaN(r)) { return false; } + r = Math.max(0, Math.min(255, r)); + } + if (g !== null) { + if (isNaN(g)) { return false; } + g = Math.max(0, Math.min(255, g)); + } + if (b !== null) { + if (isNaN(b)) { return false; } + b = Math.max(0, Math.min(255, b)); + } + + var hsv = RGB_HSV( + r===null ? this.rgb[0] : r, + g===null ? this.rgb[1] : g, + b===null ? this.rgb[2] : b + ); + if (hsv[0] !== null) { + this.hsv[0] = Math.max(0, Math.min(360, hsv[0])); + } + if (hsv[2] !== 0) { + this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1])); + } + this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2])); + + // update RGB according to final HSV, as some values might be trimmed + var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]); + this.rgb[0] = rgb[0]; + this.rgb[1] = rgb[1]; + this.rgb[2] = rgb[2]; + + this.exportColor(flags); + }; + + + this.fromString = function (str, flags) { + var m; + if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) { + // HEX notation + // + + if (m[1].length === 6) { + // 6-char notation + this.fromRGB( + parseInt(m[1].substr(0,2),16), + parseInt(m[1].substr(2,2),16), + parseInt(m[1].substr(4,2),16), + flags + ); + } else { + // 3-char notation + this.fromRGB( + parseInt(m[1].charAt(0) + m[1].charAt(0),16), + parseInt(m[1].charAt(1) + m[1].charAt(1),16), + parseInt(m[1].charAt(2) + m[1].charAt(2),16), + flags + ); + } + return true; + + } else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) { + var params = m[1].split(','); + var re = /^\s*(\d*)(\.\d+)?\s*$/; + var mR, mG, mB; + if ( + params.length >= 3 && + (mR = params[0].match(re)) && + (mG = params[1].match(re)) && + (mB = params[2].match(re)) + ) { + var r = parseFloat((mR[1] || '0') + (mR[2] || '')); + var g = parseFloat((mG[1] || '0') + (mG[2] || '')); + var b = parseFloat((mB[1] || '0') + (mB[2] || '')); + this.fromRGB(r, g, b, flags); + return true; + } + } + return false; + }; + + + this.toString = function () { + return ( + (0x100 | Math.round(this.rgb[0])).toString(16).substr(1) + + (0x100 | Math.round(this.rgb[1])).toString(16).substr(1) + + (0x100 | Math.round(this.rgb[2])).toString(16).substr(1) + ); + }; + + + this.toHEXString = function () { + return '#' + this.toString().toUpperCase(); + }; + + + this.toRGBString = function () { + return ('rgb(' + + Math.round(this.rgb[0]) + ',' + + Math.round(this.rgb[1]) + ',' + + Math.round(this.rgb[2]) + ')' + ); + }; + + + this.isLight = function () { + return ( + 0.213 * this.rgb[0] + + 0.715 * this.rgb[1] + + 0.072 * this.rgb[2] > + 255 / 2 + ); + }; + + + this._processParentElementsInDOM = function () { + if (this._linkedElementsProcessed) { return; } + this._linkedElementsProcessed = true; + + var elm = this.targetElement; + do { + // If the target element or one of its parent nodes has fixed position, + // then use fixed positioning instead + // + // Note: In Firefox, getComputedStyle returns null in a hidden iframe, + // that's why we need to check if the returned style object is non-empty + var currStyle = jsc.getStyle(elm); + if (currStyle && currStyle.position.toLowerCase() === 'fixed') { + this.fixed = true; + } + + if (elm !== this.targetElement) { + // Ensure to attach onParentScroll only once to each parent element + // (multiple targetElements can share the same parent nodes) + // + // Note: It's not just offsetParents that can be scrollable, + // that's why we loop through all parent nodes + if (!elm._jscEventsAttached) { + jsc.attachEvent(elm, 'scroll', jsc.onParentScroll); + elm._jscEventsAttached = true; + } + } + } while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body')); + }; + + + // r: 0-255 + // g: 0-255 + // b: 0-255 + // + // returns: [ 0-360, 0-100, 0-100 ] + // + function RGB_HSV (r, g, b) { + r /= 255; + g /= 255; + b /= 255; + var n = Math.min(Math.min(r,g),b); + var v = Math.max(Math.max(r,g),b); + var m = v - n; + if (m === 0) { return [ null, 0, 100 * v ]; } + var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m); + return [ + 60 * (h===6?0:h), + 100 * (m/v), + 100 * v + ]; + } + + + // h: 0-360 + // s: 0-100 + // v: 0-100 + // + // returns: [ 0-255, 0-255, 0-255 ] + // + function HSV_RGB (h, s, v) { + var u = 255 * (v / 100); + + if (h === null) { + return [ u, u, u ]; + } + + h /= 60; + s /= 100; + + var i = Math.floor(h); + var f = i%2 ? h-i : 1-(h-i); + var m = u * (1 - s); + var n = u * (1 - s * f); + switch (i) { + case 6: + case 0: return [u,n,m]; + case 1: return [n,u,m]; + case 2: return [m,u,n]; + case 3: return [m,n,u]; + case 4: return [n,m,u]; + case 5: return [u,m,n]; + } + } + + + function detachPicker () { + jsc.unsetClass(THIS.targetElement, THIS.activeClass); + jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap); + delete jsc.picker.owner; + } + + + function drawPicker () { + + // At this point, when drawing the picker, we know what the parent elements are + // and we can do all related DOM operations, such as registering events on them + // or checking their positioning + THIS._processParentElementsInDOM(); + + if (!jsc.picker) { + jsc.picker = { + owner: null, + wrap : document.createElement('div'), + box : document.createElement('div'), + boxS : document.createElement('div'), // shadow area + boxB : document.createElement('div'), // border + pad : document.createElement('div'), + padB : document.createElement('div'), // border + padM : document.createElement('div'), // mouse/touch area + padPal : jsc.createPalette(), + cross : document.createElement('div'), + crossBY : document.createElement('div'), // border Y + crossBX : document.createElement('div'), // border X + crossLY : document.createElement('div'), // line Y + crossLX : document.createElement('div'), // line X + sld : document.createElement('div'), + sldB : document.createElement('div'), // border + sldM : document.createElement('div'), // mouse/touch area + sldGrad : jsc.createSliderGradient(), + sldPtrS : document.createElement('div'), // slider pointer spacer + sldPtrIB : document.createElement('div'), // slider pointer inner border + sldPtrMB : document.createElement('div'), // slider pointer middle border + sldPtrOB : document.createElement('div'), // slider pointer outer border + btn : document.createElement('div'), + btnT : document.createElement('span') // text + }; + + jsc.picker.pad.appendChild(jsc.picker.padPal.elm); + jsc.picker.padB.appendChild(jsc.picker.pad); + jsc.picker.cross.appendChild(jsc.picker.crossBY); + jsc.picker.cross.appendChild(jsc.picker.crossBX); + jsc.picker.cross.appendChild(jsc.picker.crossLY); + jsc.picker.cross.appendChild(jsc.picker.crossLX); + jsc.picker.padB.appendChild(jsc.picker.cross); + jsc.picker.box.appendChild(jsc.picker.padB); + jsc.picker.box.appendChild(jsc.picker.padM); + + jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm); + jsc.picker.sldB.appendChild(jsc.picker.sld); + jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB); + jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB); + jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB); + jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS); + jsc.picker.box.appendChild(jsc.picker.sldB); + jsc.picker.box.appendChild(jsc.picker.sldM); + + jsc.picker.btn.appendChild(jsc.picker.btnT); + jsc.picker.box.appendChild(jsc.picker.btn); + + jsc.picker.boxB.appendChild(jsc.picker.box); + jsc.picker.wrap.appendChild(jsc.picker.boxS); + jsc.picker.wrap.appendChild(jsc.picker.boxB); + } + + var p = jsc.picker; + + var displaySlider = !!jsc.getSliderComponent(THIS); + var dims = jsc.getPickerDims(THIS); + var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize); + var padToSliderPadding = jsc.getPadToSliderPadding(THIS); + var borderRadius = Math.min( + THIS.borderRadius, + Math.round(THIS.padding * Math.PI)); // px + var padCursor = 'crosshair'; + + // wrap + p.wrap.style.clear = 'both'; + p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px'; + p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px'; + p.wrap.style.zIndex = THIS.zIndex; + + // picker + p.box.style.width = dims[0] + 'px'; + p.box.style.height = dims[1] + 'px'; + + p.boxS.style.position = 'absolute'; + p.boxS.style.left = '0'; + p.boxS.style.top = '0'; + p.boxS.style.width = '100%'; + p.boxS.style.height = '100%'; + jsc.setBorderRadius(p.boxS, borderRadius + 'px'); + + // picker border + p.boxB.style.position = 'relative'; + p.boxB.style.border = THIS.borderWidth + 'px solid'; + p.boxB.style.borderColor = THIS.borderColor; + p.boxB.style.background = THIS.backgroundColor; + jsc.setBorderRadius(p.boxB, borderRadius + 'px'); + + // IE hack: + // If the element is transparent, IE will trigger the event on the elements under it, + // e.g. on Canvas or on elements with border + p.padM.style.background = + p.sldM.style.background = + '#FFF'; + jsc.setStyle(p.padM, 'opacity', '0'); + jsc.setStyle(p.sldM, 'opacity', '0'); + + // pad + p.pad.style.position = 'relative'; + p.pad.style.width = THIS.width + 'px'; + p.pad.style.height = THIS.height + 'px'; + + // pad palettes (HSV and HVS) + p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS)); + + // pad border + p.padB.style.position = 'absolute'; + p.padB.style.left = THIS.padding + 'px'; + p.padB.style.top = THIS.padding + 'px'; + p.padB.style.border = THIS.insetWidth + 'px solid'; + p.padB.style.borderColor = THIS.insetColor; + + // pad mouse area + p.padM._jscInstance = THIS; + p.padM._jscControlName = 'pad'; + p.padM.style.position = 'absolute'; + p.padM.style.left = '0'; + p.padM.style.top = '0'; + p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px'; + p.padM.style.height = dims[1] + 'px'; + p.padM.style.cursor = padCursor; + + // pad cross + p.cross.style.position = 'absolute'; + p.cross.style.left = + p.cross.style.top = + '0'; + p.cross.style.width = + p.cross.style.height = + crossOuterSize + 'px'; + + // pad cross border Y and X + p.crossBY.style.position = + p.crossBX.style.position = + 'absolute'; + p.crossBY.style.background = + p.crossBX.style.background = + THIS.pointerBorderColor; + p.crossBY.style.width = + p.crossBX.style.height = + (2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px'; + p.crossBY.style.height = + p.crossBX.style.width = + crossOuterSize + 'px'; + p.crossBY.style.left = + p.crossBX.style.top = + (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px'; + p.crossBY.style.top = + p.crossBX.style.left = + '0'; + + // pad cross line Y and X + p.crossLY.style.position = + p.crossLX.style.position = + 'absolute'; + p.crossLY.style.background = + p.crossLX.style.background = + THIS.pointerColor; + p.crossLY.style.height = + p.crossLX.style.width = + (crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px'; + p.crossLY.style.width = + p.crossLX.style.height = + THIS.pointerThickness + 'px'; + p.crossLY.style.left = + p.crossLX.style.top = + (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px'; + p.crossLY.style.top = + p.crossLX.style.left = + THIS.pointerBorderWidth + 'px'; + + // slider + p.sld.style.overflow = 'hidden'; + p.sld.style.width = THIS.sliderSize + 'px'; + p.sld.style.height = THIS.height + 'px'; + + // slider gradient + p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000'); + + // slider border + p.sldB.style.display = displaySlider ? 'block' : 'none'; + p.sldB.style.position = 'absolute'; + p.sldB.style.right = THIS.padding + 'px'; + p.sldB.style.top = THIS.padding + 'px'; + p.sldB.style.border = THIS.insetWidth + 'px solid'; + p.sldB.style.borderColor = THIS.insetColor; + + // slider mouse area + p.sldM._jscInstance = THIS; + p.sldM._jscControlName = 'sld'; + p.sldM.style.display = displaySlider ? 'block' : 'none'; + p.sldM.style.position = 'absolute'; + p.sldM.style.right = '0'; + p.sldM.style.top = '0'; + p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px'; + p.sldM.style.height = dims[1] + 'px'; + p.sldM.style.cursor = 'default'; + + // slider pointer inner and outer border + p.sldPtrIB.style.border = + p.sldPtrOB.style.border = + THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor; + + // slider pointer outer border + p.sldPtrOB.style.position = 'absolute'; + p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px'; + p.sldPtrOB.style.top = '0'; + + // slider pointer middle border + p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor; + + // slider pointer spacer + p.sldPtrS.style.width = THIS.sliderSize + 'px'; + p.sldPtrS.style.height = sliderPtrSpace + 'px'; + + // the Close button + function setBtnBorder () { + var insetColors = THIS.insetColor.split(/\s+/); + var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1]; + p.btn.style.borderColor = outsetColor; + } + p.btn.style.display = THIS.closable ? 'block' : 'none'; + p.btn.style.position = 'absolute'; + p.btn.style.left = THIS.padding + 'px'; + p.btn.style.bottom = THIS.padding + 'px'; + p.btn.style.padding = '0 15px'; + p.btn.style.height = THIS.buttonHeight + 'px'; + p.btn.style.border = THIS.insetWidth + 'px solid'; + setBtnBorder(); + p.btn.style.color = THIS.buttonColor; + p.btn.style.font = '12px sans-serif'; + p.btn.style.textAlign = 'center'; + try { + p.btn.style.cursor = 'pointer'; + } catch(eOldIE) { + p.btn.style.cursor = 'hand'; + } + p.btn.onmousedown = function () { + THIS.hide(); + }; + p.btnT.style.lineHeight = THIS.buttonHeight + 'px'; + p.btnT.innerHTML = ''; + p.btnT.appendChild(document.createTextNode(THIS.closeText)); + + // place pointers + redrawPad(); + redrawSld(); + + // If we are changing the owner without first closing the picker, + // make sure to first deal with the old owner + if (jsc.picker.owner && jsc.picker.owner !== THIS) { + jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass); + } + + // Set the new picker owner + jsc.picker.owner = THIS; + + // The redrawPosition() method needs picker.owner to be set, that's why we call it here, + // after setting the owner + if (jsc.isElementType(container, 'body')) { + jsc.redrawPosition(); + } else { + jsc._drawPosition(THIS, 0, 0, 'relative', false); + } + + if (p.wrap.parentNode != container) { + container.appendChild(p.wrap); + } + + jsc.setClass(THIS.targetElement, THIS.activeClass); + } + + + function redrawPad () { + // redraw the pad pointer + switch (jsc.getPadYComponent(THIS)) { + case 's': var yComponent = 1; break; + case 'v': var yComponent = 2; break; + } + var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1)); + var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1)); + var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize); + var ofs = -Math.floor(crossOuterSize / 2); + jsc.picker.cross.style.left = (x + ofs) + 'px'; + jsc.picker.cross.style.top = (y + ofs) + 'px'; + + // redraw the slider + switch (jsc.getSliderComponent(THIS)) { + case 's': + var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]); + var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]); + var color1 = 'rgb(' + + Math.round(rgb1[0]) + ',' + + Math.round(rgb1[1]) + ',' + + Math.round(rgb1[2]) + ')'; + var color2 = 'rgb(' + + Math.round(rgb2[0]) + ',' + + Math.round(rgb2[1]) + ',' + + Math.round(rgb2[2]) + ')'; + jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2); + break; + case 'v': + var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100); + var color1 = 'rgb(' + + Math.round(rgb[0]) + ',' + + Math.round(rgb[1]) + ',' + + Math.round(rgb[2]) + ')'; + var color2 = '#000'; + jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2); + break; + } + } + + + function redrawSld () { + var sldComponent = jsc.getSliderComponent(THIS); + if (sldComponent) { + // redraw the slider pointer + switch (sldComponent) { + case 's': var yComponent = 1; break; + case 'v': var yComponent = 2; break; + } + var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1)); + jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px'; + } + } + + + function isPickerOwner () { + return jsc.picker && jsc.picker.owner === THIS; + } + + + function blurValue () { + THIS.importColor(); + } + + + // Find the target element + if (typeof targetElement === 'string') { + var id = targetElement; + var elm = document.getElementById(id); + if (elm) { + this.targetElement = elm; + } else { + jsc.warn('Could not find target element with ID \'' + id + '\''); + } + } else if (targetElement) { + this.targetElement = targetElement; + } else { + jsc.warn('Invalid target element: \'' + targetElement + '\''); + } + + if (this.targetElement._jscLinkedInstance) { + jsc.warn('Cannot link jscolor twice to the same element. Skipping.'); + return; + } + this.targetElement._jscLinkedInstance = this; + + // Find the value element + this.valueElement = jsc.fetchElement(this.valueElement); + // Find the style element + this.styleElement = jsc.fetchElement(this.styleElement); + + var THIS = this; + var container = + this.container ? + jsc.fetchElement(this.container) : + document.getElementsByTagName('body')[0]; + var sliderPtrSpace = 3; // px + + // For BUTTON elements it's important to stop them from sending the form when clicked + // (e.g. in Safari) + if (jsc.isElementType(this.targetElement, 'button')) { + if (this.targetElement.onclick) { + var origCallback = this.targetElement.onclick; + this.targetElement.onclick = function (evt) { + origCallback.call(this, evt); + return false; + }; + } else { + this.targetElement.onclick = function () { return false; }; + } + } + + /* + var elm = this.targetElement; + do { + // If the target element or one of its offsetParents has fixed position, + // then use fixed positioning instead + // + // Note: In Firefox, getComputedStyle returns null in a hidden iframe, + // that's why we need to check if the returned style object is non-empty + var currStyle = jsc.getStyle(elm); + if (currStyle && currStyle.position.toLowerCase() === 'fixed') { + this.fixed = true; + } + + if (elm !== this.targetElement) { + // attach onParentScroll so that we can recompute the picker position + // when one of the offsetParents is scrolled + if (!elm._jscEventsAttached) { + jsc.attachEvent(elm, 'scroll', jsc.onParentScroll); + elm._jscEventsAttached = true; + } + } + } while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body')); + */ + + // valueElement + if (this.valueElement) { + if (jsc.isElementType(this.valueElement, 'input')) { + var updateField = function () { + THIS.fromString(THIS.valueElement.value, jsc.leaveValue); + jsc.dispatchFineChange(THIS); + }; + jsc.attachEvent(this.valueElement, 'keyup', updateField); + jsc.attachEvent(this.valueElement, 'input', updateField); + jsc.attachEvent(this.valueElement, 'blur', blurValue); + this.valueElement.setAttribute('autocomplete', 'off'); + } + } + + // styleElement + if (this.styleElement) { + this.styleElement._jscOrigStyle = { + backgroundImage : this.styleElement.style.backgroundImage, + backgroundColor : this.styleElement.style.backgroundColor, + color : this.styleElement.style.color + }; + } + + if (this.value) { + // Try to set the color from the .value option and if unsuccessful, + // export the current color + this.fromString(this.value) || this.exportColor(); + } else { + this.importColor(); + } + } + +}; + + +//================================ +// Public properties and methods +//================================ + + +// By default, search for all elements with class="jscolor" and install a color picker on them. +// +// You can change what class name will be looked for by setting the property jscolor.lookupClass +// anywhere in your HTML document. To completely disable the automatic lookup, set it to null. +// +jsc.jscolor.lookupClass = 'jscolor'; + + +jsc.jscolor.installByClassName = function (className) { + var inputElms = document.getElementsByTagName('input'); + var buttonElms = document.getElementsByTagName('button'); + + jsc.tryInstallOnElements(inputElms, className); + jsc.tryInstallOnElements(buttonElms, className); +}; + + +jsc.register(); + + +return jsc.jscolor; + + +})(); } diff --git a/packages/rocketchat-theme/client/vendor/photoswipe.css b/packages/rocketchat-theme/client/vendor/photoswipe.css new file mode 100644 index 000000000000..afa4e57e6c49 --- /dev/null +++ b/packages/rocketchat-theme/client/vendor/photoswipe.css @@ -0,0 +1,422 @@ +.pswp__button { + position: relative; + + display: block; + float: right; + overflow: visible; + + width: 44px; + height: 44px; + margin: 0; + padding: 0; + + cursor: pointer; + transition: opacity 0.2s; + + opacity: 0.75; + border: 0; + background: none; + box-shadow: none; + appearance: none; + + &:focus, + &:hover { + opacity: 1; + } + + &:active { + opacity: 0.9; + outline: none; + } + + &::-moz-focus-inner { + padding: 0; + + border: 0; + } +} + +.pswp__ui--over-close .pswp__button--close { + opacity: 1; +} + +.pswp__button, +.pswp__button--arrow--left::before, +.pswp__button--arrow--right::before { + width: 44px; + height: 44px; + + background: url(/images/gallery-skin.svg) 0 0 no-repeat; + background-size: 264px 88px; +} + +@media (-webkit-min-device-pixel-ratio: 1.1), + (-webkit-min-device-pixel-ratio: 1.09375), + (min-resolution: 105dpi), + (min-resolution: 1.1dppx) { + .pswp--svg .pswp__button--arrow--left, + .pswp--svg .pswp__button--arrow--right { + background: none; + } +} + +.pswp__button--close { + background-position: 0 -44px; +} + +.pswp__button--share { + background-position: -44px -44px; +} + +.pswp__button--fs { + display: none; +} + +.pswp--supports-fs .pswp__button--fs { + display: block; +} + +.pswp--fs .pswp__button--fs { + background-position: -44px 0; +} + +.pswp__button--zoom { + display: none; + + background-position: -88px 0; +} + +.pswp--zoom-allowed .pswp__button--zoom { + display: block; +} + +.pswp--zoomed-in .pswp__button--zoom { + background-position: -132px 0; +} + +.pswp--touch .pswp__button--arrow--left, +.pswp--touch .pswp__button--arrow--right { + visibility: hidden; +} + +.pswp__button--arrow--left, +.pswp__button--arrow--right { + position: absolute; + top: 50%; + + width: 70px; + height: 100px; + margin-top: -50px; + + background: none; +} + +.pswp__button--arrow--left { + left: 0; +} + +.pswp__button--arrow--right { + right: 0; +} + +.pswp__button--arrow--left::before, +.pswp__button--arrow--right::before { + position: absolute; + top: 35px; + + width: 32px; + height: 30px; + + content: ''; + + background-color: rgba(0, 0, 0, 0.3); +} + +.pswp__button--arrow--left::before { + left: 6px; + + background-position: -138px -44px; +} + +.pswp__button--arrow--right::before { + right: 6px; + + background-position: -94px -44px; +} + +/* + + 4. Caption + + */ +.pswp__caption { + position: absolute; + bottom: 0; + left: 0; + + width: 100%; + min-height: 44px; + + & small { + color: #bbbbbb; + + font-size: 11px; + } +} + +.pswp__caption__center { + max-width: 420px; + margin: 0 auto; + padding: 10px; + + text-align: left; + + color: #cccccc; + + font-size: 13px; + line-height: 20px; +} + +.pswp__caption--empty { + display: none; +} + +/* Fake caption element, used to calculate height of next/prev image */ +.pswp__caption--fake { + visibility: hidden; +} + +/* + + 5. Loading indicator (preloader) + + You can play with it here - http://codepen.io/dimsemenov/pen/yyBWoR + + */ +.pswp__preloader { + position: absolute; + top: 0; + left: 50%; + + width: 44px; + height: 44px; + margin-left: -22px; + + transition: opacity 0.25s ease-out; + + opacity: 0; + direction: ltr; + will-change: opacity; +} + +.pswp__preloader__icn { + width: 20px; + height: 20px; + margin: 12px; +} + +.pswp__preloader--active { + opacity: 1; +} + +.pswp--css_animation { + & .pswp__preloader--active { + opacity: 1; + + & .pswp__preloader__icn { + position: absolute; + top: 15px; + left: 15px; + + width: 14px; + height: 14px; + margin: 0; + + animation: clockwise 500ms linear infinite; + + opacity: 0.75; + background: none; + } + + & .pswp__preloader__donut { + position: absolute; + top: 0; + left: 0; + + box-sizing: border-box; + width: 14px; + height: 14px; + margin: 0; + + animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; + + border: 2px solid #ffffff; + border-bottom-color: transparent; + border-left-color: transparent; + border-radius: 50%; + background: none; + } + + & .pswp__preloader__cut { + /* + The idea of animating inner circle is based on Polymer ("material") loading indicator + by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html + */ + position: relative; + + overflow: hidden; + + width: 7px; + height: 14px; + } + } +} + +@media screen and (max-width: 1024px) { + .pswp__preloader { + position: relative; + top: auto; + left: auto; + + float: right; + + margin: 0; + } +} + +@-webkit-keyframes clockwise { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +@keyframes clockwise { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +@-webkit-keyframes donut-rotate { + 0% { + transform: rotate(0); + } + + 50% { + transform: rotate(-140deg); + } + + 100% { + transform: rotate(0); + } +} + +@keyframes donut-rotate { + 0% { + transform: rotate(0); + } + + 50% { + transform: rotate(-140deg); + } + + 100% { + transform: rotate(0); + } +} + +/* + + 6. Additional styles + + */ + +/* root element of UI */ +.pswp__ui { + z-index: 1550; + + visibility: visible; + + opacity: 1; + -webkit-font-smoothing: auto; +} + +/* top black bar with buttons and "1 of X" indicator */ +.pswp__top-bar { + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 44px; +} + +.pswp__caption, +.pswp__top-bar, +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + -webkit-backface-visibility: hidden; + will-change: opacity; +} + +/* pswp--has_mouse class is added only when two subsequent mousemove events occur */ +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + visibility: visible; +} + +.pswp__top-bar, +.pswp__caption { + background-color: rgba(0, 0, 0, 0.5); +} + +/* pswp__ui--fit class is added when main image "fits" between top bar and bottom bar (caption) */ +.pswp__ui--fit .pswp__top-bar, +.pswp__ui--fit .pswp__caption { + background-color: rgba(0, 0, 0, 0.3); +} + +/* pswp__ui--idle class is added when mouse isn't moving for several seconds (JS option timeToIdle) */ +.pswp__ui--idle .pswp__top-bar { + opacity: 0; +} + +.pswp__ui--idle .pswp__button--arrow--left, +.pswp__ui--idle .pswp__button--arrow--right { + opacity: 0; +} + +/* + pswp__ui--hidden class is added when controls are hidden + e.g. when user taps to toggle visibility of controls +*/ +.pswp__ui--hidden .pswp__top-bar, +.pswp__ui--hidden .pswp__caption, +.pswp__ui--hidden .pswp__button--arrow--left, +.pswp__ui--hidden .pswp__button--arrow--right { + /* Force paint & create composition layer for controls. */ + opacity: 0.001; +} + +/* pswp__ui--one-slide class is added when there is just one item in gallery */ +.pswp__ui--one-slide .pswp__button--arrow--left, +.pswp__ui--one-slide .pswp__button--arrow--right, +.pswp__ui--one-slide .pswp__counter { + display: none; +} + +.pswp__element--disabled { + display: none !important; +} + +.pswp--minimal--dark .pswp__top-bar { + background: none; +} diff --git a/packages/rocketchat-theme/i18n/en.i18n.json b/packages/rocketchat-theme/i18n/en.i18n.json deleted file mode 100644 index 31987697d1db..000000000000 --- a/packages/rocketchat-theme/i18n/en.i18n.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "Theme_Description" : "", - "theme-color-blockquote-background" : "Blockquote Background Color", - "theme-color-blockquote-background_Description" : "", - "theme-color-code-background" : "Code Background Color", - "theme-color-code-background_Description" : "", - "theme-color-code-border" : "Code Border Color", - "theme-color-code-border_Description" : "", - "theme-color-code-color" : "Code Color", - "theme-color-code-color_Description" : "", - "theme-color-content-background-color" : "Content Background Color", - "theme-color-content-background-color_Description" : "", - "theme-color-info-active-font-color" : "Active Info Font Color", - "theme-color-info-active-font-color_Description" : "", - "theme-color-info-font-color" : "Info Font Color", - "theme-color-info-font-color_Description" : "", - "theme-color-input-font-color" : "Input Font Color", - "theme-color-input-font-color_Description" : "", - "theme-color-link-font-color" : "Link Font Color", - "theme-color-link-font-color_Description" : "", - "theme-color-primary-background-color" : "Primary Background Color", - "theme-color-primary-background-color_Description" : "", - "theme-color-primary-font-color" : "Primary Font Color", - "theme-color-primary-font-color_Description" : "", - "theme-color-secondary-background-color" : "Secondary Background Color", - "theme-color-secondary-background-color_Description" : "", - "theme-color-secondary-font-color" : "Secondary Font Color", - "theme-color-secondary-font-color_Description" : "", - "theme-color-smallprint-font-color" : "Small Print Font Color", - "theme-color-smallprint-font-color_Description" : "", - "theme-color-smallprint-hover-color" : "Small Print Hover Color", - "theme-color-smallprint-hover-color_Description" : "", - "theme-color-status-away" : "Away Status Color", - "theme-color-status-away_Description" : "", - "theme-color-status-busy" : "Busy Status Color", - "theme-color-status-busy_Description" : "", - "theme-color-status-offline" : "Offline Status Color", - "theme-color-status-offline_Description" : "", - "theme-color-status-online" : "Online Status Color", - "theme-color-status-online_Description" : "", - "theme-color-tertiary-background-color" : "Tertiary Background Color", - "theme-color-tertiary-background-color_Description" : "", - "theme-color-tertiary-font-color" : "Tertiary Font Color", - "theme-color-tertiary-font-color_Description" : "" -} diff --git a/packages/rocketchat-theme/package.js b/packages/rocketchat-theme/package.js index 7a2d5830675a..21baba9a6fff 100644 --- a/packages/rocketchat-theme/package.js +++ b/packages/rocketchat-theme/package.js @@ -2,61 +2,41 @@ Package.describe({ name: 'rocketchat:theme', version: '0.0.1', summary: '', - git: '' + git: '', }); Package.onUse(function(api) { - api.versionsFrom('1.0'); - api.use('rocketchat:lib'); - api.use('coffeescript'); - api.use('underscore'); + api.use('rocketchat:logger'); + api.use('rocketchat:assets'); + api.use('ecmascript'); + api.use('less'); api.use('webapp'); api.use('webapp-hashing'); + api.use('templating', 'client'); + // Compiled stylesheets + api.addFiles('client/main.css', 'client'); - api.addFiles('server/server.coffee', 'server'); - api.addFiles('server/variables.coffee', 'server'); - - api.addFiles('client/minicolors/jquery.minicolors.css', 'client'); - api.addFiles('client/minicolors/jquery.minicolors.js', 'client'); - - - api.addAssets('assets/stylesheets/global/_variables.less', 'server'); - api.addAssets('assets/stylesheets/utils/_colors.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_emojione.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_fonts.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_keyframes.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_lesshat.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_preloader.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_reset.import.less', 'server'); - api.addAssets('assets/stylesheets/utils/_octicons.less', 'server'); - api.addAssets('assets/stylesheets/utils/_chatops.less', 'server'); - api.addAssets('assets/stylesheets/animation.css', 'server'); - api.addAssets('assets/stylesheets/base.less', 'server'); - api.addAssets('assets/stylesheets/fontello.css', 'server'); - api.addAssets('assets/stylesheets/rtl.less', 'server'); - api.addAssets('assets/stylesheets/swipebox.min.css', 'server'); + // Server side files + api.addFiles('server/server.js', 'server'); + api.addFiles('server/variables.js', 'server'); - // TAPi18n - var _ = Npm.require('underscore'); - var fs = Npm.require('fs'); - api.use('templating', 'client'); - tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-theme/i18n'), function(filename) { - if (fs.statSync('packages/rocketchat-theme/i18n/' + filename).size > 16) { - return 'i18n/' + filename; - } - })); - api.use('tap:i18n@1.6.1', ['client', 'server']); - api.imply('tap:i18n'); - api.addFiles(tapi18nFiles, ['client', 'server']); -}); + // Colorpicker + api.addFiles('client/vendor/jscolor.js', 'client'); -Npm.depends({ - 'less': 'https://github.com/meteor/less.js/tarball/8130849eb3d7f0ecf0ca8d0af7c4207b0442e3f6', - 'less-plugin-autoprefix': '1.4.2' -}); + // Photoswipe + api.addFiles('client/vendor/photoswipe.css', 'client'); -Package.onTest(function(api) { + api.addAssets('client/imports/general/variables.css', 'server'); + // Fontello + api.addFiles('client/vendor/fontello/css/fontello.css', 'client'); + api.addAssets('client/vendor/fontello/font/fontello.eot', 'client'); + api.addAssets('client/vendor/fontello/font/fontello.svg', 'client'); + api.addAssets('client/vendor/fontello/font/fontello.ttf', 'client'); + api.addAssets('client/vendor/fontello/font/fontello.woff', 'client'); + api.addAssets('client/vendor/fontello/font/fontello.woff2', 'client'); + // Run-time stylesheets + api.addAssets('server/colors.less', 'server'); }); diff --git a/packages/rocketchat-theme/server/colors.less b/packages/rocketchat-theme/server/colors.less new file mode 100755 index 000000000000..50e6f3bca3d5 --- /dev/null +++ b/packages/rocketchat-theme/server/colors.less @@ -0,0 +1,959 @@ +/** ---------------------------------------------------------------------------- + * Derivative colours (fixed variants of inherited variables) + */ +@default-action-color: darken(@secondary-background-color, 15%); +@default-action-contrast: contrast(@default-action-color, #444444); +@primary-background-contrast: contrast(@primary-background-color, #444444); +@primary-action-contrast: contrast(@primary-action-color, #444444); +@secondary-background-contrast: contrast(@secondary-background-color, #444444); +@secondary-action-contrast: contrast(@secondary-action-color, #444444); +@selection-background: lighten(@selection-color, 30%); +@success-background: lighten(@success-color, 45%); +@success-border: lighten(@success-color, 30%); +@error-background: lighten(@error-color, 45%); +@error-border: lighten(@error-color, 30%); +@error-contrast: contrast(@error-color); +@pending-background: lighten(@pending-color, 45%); +@pending-border: lighten(@pending-color, 30%); + +/** ---------------------------------------------------------------------------- + * Transparency variables + */ + +@transparent-darkest: rgba(17, 12, 12, 0.5); +@transparent-darker: rgba(0, 0, 0, 0.15); +@transparent-dark: rgba(0, 0, 0, 0.05); +@transparent-light: rgba(255, 255, 255, 0.1); +@transparent-lighter: rgba(255, 255, 255, 0.3); +@transparent-lightest: rgba(255, 255, 255, 0.6); + +/** ---------------------------------------------------------------------------- + * Mixins + */ + +.buttonColors(@color, @bg) { + color: @color; + background-color: @bg; + + &:hover { + color: mix(@color, contrast(@bg), 60%); + background-color: mix(@bg, contrast(@color), 60%); + } +} + +/** ---------------------------------------------------------------------------- + * Classes for variables + */ + +// Major colors + +.content-background-color { + background-color: @content-background-color; +} + +.color-content-background-color { + color: @content-background-color; +} + +.primary-background-color { + background-color: @primary-background-color; +} + +.global-font-family { + font-family: @body-font-family; +} + +.color-primary-font-color { + color: @primary-font-color; +} + +.color-primary-action-color { + color: @primary-action-color; +} + +.background-primary-action-color { + background-color: @primary-action-color; +} + +.secondary-background-color { + background-color: @secondary-background-color; +} + +.border-secondary-background-color { + border-color: @secondary-background-color; +} + +.secondary-font-color { + color: @secondary-font-color; +} + +.border-component-color { + border-color: @component-color; +} + +.background-component-color { + background-color: @component-color; +} + +.color-component-color { + color: @component-color; +} + +.success-color { + color: @success-color; +} + +.pending-color { + color: @pending-color; +} + +.pending-background { + background-color: @pending-background; +} + +.pending-border { + border-color: @pending-border; +} + +.error-color { + color: @error-color; +} + +.background-error-color { + background-color: @error-color; +} + +.color-info-font-color { + color: @info-font-color; +} + +.background-info-font-color { + background-color: @info-font-color; +} + +.background-attention-color { + background-color: @attention-color; +} + +// Minor Colors + +.tertiary-background-color { + background-color: @tertiary-background-color; +} + +.border-tertiary-background-color { + border-color: @tertiary-background-color; +} + +// Derivative Colors + +.color-tertiary-font-color { + color: @tertiary-font-color; +} + +.error-background { + background-color: @error-background; +} + +.error-border { + border-color: @error-border; +} + +.color-error-contrast { + color: @error-contrast; +} + +// transparent + +.background-transparent-darkest { + background-color: @transparent-darkest; +} + +.background-transparent-darker { + background-color: @transparent-darker; +} + +.background-transparent-darker-hover:hover { + background-color: @transparent-darker; +} + +.background-transparent-darker-before::before { + background-color: @transparent-darker; +} + +.background-transparent-dark { + background-color: @transparent-dark; +} + +.background-transparent-dark-hover:hover { + background-color: @transparent-dark; +} + +.border-transparent-dark { + border-color: @transparent-dark; +} + +.background-transparent-light { + background-color: @transparent-light; +} + +.border-transparent-lighter { + border-color: @transparent-lighter; +} + +.background-transparent-lightest { + background-color: @transparent-lightest; +} + +// Derivative Colors +.color-primary-action-contrast { + color: @primary-action-contrast; +} + +/** ---------------------------------------------------------------------------- + * Special components + */ + +* { + -webkit-overflow-scrolling: touch; + + &::-webkit-scrollbar { + height: 8px; + width: 8px; + background: @transparent-dark; + } + + &::-webkit-scrollbar-thumb { + background-color: @custom-scrollbar-color; + -webkit-border-radius: 50px; + } + + &::-webkit-scrollbar-corner { + background-color: @transparent-dark; + } +} + +.filter-item { + &:hover { + border-color: @info-font-color; + } + + &.active { + border-color: @primary-background-color; + } +} + +/** ---------------------------------------------------------------------------- + * Document components + */ + +.page-container { + tr:hover td { + background-color: @content-background-color; + } +} + +.burger i { + background-color: @primary-font-color; +} + +/** ---------------------------------------------------------------------------- + * Forms + */ + +input, +select, +textarea { + color: @primary-font-color; + background-color: transparent; + border-color: mix(contrast(@content-background-color), @content-background-color, 10%); + border-style: solid; + + &::placeholder { + color: mix(@primary-font-color, @content-background-color, 75%); + } + + &[disabled] { + background-color: mix(contrast(@content-background-color), @content-background-color, 10%); + } +} + +.disabled label, +[disabled] label { + color: mix(@primary-font-color, @content-background-color, 75%); +} + +.-autocomplete-container { + background-color: mix(contrast(@content-background-color), @content-background-color, 10%); +} + +.-autocomplete-item.selected { + background-color: mix(contrast(@content-background-color), @content-background-color, 20%); +} + +.rc-old input[type="button"], +.rc-old input[type="submit"] { + color: @primary-font-color; + background: mix(contrast(@content-background-color), @content-background-color, 10%); + border-color: mix(contrast(@content-background-color), @content-background-color, 10%); +} + +.toolbar-search__input { + &:focus { + border-color: fade(@primary-background-contrast, 50%); + } + + &::placeholder { + color: @transparent-lighter; + } +} + +.toolbar-search__buttons i:hover { + color: fade(@primary-background-contrast, 50%); +} + +// .flex-nav { +// input, +// select, +// textarea { +// color: @primary-background-contrast; +// background-color: transparent; +// border-color: mix(contrast(@transparent-lighter), @transparent-lighter, 10%); +// border-style: solid; + +// &::placeholder { +// color: mix(@primary-background-contrast, @transparent-lighter, 75%); +// } + +// &[disabled] { +// background-color: mix(contrast(@transparent-lighter), @transparent-lighter, 10%); +// } +// } + +// .disabled label, +// [disabled] label { +// color: mix(@primary-background-contrast, @transparent-lighter, 75%); +// } + +// .-autocomplete-container { +// background-color: mix(contrast(@transparent-lighter), @transparent-lighter, 10%); +// } + +// .-autocomplete-item.selected { +// background-color: mix(contrast(@transparent-lighter), @transparent-lighter, 20%); +// } + +// input[type="button"], +// input[type="submit"] { +// color: @primary-background-contrast; +// background: mix(contrast(@transparent-lighter), @transparent-lighter, 10%); +// border-color: mix(contrast(@transparent-lighter), @transparent-lighter, 10%); +// } + +// input { +// &:focus { +// border-color: fade(@primary-background-contrast, 50%); +// } +// } + +// .input.checkbox.toggle { +// input:checked + label::before { +// background-color: @primary-action-color; +// } +// } +// } + +.input-line { + &.setting-changed > label { + color: @selection-color; + } +} + +input:-webkit-autofill { + color: @primary-font-color !important; + background-color: transparent !important; +} + +.input { + &.radio { + label { + &::before { + border-color: lighten(@secondary-background-contrast, 30%); + background-color: @content-background-color; + } + + &::after { + background-color: @secondary-background-contrast; + } + } + } + + &.checkbox.toggle { + input:checked + label::before { + background-color: @secondary-background-contrast; + } + + input:disabled + label::before { + background-color: lighten(@secondary-background-contrast, 50%) !important; + } + + label { + &::before { + background-color: lighten(@secondary-background-contrast, 30%); + } + + &::after { + background-color: @content-background-color; + } + + &:hover { + &::before { + background-color: lighten(@secondary-background-contrast, 20%); + } + } + } + } +} + +/** ---------------------------------------------------------------------------- + * Misc typography variants + */ + +// a:active, +// a:hover { +// color: @primary-action-color; +// } + +.message, +.flex-tab { + a i, + a[class^="icon-"] { + color: @primary-font-color; + + &:hover { + color: darken(@primary-font-color, 10%); + } + } +} + +.error { + border-color: @error-color; +} + +/** ---------------------------------------------------------------------------- + * Admin and settings styles + */ + +.page-list, +.page-settings { + a:not(.rc-button) { + color: @primary-font-color; + + &:hover { + color: @primary-action-color; + } + } +} + +.admin-table-row { + background-color: @transparent-light; + + &:nth-of-type(even) { + background-color: @transparent-lightest; + } +} + +.new-logs { + background: @primary-action-contrast; +} + +.avatar-suggestion-item { + .question-mark::before { + color: @secondary-font-color; + } +} + +/** ---------------------------------------------------------------------------- + * Asides (external to main application views) + */ + +.full-page, +.page-loading { + a { + color: @tertiary-font-color; + } + + a:hover { + color: @primary-background-contrast; + } +} + +#login-card { + .input-text { + input:-webkit-autofill { + -webkit-box-shadow: 0 0 0 20px @content-background-color inset; + } + } +} + +/** ---------------------------------------------------------------------------- + * Room components + */ + +.toggle-favorite { + color: @component-color; +} + +.upload-progress-progress { + background-color: @success-background; +} + +.messages-container { + .edit-room-title { + color: @secondary-font-color; + + &:hover { + color: @primary-font-color; + } + } + + .footer { + background: @content-background-color; + } +} + +.message-form { + .message-buttons { + .buttonColors(lighten(@primary-font-color, 25%), @secondary-background-color); + + &:hover { + background-color: mix(@secondary-background-color, contrast(@primary-font-color), 20%); + } + } + + .message-form-text { + &.editing { + background-color: lighten(@pending-color, 40%); + } + } +} + +.message.editing { + background-color: lighten(@pending-color, 40%); +} + +.rc-old { + & .popup-item { + &.selected { + color: @primary-action-contrast; + background-color: @primary-action-color; + } + } +} + +.messages-box { + &.selectable .selected { + background-color: @selection-background; + } + + // .editing .body, + // textarea.editing { + // background-color: lighten(@pending-color, 40%); + // } +} + +/** ---------------------------------------------------------------------------- + * Message content + */ + +.message { + &.new-day::before { + background-color: @content-background-color; + } + + &.new-day::after { + border-color: @component-color; + } + + .message-dropdown, + .options-menu { + color: lighten(@primary-font-color, 13%); + + ul li:hover { + background-color: @tertiary-background-color; + } + } + + a { + color: @link-font-color; + + &:hover { + color: darken(@link-font-color, 10%); + } + } + + .mention-link { + background-color: fade(@rc-color-button-primary, 20%); + + &.mention-link-me { + background: @primary-action-color; + color: @primary-action-contrast; + } + + &.mention-link-all { + background: @attention-color; + color: @primary-action-contrast; + } + } + + .highlight-text { + background-color: @selection-background; + } +} + +/** ---------------------------------------------------------------------------- + * Side nav + */ +.side-nav { + .arrow::before, + .arrow::after { + background-color: @tertiary-font-color; + } + + li.active { + background-color: @transparent-light !important; + } + + i.status-offline { + color: @transparent-lighter !important; + } + + i { + color: @transparent-lighter; + } + + .opt i:hover { + color: @transparent-lightest; + } + + .has-alert .name { + color: @primary-background-contrast; + } + + .unread { + color: @success-color; + border: 1px solid @success-color; + } + + .unread.unread-mention { + background-color: @success-color; + color: contrast(@success-color, #000000, #ffffff, 50%); + } + + .button { + .buttonColors(@tertiary-font-color, mix(@primary-action-color, @primary-background-color)); + } + + .options button { + .buttonColors(@tertiary-font-color, @primary-background-color); + } +} + +.sidebar-item__last-message { + a:not(.mention-link) { + color: @link-font-color; + + &:hover { + color: darken(@link-font-color, 10%); + } + } +} + +.message-popup.search-results-list { + background-color: lighten(@primary-background-color, 2.5%); + + .popup-item.selected { + background-color: @transparent-darker; + } +} + +/** ---------------------------------------------------------------------------- + * Flex tabs / admin fly-out panels + */ +.flex-tab { + .message { + &.new-day::before { + background-color: @secondary-background-color; + } + } + + .channel-settings { + .buttons { + .button { + .buttonColors(lighten(@primary-font-color, 25%), @secondary-background-color); + } + } + + .input.checkbox.toggle { + input:checked + label::before { + background-color: @primary-background-color; + } + } + } +} + +.flex-tab-bar { + .tab-button { + &:hover { + background-color: @secondary-background-color; + } + + &.active { + background-color: @secondary-background-color; + border-right-color: @selection-color; + } + + &.attention { + animation-duration: 1000ms; + animation-name: blink; + animation-iteration-count: infinite; + animation-direction: alternate; + } + } + + .counter { + background: @secondary-font-color; + color: white; + } +} + +/** ---------------------------------------------------------------------------- + * User status / user meta + */ +i.status-online { + color: @status-online; +} + +.status-bg-online { + background-color: @status-online; +} + +.account-box .status-online .thumb::after, +.account-box .status.online::after, +.popup-user-status-online, +.status-online::after, +.user-image.status-online .avatar::after { + background-color: @status-online; + border-color: darken(@status-online, 10%); +} + +.account-box .status-offline .thumb::after, +.account-box .status.offline::after { + background-color: @transparent-lighter; +} + +i.status-away { + color: @status-away; +} + +.status-bg-away { + background-color: @status-away; +} + +.account-box .status-away .thumb::after, +.account-box .status.away::after, +.popup-user-status-away, +.status-away::after, +.status-pending::after, +.user-image.status-away .avatar::after { + background-color: @status-away; + border-color: darken(@status-away, 10%); +} + +i.status-busy { + color: @status-busy; +} + +.status-bg-busy { + background-color: @status-busy; +} + +.account-box .status-busy .thumb::after, +.account-box .status.busy::after, +.popup-user-status-busy, +.status-busy::after, +.user-image.status-busy .avatar::after { + background-color: @status-busy; + border-color: darken(@status-busy, 10%); +} + +i.status-offline { + color: @status-offline; +} + +.status-bg-offline { + background-color: @status-offline; +} + +.popup-user-status-offline, +.status-offline::after, +.user-image.status-offline .avatar::after { + background-color: @status-offline; + border-color: darken(@status-offline, 10%); +} + +// .popup-user-status-system { +// border-color: transparent; +// } + +// .user-view { +// .box::after, +// .stats li, +// .tags li { +// background-color: @component-color; +// } +// } + +/** ---------------------------------------------------------------------------- + * Buttons! + */ +.actionLinks li .action-link { + .buttonColors(@primary-action-contrast, @primary-action-color); +} + +// new layout buttons + +.button { + .buttonColors(@default-action-contrast, @default-action-color); + + &.primary { + .buttonColors(@primary-action-contrast, @primary-action-color); + + &[disabled] { + background-color: lighten(desaturate(@primary-action-color, 50%), 30%); + } + } + + &.secondary { + .buttonColors(@secondary-action-contrast, @secondary-action-color); + + &[disabled] { + background-color: lighten(desaturate(@secondary-action-color, 50%), 30%); + } + } + + &.tertiary { + .buttonColors(@primary-action-contrast, @selection-color); + + &[disabled] { + background-color: lighten(desaturate(@selection-color, 50%), 30%); + } + } + + &.danger { + .buttonColors(@error-contrast, @error-color); + + &[disabled] { + background-color: lighten(desaturate(@error-color, 50%), 30%); + } + } +} + +/** ---------------------------------------------------------------------------- + * Feedback and overlay content + */ + +.alert-warning { + color: darken(@pending-color, 25%); + background-color: @pending-background; +} + +.alert-link { + color: @link-font-color; + + &:hover { + color: darken(@link-font-color, 10%); + } +} + +label.required::after { + color: @error-color; +} + +/** ---------------------------------------------------------------------------- + * Loading + */ + +.main-content, +.flex-tab { + .loading-animation > .bounce { + background-color: @primary-font-color; + } +} + +.loading-animation.loading-animation--primary > .bounce { + background-color: @primary-font-color; +} + +@keyframes blink { + from { + color: @selection-color; + } + + to { + opacity: inherit; + } +} + +/** ---------------------------------------------------------------------------- + * Input Range Slider + */ + +.range-slider-range::-webkit-slider-thumb { + background-color: @primary-background-color; +} + +.range-slider-range::-webkit-slider-thumb:hover { + background-color: darken(@success-color, 30%); +} + +.range-slider-range:active::-webkit-slider-thumb { + background-color: darken(@success-color, 10%); +} + +.range-slider-range::-moz-range-thumb { + background-color: @primary-background-color; +} + +.range-slider-range::-moz-range-thumb:hover { + background-color: darken(@success-color, 30%); +} + +.range-slider-range:active::-moz-range-thumb { + background-color: darken(@success-color, 10%); +} + +.range-slider-value { + color: lighten(@tertiary-background-color, 50%); + background-color: @primary-background-color; +} + +.range-slider-value::after { + border-top-color: transparent; + border-right-color: @primary-background-color; + border-bottom-color: transparent; +} + +.range-slider-range::-moz-range-track { + background-color: @tertiary-background-color; +} + +.announcement { + background-color: @primary-background-color; + &.warning { + background-color: var(--rc-color-alert); + } + &.error { + background-color: var(--rc-color-alert-message-warning); + } +} diff --git a/packages/rocketchat-theme/server/server.coffee b/packages/rocketchat-theme/server/server.coffee deleted file mode 100644 index 8958ab465630..000000000000 --- a/packages/rocketchat-theme/server/server.coffee +++ /dev/null @@ -1,125 +0,0 @@ -less = Npm.require('less') -autoprefixer = Npm.require('less-plugin-autoprefix') -crypto = Npm.require('crypto') - -calculateClientHash = WebAppHashing.calculateClientHash -WebAppHashing.calculateClientHash = (manifest, includeFilter, runtimeConfigOverride) -> - css = RocketChat.theme.getCss() - - WebAppInternals.staticFiles['/__cordova/theme.css'] = WebAppInternals.staticFiles['/theme.css'] = - cacheable: true - sourceMapUrl: undefined - type: 'css' - content: css - - hash = crypto.createHash('sha1').update(css).digest('hex') - - themeManifestItem = _.find manifest, (item) -> return item.path is 'app/theme.css' - if not themeManifestItem? - themeManifestItem = {} - manifest.push themeManifestItem - - themeManifestItem.path = 'app/theme.css' - themeManifestItem.type = 'css' - themeManifestItem.cacheable = true - themeManifestItem.where = 'client' - themeManifestItem.url = "/theme.css?#{hash}" - themeManifestItem.size = css.length - themeManifestItem.hash = hash - - calculateClientHash.call this, manifest, includeFilter, runtimeConfigOverride - - -RocketChat.theme = new class - variables: {} - files: [ - 'assets/stylesheets/global/_variables.less' - 'assets/stylesheets/utils/_emojione.import.less' - 'assets/stylesheets/utils/_fonts.import.less' - 'assets/stylesheets/utils/_keyframes.import.less' - 'assets/stylesheets/utils/_lesshat.import.less' - 'assets/stylesheets/utils/_preloader.import.less' - 'assets/stylesheets/utils/_reset.import.less' - 'assets/stylesheets/utils/_octicons.less' - 'assets/stylesheets/utils/_chatops.less' - 'assets/stylesheets/animation.css' - 'assets/stylesheets/base.less' - 'assets/stylesheets/fontello.css' - 'assets/stylesheets/rtl.less' - 'assets/stylesheets/swipebox.min.css' - 'assets/stylesheets/utils/_colors.import.less' - ] - - constructor: -> - RocketChat.settings.add 'css', '' - RocketChat.settings.addGroup 'Theme' - - compile = _.debounce Meteor.bindEnvironment(@compile.bind(@)), 200 - - RocketChat.settings.onload '*', Meteor.bindEnvironment (key, value, initialLoad) => - if /^theme-.+/.test(key) is false then return - - name = key.replace /^theme-[a-z]+-/, '' - if @variables[name]? - @variables[name].value = value - - compile() - - compile: -> - content = [ - @getVariablesAsLess() - ] - - content.push Assets.getText file for file in @files - - content = content.join '\n' - - options = - compress: true - plugins: [ - new autoprefixer() - ] - - start = Date.now() - less.render content, options, (err, data) -> - console.log 'stop rendering', Date.now() - start - if err? - return console.log err - - RocketChat.settings.updateById 'css', data.css - - process.emit('message', {refresh: 'client'}) - - addVariable: (type, name, value, persist=true) -> - @variables[name] = - type: type - value: value - - if persist is true - config = - group: 'Theme' - type: type - section: type - public: false - - RocketChat.settings.add "theme-#{type}-#{name}", value, config - - addPublicColor: (name, value) -> - @addVariable 'color', name, value, true - - getVariablesAsObject: -> - obj = {} - for name, variable of @variables - obj[name] = variable.value - - return obj - - getVariablesAsLess: -> - items = [] - for name, variable of @variables - items.push "@#{name}: #{variable.value};" - - return items.join '\n' - - getCss: -> - return RocketChat.settings.get 'css' diff --git a/packages/rocketchat-theme/server/server.js b/packages/rocketchat-theme/server/server.js new file mode 100644 index 000000000000..61325fcf3f98 --- /dev/null +++ b/packages/rocketchat-theme/server/server.js @@ -0,0 +1,185 @@ +/* globals WebAppHashing */ + +import _ from 'underscore'; +import less from 'less'; +import Autoprefixer from 'less-plugin-autoprefix'; +import crypto from 'crypto'; + +const logger = new Logger('rocketchat:theme', { + methods: { + stop_rendering: { + type: 'info', + }, + }, +}); + +WebApp.rawConnectHandlers.use(function(req, res, next) { + const path = req.url.split('?')[0]; + const prefix = __meteor_runtime_config__.ROOT_URL_PATH_PREFIX || ''; + if (path === `${ prefix }/__cordova/theme.css` || path === `${ prefix }/theme.css`) { + const css = RocketChat.theme.getCss(); + const hash = crypto.createHash('sha1').update(css).digest('hex'); + res.setHeader('Content-Type', 'text/css; charset=UTF-8'); + res.setHeader('ETag', `"${ hash }"`); + res.write(css); + return res.end(); + } else { + return next(); + } +}); + +const { calculateClientHash } = WebAppHashing; + +WebAppHashing.calculateClientHash = function(manifest, includeFilter, runtimeConfigOverride) { + const css = RocketChat.theme.getCss(); + if (css.trim() !== '') { + const hash = crypto.createHash('sha1').update(css).digest('hex'); + let themeManifestItem = _.find(manifest, function(item) { + return item.path === 'app/theme.css'; + }); + if (themeManifestItem == null) { + themeManifestItem = {}; + manifest.push(themeManifestItem); + } + themeManifestItem.path = 'app/theme.css'; + themeManifestItem.type = 'css'; + themeManifestItem.cacheable = true; + themeManifestItem.where = 'client'; + themeManifestItem.url = `/theme.css?${ hash }`; + themeManifestItem.size = css.length; + themeManifestItem.hash = hash; + } + return calculateClientHash.call(this, manifest, includeFilter, runtimeConfigOverride); +}; + +RocketChat.theme = new class { + constructor() { + this.variables = {}; + this.packageCallbacks = []; + this.files = ['server/colors.less']; + this.customCSS = ''; + RocketChat.settings.add('css', ''); + RocketChat.settings.addGroup('Layout'); + RocketChat.settings.onload('css', Meteor.bindEnvironment((key, value, initialLoad) => { + if (!initialLoad) { + Meteor.startup(function() { + process.emit('message', { + refresh: 'client', + }); + }); + } + })); + this.compileDelayed = _.debounce(Meteor.bindEnvironment(this.compile.bind(this)), 100); + Meteor.startup(() => { + RocketChat.settings.onAfterInitialLoad(() => { + RocketChat.settings.get(/^theme-./, Meteor.bindEnvironment((key, value) => { + if (key === 'theme-custom-css' && value != null) { + this.customCSS = value; + } else { + const name = key.replace(/^theme-[a-z]+-/, ''); + if (this.variables[name] != null) { + this.variables[name].value = value; + } + } + + this.compileDelayed(); + })); + }); + }); + } + + compile() { + let content = [this.getVariablesAsLess()]; + + content.push(...this.files.map((name) => Assets.getText(name))); + + content.push(...this.packageCallbacks.map((name) => name())); + + content.push(this.customCSS); + content = content.join('\n'); + const options = { + compress: true, + plugins: [new Autoprefixer()], + }; + const start = Date.now(); + return less.render(content, options, function(err, data) { + logger.stop_rendering(Date.now() - start); + if (err != null) { + return console.log(err); + } + RocketChat.settings.updateById('css', data.css); + return Meteor.startup(function() { + return Meteor.setTimeout(function() { + return process.emit('message', { + refresh: 'client', + }); + }, 200); + }); + }); + } + + addColor(name, value, section, properties) { + const config = { + group: 'Colors', + type: 'color', + editor: 'color', + public: true, + properties, + section, + }; + + return RocketChat.settings.add(`theme-color-${ name }`, value, config); + } + + addVariable(type, name, value, section, persist = true, editor, allowedTypes, property) { + this.variables[name] = { + type, + value, + }; + if (persist) { + const config = { + group: 'Layout', + type, + editor: editor || type, + section, + public: true, + allowedTypes, + property, + }; + return RocketChat.settings.add(`theme-${ type }-${ name }`, value, config); + } + + } + + addPublicColor(name, value, section, editor = 'color', property) { + return this.addVariable('color', name, value, section, true, editor, ['color', 'expression'], property); + } + + addPublicFont(name, value) { + return this.addVariable('font', name, value, 'Fonts', true); + } + + getVariablesAsObject() { + return Object.keys(this.variables).reduce((obj, name) => { + obj[name] = this.variables[name].value; + return obj; + }, {}); + } + + getVariablesAsLess() { + return Object.keys(this.variables).map((name) => { + const variable = this.variables[name]; + return `@${ name }: ${ variable.value };`; + }).join('\n'); + } + + addPackageAsset(cb) { + this.packageCallbacks.push(cb); + return this.compileDelayed(); + } + + getCss() { + return RocketChat.settings.get('css') || ''; + } + +}; diff --git a/packages/rocketchat-theme/server/variables.coffee b/packages/rocketchat-theme/server/variables.coffee deleted file mode 100644 index 9830698b0e87..000000000000 --- a/packages/rocketchat-theme/server/variables.coffee +++ /dev/null @@ -1,21 +0,0 @@ -RocketChat.theme.addPublicColor "content-background-color", "#FFF" -RocketChat.theme.addPublicColor "primary-background-color", "#04436A" -RocketChat.theme.addPublicColor "secondary-background-color", "#F4F4F4" -RocketChat.theme.addPublicColor "tertiary-background-color", "#EAEAEA" -RocketChat.theme.addPublicColor "primary-font-color", "#444444" -RocketChat.theme.addPublicColor "secondary-font-color", "#7F7F7F" -RocketChat.theme.addPublicColor "tertiary-font-color", "rgba(255, 255, 255, 0.6)" -RocketChat.theme.addPublicColor "input-font-color", "rgba(255, 255, 255, 0.85)" -RocketChat.theme.addPublicColor "link-font-color", "#008CE3" -RocketChat.theme.addPublicColor "info-font-color", "#AAAAAA" -RocketChat.theme.addPublicColor "info-active-font-color", "#FF0000" -RocketChat.theme.addPublicColor "smallprint-font-color", "#C2E7FF" -RocketChat.theme.addPublicColor "smallprint-hover-color", "#FFFFFF" -RocketChat.theme.addPublicColor "status-online", "#35AC19" -RocketChat.theme.addPublicColor "status-offline", "rgba(150, 150, 150, 0.50)" -RocketChat.theme.addPublicColor "status-busy", "#D30230" -RocketChat.theme.addPublicColor "status-away", "#FCB316" -RocketChat.theme.addPublicColor "code-background", "#F8F8F8" -RocketChat.theme.addPublicColor "code-border", "#CCC" -RocketChat.theme.addPublicColor "code-color", "#333" -RocketChat.theme.addPublicColor "blockquote-background", "#CCC" diff --git a/packages/rocketchat-theme/server/variables.js b/packages/rocketchat-theme/server/variables.js new file mode 100644 index 000000000000..4aae864e2000 --- /dev/null +++ b/packages/rocketchat-theme/server/variables.js @@ -0,0 +1,79 @@ + +// TODO: Define registers/getters/setters for packages to work with established +// heirarchy of colors instead of making duplicate definitions +// TODO: Settings pages to show simple separation of major/minor/addon colors +// TODO: Get major colours as swatches for minor colors in minicolors plugin +// TODO: Minicolors settings to use rgb for alphas, hex otherwise +// TODO: Add setting toggle to use defaults for minor colours and hide settings + +// New colors, used for shades on solid backgrounds +// Defined range of transparencies reduces random colour variances +// Major colors form the core of the scheme +// Names changed to reflect usage, comments show pre-refactor names + +const reg = /--(rc-color-.*?): (.*?);/igm; + +const colors = [...Assets.getText('client/imports/general/variables.css').match(reg)].map((color) => { + const [name, value] = color.split(': '); + return [name.replace('--', ''), value.replace(';', '')]; +}); + +colors.forEach(([key, color]) => { + if (/var/.test(color)) { + const [, value] = color.match(/var\(--(.*?)\)/i); + return RocketChat.theme.addPublicColor(key, value, 'Colors', 'expression'); + } + RocketChat.theme.addPublicColor(key, color, 'Colors'); +}); + +const majorColors = { + 'content-background-color': '#FFFFFF', + 'primary-background-color': '#04436A', + 'primary-font-color': '#444444', + 'primary-action-color': '#13679A', // was action-buttons-color + 'secondary-background-color': '#F4F4F4', + 'secondary-font-color': '#A0A0A0', + 'secondary-action-color': '#DDDDDD', + 'component-color': '#EAEAEA', + 'success-color': '#4dff4d', + 'pending-color': '#FCB316', + 'error-color': '#BC2031', + 'selection-color': '#02ACEC', + 'attention-color': '#9C27B0', +}; + +// Minor colours implement major colours by default, but can be overruled +const minorColors = { + 'tertiary-background-color': '@component-color', + 'tertiary-font-color': '@transparent-lightest', + 'link-font-color': '@primary-action-color', + 'info-font-color': '@secondary-font-color', + 'custom-scrollbar-color': '@transparent-darker', + 'status-online': '@success-color', + 'status-away': '@pending-color', + 'status-busy': '@error-color', + 'status-offline': '@transparent-darker', +}; + +// Bulk-add settings for color scheme +Object.keys(majorColors).forEach((key) => { + const value = majorColors[key]; + RocketChat.theme.addPublicColor(key, value, 'Old Colors'); +}); + +Object.keys(minorColors).forEach((key) => { + const value = minorColors[key]; + RocketChat.theme.addPublicColor(key, value, 'Old Colors (minor)', 'expression'); +}); + +RocketChat.theme.addPublicFont('body-font-family', '-apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Oxygen, Ubuntu, Cantarell, \'Helvetica Neue\', \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\', \'Meiryo UI\', Arial, sans-serif'); + +RocketChat.settings.add('theme-custom-css', '', { + group: 'Layout', + type: 'code', + code: 'text/css', + multiline: true, + section: 'Custom CSS', + public: true, +}); + diff --git a/packages/rocketchat-token-login/client/login_token_client.js b/packages/rocketchat-token-login/client/login_token_client.js new file mode 100644 index 000000000000..051e51d80ad9 --- /dev/null +++ b/packages/rocketchat-token-login/client/login_token_client.js @@ -0,0 +1,20 @@ +Meteor.loginWithLoginToken = function(token) { + Accounts.callLoginMethod({ + methodArguments: [{ + loginToken: token, + }], + userCallback(error) { + if (!error) { + FlowRouter.go('/'); + } + }, + }); +}; + +FlowRouter.route('/login-token/:token', { + name: 'tokenLogin', + action() { + BlazeLayout.render('loginLayout'); + Meteor.loginWithLoginToken(this.getParam('token')); + }, +}); diff --git a/packages/rocketchat-token-login/package.js b/packages/rocketchat-token-login/package.js new file mode 100644 index 000000000000..785e5f333618 --- /dev/null +++ b/packages/rocketchat-token-login/package.js @@ -0,0 +1,23 @@ +Package.describe({ + name: 'rocketchat:login-token', + summary: '', + version: '1.0.0', +}); + +Package.onUse(function(api) { + + // Server libs + api.use('rocketchat:logger', 'server'); + + api.use('kadira:flow-router', 'client'); + + api.use('rocketchat:lib'); + api.use('accounts-base'); + api.use('ecmascript'); + + // Server files + api.addFiles('server/login_token_server.js', 'server'); + + // Client files + api.addFiles('client/login_token_client.js', 'client'); +}); diff --git a/packages/rocketchat-token-login/server/login_token_server.js b/packages/rocketchat-token-login/server/login_token_server.js new file mode 100644 index 000000000000..d3a20126d71c --- /dev/null +++ b/packages/rocketchat-token-login/server/login_token_server.js @@ -0,0 +1,19 @@ +/* globals Accounts */ + +Accounts.registerLoginHandler('login-token', function(result) { + if (!result.loginToken) { + return; + } + + const user = Meteor.users.findOne({ + 'services.loginToken.token': result.loginToken, + }); + + if (user) { + Meteor.users.update({ _id: user._id }, { $unset: { 'services.loginToken': 1 } }); + + return { + userId: user._id, + }; + } +}); diff --git a/packages/rocketchat-tokenpass/README.md b/packages/rocketchat-tokenpass/README.md new file mode 100644 index 000000000000..8eb3a0c7a37a --- /dev/null +++ b/packages/rocketchat-tokenpass/README.md @@ -0,0 +1,3 @@ +# Tokenpass OAuth Flow + +An implementation of the Tokenpass OAuth flow with Tokenpass using RocketChat CustomOAuth. See the [Tokenpass API Reference](http://apidocs.tokenly.com/tokenpass/#oauth-integration) for more details. diff --git a/packages/rocketchat-tokenpass/client/channelSettings.css b/packages/rocketchat-tokenpass/client/channelSettings.css new file mode 100644 index 000000000000..08c0275b14c4 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/channelSettings.css @@ -0,0 +1,47 @@ +.channelSettings-tokenpass { + flex-direction: column; + + &.tokenpass__editing { + & .button.edit { + visibility: hidden !important; + } + } + + & .details { + padding-left: 1rem; + } + + & button { + margin: 0 5px 0 0 !important; + } + + & button[disabled] { + opacity: 0.5; + } + + & button[disabled]:hover { + opacity: 0.5; + } + + & .js-edit { + float: right; + } + + & .chip-container { + margin: 0; + + & > li { + padding: 2px 8px; + } + } + + &__form .button { + visibility: visible !important; + } + + &__input { + height: auto !important; + margin: 0 0 10px !important; + padding: 10px !important; + } +} diff --git a/packages/rocketchat-tokenpass/client/login-button.css b/packages/rocketchat-tokenpass/client/login-button.css new file mode 100644 index 000000000000..1171df2633cc --- /dev/null +++ b/packages/rocketchat-tokenpass/client/login-button.css @@ -0,0 +1,14 @@ +.icon-tokenpass.service-icon { + display: inline-block; + + width: 25px; + height: 1em; + + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAddEVYdFRpdGxlAFRva2VubHlfTG9nb19JY29uX1doaXRldF224QAAAapJREFUOI2lk89OE1EUxn9nrumS2GZIhiaFBFekQsILsME/JC7AF2DVpT4BBI3GNRvZoG58Ad0SdCEvwKJW3ehCQmfajB1YAr33uJiZOg2hbeK3u1/O/d1zvnuvUFCr1SqVK/4h6EruqdAAVJR3/yrlKOnF9+v1+mXueEVQpeI/LUJulq6Uy/6TojMAhWE4raLb4yF5U/qs2+0G10Aq8hLl9sQgmOo793wIFEXRIkoj834C8QhAnNWA0jjpdJYAbgGosgsY4EqdfYQxDwTuAmDlBwBG99O9fNW+OfCMbQIlz+kusCrtdmcD0Q/ZaSeoe2iMuRg1k7W2hHgHwGzamTyWdhh9AxbGRzJS37202/+WymkUrYvyMTN+o25t3GiXIsZYdwjMpRQ2BCAMo08Kq6RhLxbDVivvAcToJlwPW+DzzExwTyC9fqcck97cL2AK8LPTGgCivM0aioFz4A5gPWE5CIKmBxAEQRP0TVY4n0NukJ9BAN1P9xZetu33t4DeqGyGJJyhupMvB6BardZD5dXEIMeLarU6+AFDvz9J4tcgRxNgviTJn72i8RdLE6KbF5O00AAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + background-position: center center; +} + +.button.external-login.tokenpass { + background-color: #4170a0; +} diff --git a/packages/rocketchat-tokenpass/client/roomType.js b/packages/rocketchat-tokenpass/client/roomType.js new file mode 100644 index 000000000000..71aa74ae91e9 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/roomType.js @@ -0,0 +1,21 @@ +import { RoomTypeConfig } from 'meteor/rocketchat:lib'; + +class TokenPassRoomType extends RoomTypeConfig { + constructor() { + super({ + identifier: 'tokenpass', + order: 1, + }); + + this.customTemplate = 'tokenChannelsList'; + } + + condition() { + const user = Meteor.users.findOne(Meteor.userId(), { fields: { 'services.tokenpass': 1 } }); + const hasTokenpass = !!(user && user.services && user.services.tokenpass); + + return hasTokenpass; + } +} + +RocketChat.roomTypes.add(new TokenPassRoomType()); diff --git a/packages/rocketchat-tokenpass/client/startup.js b/packages/rocketchat-tokenpass/client/startup.js new file mode 100644 index 000000000000..a878e904b628 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/startup.js @@ -0,0 +1,16 @@ +Meteor.startup(function() { + RocketChat.ChannelSettings.addOption({ + group: ['room'], + id: 'tokenpass', + template: 'channelSettings__tokenpass', + validation(data) { + if (data && data.rid) { + const room = RocketChat.models.Rooms.findOne(data.rid, { fields: { tokenpass: 1 } }); + + return room && room.tokenpass; + } + + return false; + }, + }); +}); diff --git a/packages/rocketchat-tokenpass/client/styles.css b/packages/rocketchat-tokenpass/client/styles.css new file mode 100644 index 000000000000..126731991bd7 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/styles.css @@ -0,0 +1,12 @@ +.icon-tokenpass { + display: inline-block; + + width: 24px; + height: 0.8em; + + margin-bottom: -1px; + + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MzIgMzgxLjUiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDojNDE3MGEwO308L3N0eWxlPjwvZGVmcz48dGl0bGU+VG9rZW5seV9JY29uPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iTGF5ZXJfMS0yIiBkYXRhLW5hbWU9IkxheWVyIDEiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTQyOC4zMSwxNzcsMzM0LjA3LDEzLjc2QTI3LjUyLDI3LjUyLDAsMCwwLDMxMC4yNCwwaC03OS40VjEzMy44OWg3NFYxMTIuODRoMTcuNzJsMTguMTMsMzEuNGExMi41MiwxMi41MiwwLDAsMSwwLDEyLjcxLDEyLjc1LDEyLjc1LDAsMCwxLTExLjIyLDYuNTRIMTAyLjU2YTEyLjc1LDEyLjc1LDAsMCwxLTExLjIyLTYuNTQsMTIuNTIsMTIuNTIsMCwwLDEsMC0xMi43MWwxOC4xMy0zMS40aDE3LjcydjIxLjA1aDc0VjBoLTc5LjRBMjcuNTIsMjcuNTIsMCwwLDAsOTcuOTMsMTMuNzZMMy42OSwxNzdhMjcuNTIsMjcuNTIsMCwwLDAsMCwyNy41Mkw5Ny45MywzNjcuNzRhMjcuNTIsMjcuNTIsMCwwLDAsMjMuODQsMTMuNzZoNzkuNFYyNDcuNjFoLTc0djIxLjA2SDEwOS40N2wtMTguMTMtMzEuNGExMi41MiwxMi41MiwwLDAsMSwwLTEyLjcxQTEyLjc1LDEyLjc1LDAsMCwxLDEwMi41NiwyMThIMzI5LjQ0YTEyLjc1LDEyLjc1LDAsMCwxLDExLjIyLDYuNTQsMTIuNTIsMTIuNTIsMCwwLDEsMCwxMi43MWwtMTguMTMsMzEuNEgzMDQuODFWMjQ3LjYxaC03NFYzODEuNWg3OS40YTI3LjUyLDI3LjUyLDAsMCwwLDIzLjg0LTEzLjc2bDk0LjI0LTE2My4yM0EyNy41MiwyNy41MiwwLDAsMCw0MjguMzEsMTc3WiIvPjwvZz48L2c+PC9zdmc+); + background-repeat: no-repeat; + background-position: center center; +} diff --git a/packages/rocketchat-tokenpass/client/tokenChannelsList.html b/packages/rocketchat-tokenpass/client/tokenChannelsList.html new file mode 100644 index 000000000000..ae892bfd614a --- /dev/null +++ b/packages/rocketchat-tokenpass/client/tokenChannelsList.html @@ -0,0 +1,14 @@ + diff --git a/packages/rocketchat-tokenpass/client/tokenChannelsList.js b/packages/rocketchat-tokenpass/client/tokenChannelsList.js new file mode 100644 index 000000000000..0044bb156aeb --- /dev/null +++ b/packages/rocketchat-tokenpass/client/tokenChannelsList.js @@ -0,0 +1,24 @@ +Template.tokenChannelsList.helpers({ + rooms() { + return Template.instance().tokenpassRooms.get().filter((room) => RocketChat.models.Subscriptions.find({ rid: room._id }).count() === 0); + }, +}); + +Template.tokenChannelsList.onRendered(function() { + Tracker.autorun((c) => { + const user = Meteor.user(); + if (user && user.services && user.services.tokenpass) { + c.stop(); + + Meteor.call('findTokenChannels', (error, result) => { + if (!error) { + this.tokenpassRooms.set(result); + } + }); + } + }); +}); + +Template.tokenChannelsList.onCreated(function() { + this.tokenpassRooms = new ReactiveVar([]); +}); diff --git a/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.html b/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.html new file mode 100644 index 000000000000..4f9ab15e9f37 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.html @@ -0,0 +1,39 @@ + diff --git a/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.js b/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.js new file mode 100644 index 000000000000..0ea2a595a902 --- /dev/null +++ b/packages/rocketchat-tokenpass/client/tokenpassChannelSettings.js @@ -0,0 +1,102 @@ +Template.channelSettings__tokenpass.helpers({ + addDisabled() { + const { balance, token } = Template.instance(); + return balance.get() && token.get() ? '' : 'disabled'; + }, + list() { + return Template.instance().list.get(); + }, + save() { + const { list, initial } = Template.instance(); + return JSON.stringify(list.get()) !== JSON.stringify(initial); + }, + editing() { + return Template.instance().editing.get() ? 'tokenpass__editing' : ''; + }, + requiredChecked() { + return Template.instance().requireAll.get() ? 'checked' : ''; + }, + requiredLabel() { + return Template.instance().requireAll.get() ? t('Require_all_tokens') : t('Require_any_token'); + }, + requiredDisabled() { + return !Template.instance().editing.get() ? 'disabled' : ''; + }, + editDisabled() { + return Template.instance().editing.get() ? 'disabled' : ''; + }, +}); + +Template.channelSettings__tokenpass.onCreated(function() { + const room = ChatRoom.findOne(this.data.rid, { fields: { tokenpass : 1 } }); + + this.editing = new ReactiveVar(false); + this.initial = room.tokenpass; + this.requireAll = new ReactiveVar(room.tokenpass.require === 'all'); + this.list = new ReactiveVar(this.initial.tokens); + this.token = new ReactiveVar(''); + this.balance = new ReactiveVar(''); +}); + +Template.channelSettings__tokenpass.events({ + 'click .js-edit'(e, i) { + i.editing.set(true); + }, + 'input [name=token]'(e, i) { + i.token.set(e.target.value); + }, + 'input [name=balance]'(e, i) { + i.balance.set(e.target.value); + }, + 'click .js-add'(e, i) { + e.preventDefault(); + const instance = Template.instance(); + const { balance, token, list } = instance; + list.set([...list.get().filter((t) => t.token !== token), { token:token.get(), balance: balance.get() }]); + + + [...i.findAll('input')].forEach((el) => el.value = ''); + return balance.set('') && token.set(''); + }, + 'click .js-remove'(e, instance) { + e.preventDefault(); + const { list, editing } = instance; + + if (!editing.get()) { + return; + } + list.set(list.get().filter((t) => t.token !== this.token)); + + }, + 'click .js-save'(e, i) { + e.preventDefault(); + + const tokenpass = { + require: i.find('[name=requireAllTokens]').checked ? 'all' : 'any', + tokens: i.list.get(), + }; + + Meteor.call('saveRoomSettings', this.rid, 'tokenpass', tokenpass, function(err) { + if (err) { + return handleError(err); + } + i.editing.set(false); + i.token.set(''); + i.balance.set(''); + i.initial = tokenpass; + [...i.findAll('input')].forEach((el) => el.value = ''); + return toastr.success(TAPi18n.__('Room_tokenpass_config_changed_successfully')); + }); + }, + 'click .js-cancel'(e, i) { + e.preventDefault(); + i.editing.set(false); + i.list.set(i.initial.tokens); + i.token.set(''); + i.balance.set(''); + [...i.findAll('input')].forEach((el) => el.value = ''); + }, + 'change [name=requireAllTokens]'(e, instance) { + instance.requireAll.set(e.currentTarget.checked); + }, +}); diff --git a/packages/rocketchat-tokenpass/common.js b/packages/rocketchat-tokenpass/common.js new file mode 100644 index 000000000000..245d102d2cd6 --- /dev/null +++ b/packages/rocketchat-tokenpass/common.js @@ -0,0 +1,36 @@ +/* global CustomOAuth */ + +const config = { + serverURL: '', + identityPath: '/oauth/user', + authorizePath: '/oauth/authorize', + tokenPath: '/oauth/access-token', + scope: 'user,tca,private-balances', + tokenSentVia: 'payload', + usernameField: 'username', + mergeUsers: true, + addAutopublishFields: { + forLoggedInUser: ['services.tokenpass'], + forOtherUsers: ['services.tokenpass.name'], + }, +}; + +const Tokenpass = new CustomOAuth('tokenpass', config); + +if (Meteor.isServer) { + Meteor.startup(function() { + RocketChat.settings.get('API_Tokenpass_URL', function(key, value) { + config.serverURL = value; + Tokenpass.configure(config); + }); + }); +} else { + Meteor.startup(function() { + Tracker.autorun(function() { + if (RocketChat.settings.get('API_Tokenpass_URL')) { + config.serverURL = RocketChat.settings.get('API_Tokenpass_URL'); + Tokenpass.configure(config); + } + }); + }); +} diff --git a/packages/rocketchat-tokenpass/package.js b/packages/rocketchat-tokenpass/package.js new file mode 100644 index 000000000000..1b4fc709e790 --- /dev/null +++ b/packages/rocketchat-tokenpass/package.js @@ -0,0 +1,51 @@ +Package.describe({ + name: 'rocketchat:tokenpass', + version: '0.0.1', + summary: 'RocketChat settings for Tokenpass OAuth flow', +}); + +Package.onUse(function(api) { + api.versionsFrom('1.0'); + api.use('accounts-base'); + api.use('ecmascript'); + api.use('service-configuration'); + api.use('templating', 'client'); + api.use('percolate:synced-cron'); + api.use('rocketchat:lib'); + api.use('rocketchat:authorization'); + api.use('rocketchat:custom-oauth'); + api.use('rocketchat:channel-settings'); + + api.addFiles('common.js'); + + api.addFiles('client/login-button.css', 'client'); + api.addFiles('client/channelSettings.css', 'client'); + api.addFiles('client/styles.css', 'client'); + + api.addFiles('client/startup.js', 'client'); + api.addFiles('client/roomType.js', 'client'); + api.addFiles('client/tokenChannelsList.html', 'client'); + api.addFiles('client/tokenChannelsList.js', 'client'); + api.addFiles('client/tokenpassChannelSettings.html', 'client'); + api.addFiles('client/tokenpassChannelSettings.js', 'client'); + + api.addFiles('server/startup.js', 'server'); + + api.addFiles('server/functions/getProtectedTokenpassBalances.js', 'server'); + api.addFiles('server/functions/getPublicTokenpassBalances.js', 'server'); + api.addFiles('server/functions/saveRoomTokens.js', 'server'); + api.addFiles('server/functions/saveRoomTokensMinimumBalance.js', 'server'); + api.addFiles('server/functions/updateUserTokenpassBalances.js', 'server'); + + api.addFiles('server/models/indexes.js', 'server'); + api.addFiles('server/models/Rooms.js', 'server'); + api.addFiles('server/models/Subscriptions.js', 'server'); + api.addFiles('server/models/Users.js', 'server'); + + api.addFiles('server/methods/findTokenChannels.js', 'server'); + api.addFiles('server/methods/getChannelTokenpass.js', 'server'); + + api.addFiles('server/cronRemoveUsers.js', 'server'); + + api.addFiles('server/Tokenpass.js', 'server'); +}); diff --git a/packages/rocketchat-tokenpass/server/Tokenpass.js b/packages/rocketchat-tokenpass/server/Tokenpass.js new file mode 100644 index 000000000000..24e82f2efdeb --- /dev/null +++ b/packages/rocketchat-tokenpass/server/Tokenpass.js @@ -0,0 +1,6 @@ +RocketChat.Tokenpass = { + validateAccess(tokenpass, balances) { + const compFunc = tokenpass.require === 'any' ? 'some' : 'every'; + return tokenpass.tokens[compFunc]((config) => balances.some((userToken) => config.token === userToken.asset && parseFloat(config.balance) <= parseFloat(userToken.balance))); + }, +}; diff --git a/packages/rocketchat-tokenpass/server/cronRemoveUsers.js b/packages/rocketchat-tokenpass/server/cronRemoveUsers.js new file mode 100644 index 000000000000..f8540c089bda --- /dev/null +++ b/packages/rocketchat-tokenpass/server/cronRemoveUsers.js @@ -0,0 +1,45 @@ +/* globals SyncedCron */ +function removeUsersFromTokenChannels() { + const rooms = {}; + + RocketChat.models.Rooms.findAllTokenChannels().forEach((room) => { + rooms[room._id] = room.tokenpass; + }); + + const users = {}; + + RocketChat.models.Subscriptions.findByRoomIds(Object.keys(rooms)).forEach((sub) => { + if (!users[sub.u._id]) { + users[sub.u._id] = []; + } + users[sub.u._id].push(sub.rid); + }); + + Object.keys(users).forEach((user) => { + const userInfo = RocketChat.models.Users.findOneById(user); + + if (userInfo && userInfo.services && userInfo.services.tokenpass) { + const balances = RocketChat.updateUserTokenpassBalances(userInfo); + + users[user].forEach((roomId) => { + const valid = RocketChat.Tokenpass.validateAccess(rooms[roomId], balances); + + if (!valid) { + RocketChat.removeUserFromRoom(roomId, userInfo); + } + }); + } + }); +} + +Meteor.startup(function() { + Meteor.defer(function() { + removeUsersFromTokenChannels(); + + SyncedCron.add({ + name: 'Remove users from Token Channels', + schedule: (parser) => parser.cron('0 * * * *'), + job: removeUsersFromTokenChannels, + }); + }); +}); diff --git a/packages/rocketchat-tokenpass/server/functions/getProtectedTokenpassBalances.js b/packages/rocketchat-tokenpass/server/functions/getProtectedTokenpassBalances.js new file mode 100644 index 000000000000..7a8c440c4ed2 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/functions/getProtectedTokenpassBalances.js @@ -0,0 +1,19 @@ +let userAgent = 'Meteor'; +if (Meteor.release) { userAgent += `/${ Meteor.release }`; } + +RocketChat.getProtectedTokenpassBalances = function(accessToken) { + try { + return HTTP.get( + `${ RocketChat.settings.get('API_Tokenpass_URL') }/api/v1/tca/protected/balances`, { + headers: { + Accept: 'application/json', + 'User-Agent': userAgent, + }, + params: { + oauth_token: accessToken, + }, + }).data; + } catch (error) { + throw new Error(`Failed to fetch protected tokenpass balances from Tokenpass. ${ error.message }`); + } +}; diff --git a/packages/rocketchat-tokenpass/server/functions/getPublicTokenpassBalances.js b/packages/rocketchat-tokenpass/server/functions/getPublicTokenpassBalances.js new file mode 100644 index 000000000000..719b58f66aad --- /dev/null +++ b/packages/rocketchat-tokenpass/server/functions/getPublicTokenpassBalances.js @@ -0,0 +1,19 @@ +let userAgent = 'Meteor'; +if (Meteor.release) { userAgent += `/${ Meteor.release }`; } + +RocketChat.getPublicTokenpassBalances = function(accessToken) { + try { + return HTTP.get( + `${ RocketChat.settings.get('API_Tokenpass_URL') }/api/v1/tca/public/balances`, { + headers: { + Accept: 'application/json', + 'User-Agent': userAgent, + }, + params: { + oauth_token: accessToken, + }, + }).data; + } catch (error) { + throw new Error(`Failed to fetch public tokenpass balances from Tokenpass. ${ error.message }`); + } +}; diff --git a/packages/rocketchat-tokenpass/server/functions/saveRoomTokens.js b/packages/rocketchat-tokenpass/server/functions/saveRoomTokens.js new file mode 100644 index 000000000000..0a61985aea9c --- /dev/null +++ b/packages/rocketchat-tokenpass/server/functions/saveRoomTokens.js @@ -0,0 +1,9 @@ +RocketChat.saveRoomTokenpass = function(rid, tokenpass) { + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + function: 'RocketChat.saveRoomTokens', + }); + } + + return RocketChat.models.Rooms.setTokenpassById(rid, tokenpass); +}; diff --git a/packages/rocketchat-tokenpass/server/functions/saveRoomTokensMinimumBalance.js b/packages/rocketchat-tokenpass/server/functions/saveRoomTokensMinimumBalance.js new file mode 100644 index 000000000000..3012197cc109 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/functions/saveRoomTokensMinimumBalance.js @@ -0,0 +1,13 @@ +import s from 'underscore.string'; + +RocketChat.saveRoomTokensMinimumBalance = function(rid, roomTokensMinimumBalance) { + if (!Match.test(rid, String)) { + throw new Meteor.Error('invalid-room', 'Invalid room', { + function: 'RocketChat.saveRoomTokensMinimumBalance', + }); + } + + const minimumTokenBalance = parseFloat(s.escapeHTML(roomTokensMinimumBalance)); + + return RocketChat.models.Rooms.setMinimumTokenBalanceById(rid, minimumTokenBalance); +}; diff --git a/packages/rocketchat-tokenpass/server/functions/updateUserTokenpassBalances.js b/packages/rocketchat-tokenpass/server/functions/updateUserTokenpassBalances.js new file mode 100644 index 000000000000..8eb841d7d9a9 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/functions/updateUserTokenpassBalances.js @@ -0,0 +1,14 @@ +import _ from 'underscore'; + +RocketChat.updateUserTokenpassBalances = function(user) { + if (user && user.services && user.services.tokenpass) { + const tcaPublicBalances = RocketChat.getPublicTokenpassBalances(user.services.tokenpass.accessToken); + const tcaProtectedBalances = RocketChat.getProtectedTokenpassBalances(user.services.tokenpass.accessToken); + + const balances = _.uniq(_.union(tcaPublicBalances, tcaProtectedBalances), false, (item) => item.asset); + + RocketChat.models.Users.setTokenpassTcaBalances(user._id, balances); + + return balances; + } +}; diff --git a/packages/rocketchat-tokenpass/server/methods/findTokenChannels.js b/packages/rocketchat-tokenpass/server/methods/findTokenChannels.js new file mode 100644 index 000000000000..c46915d3ee55 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/methods/findTokenChannels.js @@ -0,0 +1,21 @@ +Meteor.methods({ + findTokenChannels() { + if (!Meteor.userId()) { + return []; + } + + const user = Meteor.user(); + + if (user.services && user.services.tokenpass && user.services.tokenpass.tcaBalances) { + const tokens = {}; + user.services.tokenpass.tcaBalances.forEach((token) => { + tokens[token.asset] = 1; + }); + + return RocketChat.models.Rooms.findByTokenpass(Object.keys(tokens)) + .filter((room) => RocketChat.Tokenpass.validateAccess(room.tokenpass, user.services.tokenpass.tcaBalances)); + } + + return []; + }, +}); diff --git a/packages/rocketchat-tokenpass/server/methods/getChannelTokenpass.js b/packages/rocketchat-tokenpass/server/methods/getChannelTokenpass.js new file mode 100644 index 000000000000..da0928da8132 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/methods/getChannelTokenpass.js @@ -0,0 +1,17 @@ +Meteor.methods({ + getChannelTokenpass(rid) { + check(rid, String); + + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getChannelTokenpass' }); + } + + const room = RocketChat.models.Rooms.findOneById(rid); + + if (!room) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getChannelTokenpass' }); + } + + return room.tokenpass; + }, +}); diff --git a/packages/rocketchat-tokenpass/server/models/Rooms.js b/packages/rocketchat-tokenpass/server/models/Rooms.js new file mode 100644 index 000000000000..0a601e610d79 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/models/Rooms.js @@ -0,0 +1,41 @@ +RocketChat.models.Rooms.findByTokenpass = function(tokens) { + const query = { + 'tokenpass.tokens.token': { + $in: tokens, + }, + }; + + return this._db.find(query).fetch(); +}; + +RocketChat.models.Rooms.setTokensById = function(_id, tokens) { + const update = { + $set: { + 'tokenpass.tokens.token': tokens, + }, + }; + + return this.update({ _id }, update); +}; + +RocketChat.models.Rooms.setTokenpassById = function(_id, tokenpass) { + const update = { + $set: { + tokenpass, + }, + }; + + return this.update({ _id }, update); +}; + +RocketChat.models.Rooms.findAllTokenChannels = function() { + const query = { + tokenpass: { $exists: true }, + }; + const options = { + fields: { + tokenpass: 1, + }, + }; + return this._db.find(query, options); +}; diff --git a/packages/rocketchat-tokenpass/server/models/Subscriptions.js b/packages/rocketchat-tokenpass/server/models/Subscriptions.js new file mode 100644 index 000000000000..0d0f321a82b2 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/models/Subscriptions.js @@ -0,0 +1,15 @@ +RocketChat.models.Subscriptions.findByRoomIds = function(roomIds) { + const query = { + rid: { + $in: roomIds, + }, + }; + const options = { + fields: { + 'u._id': 1, + rid: 1, + }, + }; + + return this._db.find(query, options); +}; diff --git a/packages/rocketchat-tokenpass/server/models/Users.js b/packages/rocketchat-tokenpass/server/models/Users.js new file mode 100644 index 000000000000..670ea3e1f723 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/models/Users.js @@ -0,0 +1,23 @@ +RocketChat.models.Users.setTokenpassTcaBalances = function(_id, tcaBalances) { + const update = { + $set: { + 'services.tokenpass.tcaBalances': tcaBalances, + }, + }; + + return this.update(_id, update); +}; + +RocketChat.models.Users.getTokenBalancesByUserId = function(userId) { + const query = { + _id: userId, + }; + + const options = { + fields: { + 'services.tokenpass.tcaBalances': 1, + }, + }; + + return this.findOne(query, options); +}; diff --git a/packages/rocketchat-tokenpass/server/models/indexes.js b/packages/rocketchat-tokenpass/server/models/indexes.js new file mode 100644 index 000000000000..d438b667bead --- /dev/null +++ b/packages/rocketchat-tokenpass/server/models/indexes.js @@ -0,0 +1,3 @@ +Meteor.startup(function() { + RocketChat.models.Rooms.tryEnsureIndex({ 'tokenpass.tokens.token': 1 }); +}); diff --git a/packages/rocketchat-tokenpass/server/startup.js b/packages/rocketchat-tokenpass/server/startup.js new file mode 100644 index 000000000000..19b3d89938a8 --- /dev/null +++ b/packages/rocketchat-tokenpass/server/startup.js @@ -0,0 +1,48 @@ +RocketChat.settings.addGroup('OAuth', function() { + this.section('Tokenpass', function() { + const enableQuery = { + _id: 'Accounts_OAuth_Tokenpass', + value: true, + }; + + this.add('Accounts_OAuth_Tokenpass', false, { type: 'boolean' }); + this.add('API_Tokenpass_URL', '', { type: 'string', public: true, enableQuery, i18nDescription: 'API_Tokenpass_URL_Description' }); + this.add('Accounts_OAuth_Tokenpass_id', '', { type: 'string', enableQuery }); + this.add('Accounts_OAuth_Tokenpass_secret', '', { type: 'string', enableQuery }); + this.add('Accounts_OAuth_Tokenpass_callback_url', '_oauth/tokenpass', { type: 'relativeUrl', readonly: true, force: true, enableQuery }); + }); +}); + +function validateTokenAccess(userData, roomData) { + if (!userData || !userData.services || !userData.services.tokenpass || !userData.services.tokenpass.tcaBalances) { + return false; + } + + return RocketChat.Tokenpass.validateAccess(roomData.tokenpass, userData.services.tokenpass.tcaBalances); +} + +Meteor.startup(function() { + RocketChat.authz.addRoomAccessValidator(function(room, user) { + if (!room || !room.tokenpass || !user) { + return false; + } + + const userData = RocketChat.models.Users.getTokenBalancesByUserId(user._id); + + return validateTokenAccess(userData, room); + }); + + RocketChat.callbacks.add('beforeJoinRoom', function(user, room) { + if (room.tokenpass && !validateTokenAccess(user, room)) { + throw new Meteor.Error('error-not-allowed', 'Token required', { method: 'joinRoom' }); + } + + return room; + }); +}); + +Accounts.onLogin(function({ user }) { + if (user && user.services && user.services.tokenpass) { + RocketChat.updateUserTokenpassBalances(user); + } +}); diff --git a/packages/rocketchat-ui-sidenav/styles/side-nav.less b/packages/rocketchat-tooltip/README.md similarity index 100% rename from packages/rocketchat-ui-sidenav/styles/side-nav.less rename to packages/rocketchat-tooltip/README.md diff --git a/packages/rocketchat-tooltip/client/init.js b/packages/rocketchat-tooltip/client/init.js new file mode 100644 index 000000000000..96dd52e7835b --- /dev/null +++ b/packages/rocketchat-tooltip/client/init.js @@ -0,0 +1,3 @@ +Template.main.onCreated(function() { + RocketChat.tooltip.init(); +}); diff --git a/packages/rocketchat-tooltip/client/rocketchat-tooltip.html b/packages/rocketchat-tooltip/client/rocketchat-tooltip.html new file mode 100644 index 000000000000..5fea5460a40d --- /dev/null +++ b/packages/rocketchat-tooltip/client/rocketchat-tooltip.html @@ -0,0 +1,7 @@ + diff --git a/packages/rocketchat-tooltip/client/rocketchat-tooltip.js b/packages/rocketchat-tooltip/client/rocketchat-tooltip.js new file mode 100644 index 000000000000..eea7f3f6689b --- /dev/null +++ b/packages/rocketchat-tooltip/client/rocketchat-tooltip.js @@ -0,0 +1,86 @@ +/* globals Blaze, RocketChat */ +RocketChat.tooltip = { + source: null, + initiated: false, + opened: false, + + init() { + if (this.initiated) { + return; + } + this.initiated = true; + + Blaze.render(Template.rocketchatTooltip, document.body); + }, + + showElement(element, source) { + if (this.opened) { + return; + } + + if (this.timeout) { + clearTimeout(this.timeout); + } + + this.timeout = setTimeout(() => { + this.timeout = null; + this.source = source; + + $('.tooltip .content').empty().append($(element).clone().show()); + + this.setPosition().addClass('show'); + + this.opened = true; + }, 300); + + }, + + hide() { + if (this.timeout) { + clearTimeout(this.timeout); + } + + if (this.opened) { + $('.tooltip').removeClass('show'); + $('.tooltip .content').empty(); + this.opened = false; + } + }, + + setPosition() { + const sourcePos = $(this.source).offset(); + + const sourceWidth = $(this.source).outerWidth(); + + const tip = $('.tooltip'); + + let top = sourcePos.top - tip.outerHeight() - 5; + let { left } = sourcePos; + + left = left + (sourceWidth / 2) - (tip.outerWidth() / 2); + + if (left < 0) { + $('.tooltip .tooltip-arrow').css({ + 'margin-left': `${ left - 5 }px`, + }); + left = 0; + } else { + $('.tooltip .tooltip-arrow').css({ + 'margin-left': '', + }); + } + + if (top < 0) { + top = sourcePos.top + $(this.source).outerHeight() + 5; + tip.addClass('bellow'); + } else { + tip.removeClass('bellow'); + } + + return tip + .css({ + top: `${ top }px`, + left: `${ left }px`, + }); + }, +}; diff --git a/packages/rocketchat-tooltip/client/tooltip.css b/packages/rocketchat-tooltip/client/tooltip.css new file mode 100644 index 000000000000..44184897956a --- /dev/null +++ b/packages/rocketchat-tooltip/client/tooltip.css @@ -0,0 +1,48 @@ +.tooltip { + position: absolute; + z-index: 300; + + visibility: hidden; + + max-width: 400px; + padding: 8px 10px; + + transition: opacity 0.3s ease; + text-align: center; + + opacity: 0; + color: #ffffff; + border-radius: 5px; + background: #000000; + + font-size: 0.8rem; + + &.show { + visibility: visible; + + opacity: 0.9; + } + + & .tooltip-arrow { + position: absolute; + top: 100%; + left: 50%; + + width: 0; + height: 0; + margin-left: -5px; + + border-top: 5px solid #000000; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + } + + &.bellow { + & .tooltip-arrow { + top: -5px; + + border-top: none; + border-bottom: 5px solid #000000; + } + } +} diff --git a/packages/rocketchat-tooltip/package.js b/packages/rocketchat-tooltip/package.js new file mode 100644 index 000000000000..5e287bec2ba8 --- /dev/null +++ b/packages/rocketchat-tooltip/package.js @@ -0,0 +1,22 @@ +Package.describe({ + name: 'rocketchat:tooltip', + version: '0.0.1', + summary: '', + git: '', + documentation: 'README.md', +}); + +Package.onUse(function(api) { + api.use('ecmascript'); + api.use('templating', 'client'); + api.use('rocketchat:lib'); + api.use('rocketchat:theme'); + api.use('rocketchat:ui-master'); + + api.addFiles('client/tooltip.css', 'client'); + + api.addFiles('client/rocketchat-tooltip.html', 'client'); + api.addFiles('client/rocketchat-tooltip.js', 'client'); + + api.addFiles('client/init.js', 'client'); +}); diff --git a/packages/rocketchat-tutum/.npm/package/npm-shrinkwrap.json b/packages/rocketchat-tutum/.npm/package/npm-shrinkwrap.json deleted file mode 100644 index f1a4a466ed72..000000000000 --- a/packages/rocketchat-tutum/.npm/package/npm-shrinkwrap.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dependencies": { - "redis": { - "version": "2.2.5", - "dependencies": { - "double-ended-queue": { - "version": "2.1.0-0" - } - } - } - } -} diff --git a/packages/rocketchat-tutum/package.js b/packages/rocketchat-tutum/package.js index 34a218788a30..a47702f83a1f 100644 --- a/packages/rocketchat-tutum/package.js +++ b/packages/rocketchat-tutum/package.js @@ -1,20 +1,11 @@ Package.describe({ - name: 'rocketchat:tutum', - version: '0.0.1', - summary: 'RocketChat tutum integration' + name: 'rocketchat:tutum', + version: '0.0.1', + summary: 'RocketChat tutum integration', }); Package.onUse(function(api) { - api.versionsFrom('1.0'); - api.use('coffeescript'); - - api.addFiles('startup.coffee', 'server'); -}); - -Npm.depends({ - 'redis': '2.2.5' -}); - -Package.onTest(function(api) { - + api.use('ecmascript'); + api.use('rocketchat:lib'); + api.addFiles('startup.js', 'server'); }); diff --git a/packages/rocketchat-tutum/startup.coffee b/packages/rocketchat-tutum/startup.coffee deleted file mode 100644 index 6757de359fc9..000000000000 --- a/packages/rocketchat-tutum/startup.coffee +++ /dev/null @@ -1,15 +0,0 @@ -### Examples - -TUTUM_REDIS_HOST=redis://:password@host:6379 -TUTUM_CLIENT_NAME=mywebsite -TUTUM_CLIENT_HOST=mywebsite.dotcloud.com -### - -if process.env.TUTUM_REDIS_HOST? - redis = Npm.require 'redis' - - client = redis.createClient(process.env.TUTUM_REDIS_HOST) - - client.del("frontend:#{process.env.TUTUM_CLIENT_HOST}") - client.rpush("frontend:#{process.env.TUTUM_CLIENT_HOST}", process.env.TUTUM_CLIENT_NAME) - client.rpush("frontend:#{process.env.TUTUM_CLIENT_HOST}", "http://#{process.env.TUTUM_IP_ADDRESS.split('/')[0]}:3000") diff --git a/packages/rocketchat-tutum/startup.js b/packages/rocketchat-tutum/startup.js new file mode 100644 index 000000000000..a43cb5d63d61 --- /dev/null +++ b/packages/rocketchat-tutum/startup.js @@ -0,0 +1,25 @@ +/* Examples + +DOCKERCLOUD_REDIS_HOST=redis://:password@host:6379 +DOCKERCLOUD_CLIENT_NAME=mywebsite +DOCKERCLOUD_CLIENT_HOST=mywebsite.dotcloud.com +*/ + +if (process.env.DOCKERCLOUD_REDIS_HOST != null) { + const redis = require('redis'); + + const client = redis.createClient(process.env.DOCKERCLOUD_REDIS_HOST); + + client.on('error', (err) => console.log('Redis error ->', err)); + + client.del(`frontend:${ process.env.DOCKERCLOUD_CLIENT_HOST }`); + client.rpush(`frontend:${ process.env.DOCKERCLOUD_CLIENT_HOST }`, process.env.DOCKERCLOUD_CLIENT_NAME); + + const port = process.env.PORT || 3000; + client.rpush(`frontend:${ process.env.DOCKERCLOUD_CLIENT_HOST }`, `http://${ process.env.DOCKERCLOUD_IP_ADDRESS.split('/')[0] }:${ port }`); + + // removes the redis entry in 90 seconds on a SIGTERM + process.on('SIGTERM', () => client.expire(`frontend:${ process.env.DOCKERCLOUD_CLIENT_HOST }`, 90)); + + process.on('SIGINT', () => client.expire(`frontend:${ process.env.DOCKERCLOUD_CLIENT_HOST }`, 90)); +} diff --git a/packages/rocketchat-ui-account/account/account.coffee b/packages/rocketchat-ui-account/account/account.coffee deleted file mode 100644 index 55a3ba0d397c..000000000000 --- a/packages/rocketchat-ui-account/account/account.coffee +++ /dev/null @@ -1,11 +0,0 @@ -Template.account.helpers - flexOpened: -> - return 'opened' if RocketChat.TabBar.isFlexOpen() - arrowPosition: -> - console.log 'room.helpers arrowPosition' if window.rocketDebug - return 'left' unless RocketChat.TabBar.isFlexOpen() - -Template.account.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "accountFlex" - SideNav.openFlex() diff --git a/packages/rocketchat-ui-account/account/account.html b/packages/rocketchat-ui-account/account/account.html deleted file mode 100644 index ad14c8a22aa2..000000000000 --- a/packages/rocketchat-ui-account/account/account.html +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-account/account/accountFlex.coffee b/packages/rocketchat-ui-account/account/accountFlex.coffee deleted file mode 100644 index 1e04bc7ce919..000000000000 --- a/packages/rocketchat-ui-account/account/accountFlex.coffee +++ /dev/null @@ -1,21 +0,0 @@ -Template.accountFlex.events - 'mouseenter header': -> - SideNav.overArrow() - - 'mouseleave header': -> - SideNav.leaveArrow() - - 'click header': -> - SideNav.closeFlex() - - 'click .cancel-settings': -> - SideNav.closeFlex() - - 'click .account-link': -> - menu.close() - -Template.accountFlex.helpers - allowUserProfileChange: -> - return RocketChat.settings.get("Accounts_AllowUserProfileChange") - allowUserAvatarChange: -> - return RocketChat.settings.get("Accounts_AllowUserAvatarChange") \ No newline at end of file diff --git a/packages/rocketchat-ui-account/account/accountFlex.html b/packages/rocketchat-ui-account/account/accountFlex.html deleted file mode 100644 index 8a41d5b26e24..000000000000 --- a/packages/rocketchat-ui-account/account/accountFlex.html +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/packages/rocketchat-ui-account/account/accountPreferences.coffee b/packages/rocketchat-ui-account/account/accountPreferences.coffee deleted file mode 100644 index d8171ec2f97f..000000000000 --- a/packages/rocketchat-ui-account/account/accountPreferences.coffee +++ /dev/null @@ -1,67 +0,0 @@ -Template.accountPreferences.helpers - checked: (property, value, defaultValue) -> - if not Meteor.user()?.settings?.preferences?[property]? and defaultValue is true - currentValue = value - else if Meteor.user()?.settings?.preferences?[property]? - currentValue = !!Meteor.user()?.settings?.preferences?[property] - - return currentValue is value - - desktopNotificationEnabled: -> - return (KonchatNotification.notificationStatus.get() is 'granted') or (window.Notification && Notification.permission is "granted") - - desktopNotificationDisabled: -> - return (KonchatNotification.notificationStatus.get() is 'denied') or (window.Notification && Notification.permission is "denied") - -Template.accountPreferences.onCreated -> - settingsTemplate = this.parentTemplate(3) - settingsTemplate.child ?= [] - settingsTemplate.child.push this - - @useEmojis = new ReactiveVar not Meteor.user()?.settings?.preferences?.useEmojis? or Meteor.user().settings.preferences.useEmojis - instance = @ - @autorun -> - if instance.useEmojis.get() - Tracker.afterFlush -> - $('#convertAsciiEmoji').show() - else - Tracker.afterFlush -> - $('#convertAsciiEmoji').hide() - - @clearForm = -> - - @save = -> - instance = @ - data = {} - - data.disableNewRoomNotification = $('input[name=disableNewRoomNotification]:checked').val() - data.disableNewMessageNotification = $('input[name=disableNewMessageNotification]:checked').val() - data.useEmojis = $('input[name=useEmojis]:checked').val() - data.convertAsciiEmoji = $('input[name=convertAsciiEmoji]:checked').val() - data.saveMobileBandwidth = $('input[name=saveMobileBandwidth]:checked').val() - data.compactView = $('input[name=compactView]:checked').val() - data.unreadRoomsMode = $('input[name=unreadRoomsMode]:checked').val() - data.autoImageLoad = $('input[name=autoImageLoad]:checked').val() - - Meteor.call 'saveUserPreferences', data, (error, results) -> - if results - toastr.success t('Preferences_saved') - instance.clearForm() - - if error - toastr.error error.reason - -Template.accountPreferences.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "accountFlex" - SideNav.openFlex() - -Template.accountPreferences.events - 'click .submit button': (e, t) -> - t.save() - - 'change input[name=useEmojis]': (e, t) -> - t.useEmojis.set $(e.currentTarget).val() is '1' - - 'click .enable-notifications': -> - KonchatNotification.getDesktopPermission() diff --git a/packages/rocketchat-ui-account/account/accountPreferences.html b/packages/rocketchat-ui-account/account/accountPreferences.html deleted file mode 100644 index 331a1764cd28..000000000000 --- a/packages/rocketchat-ui-account/account/accountPreferences.html +++ /dev/null @@ -1,99 +0,0 @@ - diff --git a/packages/rocketchat-ui-account/account/accountProfile.coffee b/packages/rocketchat-ui-account/account/accountProfile.coffee deleted file mode 100644 index 78c1828d504c..000000000000 --- a/packages/rocketchat-ui-account/account/accountProfile.coffee +++ /dev/null @@ -1,108 +0,0 @@ -Template.accountProfile.helpers - languages: -> - languages = TAPi18n.getLanguages() - result = [] - for key, language of languages - result.push _.extend(language, { key: key }) - return _.sortBy(result, 'key') - - userLanguage: (key) -> - return (localStorage.getItem('userLanguage') or defaultUserLanguage())?.split('-').shift().toLowerCase() is key - - realname: -> - return Meteor.user().name - - username: -> - return Meteor.user().username - - allowUsernameChange: -> - return RocketChat.settings.get("Accounts_AllowUsernameChange") - - usernameChangeDisabled: -> - return t('Username_Change_Disabled') - - allowPasswordChange: -> - return RocketChat.settings.get("Accounts_AllowPasswordChange") - - passwordChangeDisabled: -> - return t('Password_Change_Disabled') - -Template.accountProfile.onCreated -> - settingsTemplate = this.parentTemplate(3) - settingsTemplate.child ?= [] - settingsTemplate.child.push this - - @clearForm = -> - @find('#language').value = localStorage.getItem('userLanguage') - @find('#oldPassword').value = '' - @find('#password').value = '' - @find('#username').value = '' - - @changePassword = (oldPassword, newPassword, callback) -> - instance = @ - if not oldPassword and not newPassword - return callback() - - else if !!oldPassword ^ !!newPassword - toastr.warning t('Old_and_new_password_required') - - else if newPassword and oldPassword - if !RocketChat.settings.get("Accounts_AllowPasswordChange") - toastr.error t('Password_Change_Disabled') - instance.clearForm() - return - Accounts.changePassword oldPassword, newPassword, (error) -> - if error - toastr.error t('Incorrect_Password') - else - return callback() - - @save = -> - instance = @ - - oldPassword = _.trim($('#oldPassword').val()) - newPassword = _.trim($('#password').val()) - - instance.changePassword oldPassword, newPassword, -> - data = {} - reload = false - selectedLanguage = $('#language').val() - - if localStorage.getItem('userLanguage') isnt selectedLanguage - localStorage.setItem 'userLanguage', selectedLanguage - data.language = selectedLanguage - reload = true - - if _.trim $('#realname').val() - data.realname = _.trim $('#realname').val() - - if _.trim $('#username').val() - if !RocketChat.settings.get("Accounts_AllowUsernameChange") - toastr.error t('Username_Change_Disabled') - instance.clearForm() - return - else - data.username = _.trim $('#username').val() - - Meteor.call 'saveUserProfile', data, (error, results) -> - if results - toastr.success t('Profile_saved_successfully') - instance.clearForm() - if reload - setTimeout -> - Meteor._reload.reload() - , 1000 - - if error - toastr.error error.reason - -Template.accountProfile.onRendered -> - Tracker.afterFlush -> - # this should throw an error-template - FlowRouter.go("home") if !RocketChat.settings.get("Accounts_AllowUserProfileChange") - SideNav.setFlex "accountFlex" - SideNav.openFlex() - -Template.accountProfile.events - 'click .submit button': (e, t) -> - t.save() diff --git a/packages/rocketchat-ui-account/account/accountProfile.html b/packages/rocketchat-ui-account/account/accountProfile.html deleted file mode 100644 index 8a6dbfab5d4c..000000000000 --- a/packages/rocketchat-ui-account/account/accountProfile.html +++ /dev/null @@ -1,65 +0,0 @@ - diff --git a/packages/rocketchat-ui-account/account/avatar/avatar.coffee b/packages/rocketchat-ui-account/account/avatar/avatar.coffee deleted file mode 100644 index b0abe8754a17..000000000000 --- a/packages/rocketchat-ui-account/account/avatar/avatar.coffee +++ /dev/null @@ -1,14 +0,0 @@ -Template.avatar.helpers - imageUrl: -> - username = this.username - if not username? and this.userId? - username = Meteor.users.findOne(this.userId)?.username - - if not username? - return - - Session.get "avatar_random_#{username}" - - url = getAvatarUrlFromUsername(username) - - return "background-image:url(#{url});" diff --git a/packages/rocketchat-ui-account/account/avatar/avatar.html b/packages/rocketchat-ui-account/account/avatar/avatar.html deleted file mode 100644 index 047653ecdc55..000000000000 --- a/packages/rocketchat-ui-account/account/avatar/avatar.html +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-account/account/avatar/prompt.coffee b/packages/rocketchat-ui-account/account/avatar/prompt.coffee deleted file mode 100644 index e1982da5a20c..000000000000 --- a/packages/rocketchat-ui-account/account/avatar/prompt.coffee +++ /dev/null @@ -1,100 +0,0 @@ -Template.avatarPrompt.onCreated -> - self = this - self.suggestions = new ReactiveVar - self.upload = new ReactiveVar - - self.getSuggestions = -> - self.suggestions.set undefined - Meteor.call 'getAvatarSuggestion', (error, avatars) -> - self.suggestions.set - ready: true - avatars: avatars - - self.getSuggestions() - -Template.avatarPrompt.onRendered -> - Tracker.afterFlush -> - # this should throw an error-template - FlowRouter.go("home") if !RocketChat.settings.get("Accounts_AllowUserAvatarChange") - SideNav.setFlex "accountFlex" - SideNav.openFlex() - -Template.avatarPrompt.helpers - suggestions: -> - return Template.instance().suggestions.get() - - suggestAvatar: (service) -> - suggestions = Template.instance().suggestions.get() - console.log service, "Accounts_OAuth_#{_.capitalize service}", RocketChat.settings.get("Accounts_OAuth_#{_.capitalize service}"), suggestions - return RocketChat.settings.get("Accounts_OAuth_#{_.capitalize service}") and not suggestions.avatars[service] - - upload: -> - return Template.instance().upload.get() - - username: -> - return Meteor.user()?.username - - initialsUsername: -> - return '@'+Meteor.user()?.username - -Template.avatarPrompt.events - 'click .select-service': -> - if @service is 'initials' - Meteor.call 'resetAvatar', (err) -> - if err?.details?.timeToReset? - toastr.error t('Error_too_many_requests', parseInt(err.details.timeToReset / 1000)) - else - toastr.success t('Avatar_changed_successfully') - else if @service is 'url' - if _.trim $('#avatarurl').val() - Meteor.call 'setAvatarFromService', $('#avatarurl').val(), '', @service, (err) -> - if err - if err.details?.timeToReset? - toastr.error t('Error_too_many_requests', parseInt(err.details.timeToReset / 1000)) - else - toastr.error t('Avatar_url_invalid_or_error') - else - toastr.success t('Avatar_changed_successfully') - else - toastr.error t('Please_enter_value_for_url') - else - Meteor.call 'setAvatarFromService', @blob, @contentType, @service, (err) -> - if err?.details?.timeToReset? - toastr.error t('Error_too_many_requests', parseInt(err.details.timeToReset / 1000)) - else - toastr.success t('Avatar_changed_successfully') - - 'click .login-with-service': (event, template) -> - loginWithService = "loginWith#{_.capitalize(this)}" - - serviceConfig = {} - - Meteor[loginWithService] serviceConfig, (error) -> - if error?.error is 'github-no-public-email' - alert t("github_no_public_email") - return - - console.log error - if error? - toastr.error error.message - return - - template.getSuggestions() - - 'change .avatar-file-input': (event, template) -> - e = event.originalEvent or event - files = e.target.files - if not files or files.length is 0 - files = e.dataTransfer?.files or [] - - for blob in files - if not /image\/.+/.test blob.type - return - - reader = new FileReader() - reader.readAsDataURL(blob) - reader.onloadend = -> - template.upload.set - service: 'upload' - contentType: blob.type - blob: reader.result diff --git a/packages/rocketchat-ui-account/account/avatar/prompt.html b/packages/rocketchat-ui-account/account/avatar/prompt.html deleted file mode 100644 index 86ccb8b6d8c1..000000000000 --- a/packages/rocketchat-ui-account/account/avatar/prompt.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - diff --git a/packages/rocketchat-ui-account/client/account.html b/packages/rocketchat-ui-account/client/account.html new file mode 100644 index 000000000000..537dbcdf8dc2 --- /dev/null +++ b/packages/rocketchat-ui-account/client/account.html @@ -0,0 +1,10 @@ + diff --git a/packages/rocketchat-ui-account/client/account.js b/packages/rocketchat-ui-account/client/account.js new file mode 100644 index 000000000000..214d55abe8c6 --- /dev/null +++ b/packages/rocketchat-ui-account/client/account.js @@ -0,0 +1,6 @@ +Template.account.onRendered(function() { + Tracker.afterFlush(function() { + SideNav.setFlex('accountFlex'); + SideNav.openFlex(); + }); +}); diff --git a/packages/rocketchat-ui-account/client/accountFlex.html b/packages/rocketchat-ui-account/client/accountFlex.html new file mode 100644 index 000000000000..68a5d6209fa0 --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountFlex.html @@ -0,0 +1,27 @@ + diff --git a/packages/rocketchat-ui-account/client/accountFlex.js b/packages/rocketchat-ui-account/client/accountFlex.js new file mode 100644 index 000000000000..d7a9059e6cb2 --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountFlex.js @@ -0,0 +1,30 @@ +Template.accountFlex.events({ + 'click [data-action="close"]'() { + SideNav.closeFlex(); + }, +}); + +// Template.accountFlex.onRendered(function() { +// $(this.find('.rooms-list')).perfectScrollbar(); +// }); + +Template.accountFlex.helpers({ + allowUserProfileChange() { + return RocketChat.settings.get('Accounts_AllowUserProfileChange'); + }, + accessTokensEnabled() { + return RocketChat.settings.get('API_Enable_Personal_Access_Tokens'); + }, + menuItem(name, icon, section, group) { + return { + name: t(name), + icon, + pathSection: section, + pathGroup: group, + darken: true, + }; + }, + embeddedVersion() { + return RocketChat.Layout.isEmbedded(); + }, +}); diff --git a/packages/rocketchat-ui-account/client/accountPreferences.html b/packages/rocketchat-ui-account/client/accountPreferences.html new file mode 100644 index 000000000000..22c4df61e54b --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountPreferences.html @@ -0,0 +1,327 @@ + diff --git a/packages/rocketchat-ui-account/client/accountPreferences.js b/packages/rocketchat-ui-account/client/accountPreferences.js new file mode 100644 index 000000000000..cf7a8cdddb80 --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountPreferences.js @@ -0,0 +1,325 @@ +/* globals KonchatNotification */ +import _ from 'underscore'; +import s from 'underscore.string'; +import toastr from 'toastr'; + +const notificationLabels = { + all: 'All_messages', + mentions: 'Mentions', + nothing: 'Nothing', +}; + +const emailLabels = { + nothing: 'Email_Notification_Mode_Disabled', + mentions: 'Email_Notification_Mode_All', +}; + +function checkedSelected(property, value, defaultValue = undefined) { + if (defaultValue && defaultValue.hash) { + defaultValue = undefined; + } + return RocketChat.getUserPreference(Meteor.user(), property, defaultValue) === value; +} + +Template.accountPreferences.helpers({ + audioAssets() { + return (RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList()) || []; + }, + newMessageNotification() { + return RocketChat.getUserPreference(Meteor.user(), 'newMessageNotification'); + }, + newRoomNotification() { + return RocketChat.getUserPreference(Meteor.user(), 'newRoomNotification'); + }, + muteFocusedConversations() { + return RocketChat.getUserPreference(Meteor.user(), 'muteFocusedConversations'); + }, + languages() { + const languages = TAPi18n.getLanguages(); + + const result = Object.entries(languages) + .map(([key, language]) => ({ ...language, key: key.toLowerCase() })) + .sort((a, b) => a.key - b.key); + + result.unshift({ + name: 'Default', + en: 'Default', + key: '', + }); + + return result; + }, + isUserLanguage(key) { + const languageKey = Meteor.user().language; + return typeof languageKey === 'string' && languageKey.toLowerCase() === key; + }, + checked(property, value, defaultValue = undefined) { + return checkedSelected(property, value, defaultValue); + }, + selected(property, value, defaultValue = undefined) { + return checkedSelected(property, value, defaultValue); + }, + highlights() { + const userHighlights = RocketChat.getUserPreference(Meteor.user(), 'highlights'); + return userHighlights ? userHighlights.join(',\n') : undefined; + }, + desktopNotificationEnabled() { + return KonchatNotification.notificationStatus.get() === 'granted' || (window.Notification && Notification.permission === 'granted'); + }, + desktopNotificationDisabled() { + return KonchatNotification.notificationStatus.get() === 'denied' || (window.Notification && Notification.permission === 'denied'); + }, + desktopNotificationDuration() { + const userPref = RocketChat.getUserPreference(Meteor.user(), 'desktopNotificationDuration', 'undefined'); + return userPref !== 'undefined' ? userPref : undefined; + }, + defaultDesktopNotificationDuration() { + return RocketChat.settings.get('Accounts_Default_User_Preferences_desktopNotificationDuration'); + }, + idleTimeLimit() { + return RocketChat.getUserPreference(Meteor.user(), 'idleTimeLimit'); + }, + defaultIdleTimeLimit() { + return RocketChat.settings.get('Accounts_Default_User_Preferences_idleTimeLimit'); + }, + defaultDesktopNotification() { + return notificationLabels[RocketChat.settings.get('Accounts_Default_User_Preferences_desktopNotifications')]; + }, + defaultMobileNotification() { + return notificationLabels[RocketChat.settings.get('Accounts_Default_User_Preferences_mobileNotifications')]; + }, + defaultEmailNotification() { + return emailLabels[RocketChat.settings.get('Accounts_Default_User_Preferences_emailNotificationMode')]; + }, + showRoles() { + return RocketChat.settings.get('UI_DisplayRoles'); + }, + userDataDownloadEnabled() { + return RocketChat.settings.get('UserData_EnableDownload') !== false; + }, + notificationsSoundVolume() { + return RocketChat.getUserPreference(Meteor.user(), 'notificationsSoundVolume'); + }, + dontAskAgainList() { + return RocketChat.getUserPreference(Meteor.user(), 'dontAskAgainList'); + }, +}); + +Template.accountPreferences.onCreated(function() { + const user = Meteor.user(); + const settingsTemplate = this.parentTemplate(3); + + if (settingsTemplate.child == null) { + settingsTemplate.child = []; + } + + settingsTemplate.child.push(this); + + this.useEmojis = new ReactiveVar(RocketChat.getUserPreference(user, 'useEmojis')); + + let instance = this; + + this.autorun(() => { + if (instance.useEmojis && instance.useEmojis.get()) { + Tracker.afterFlush(() => $('#convertAsciiEmoji').show()); + } else { + Tracker.afterFlush(() => $('#convertAsciiEmoji').hide()); + } + }); + + this.clearForm = function() { + this.find('#language').value = localStorage.getItem('userLanguage'); + }; + + this.shouldUpdateLocalStorageSetting = function(setting, newValue) { + return localStorage.getItem(setting) !== newValue; + }; + + this.save = function() { + instance = this; + const data = {}; + + data.newRoomNotification = $('select[name=newRoomNotification]').val(); + data.newMessageNotification = $('select[name=newMessageNotification]').val(); + data.useEmojis = JSON.parse($('input[name=useEmojis]:checked').val()); + data.convertAsciiEmoji = JSON.parse($('input[name=convertAsciiEmoji]:checked').val()); + data.saveMobileBandwidth = JSON.parse($('input[name=saveMobileBandwidth]:checked').val()); + data.collapseMediaByDefault = JSON.parse($('input[name=collapseMediaByDefault]:checked').val()); + data.muteFocusedConversations = JSON.parse($('#muteFocusedConversations').find('input:checked').val()); + data.hideUsernames = JSON.parse($('#hideUsernames').find('input:checked').val()); + data.messageViewMode = parseInt($('#messageViewMode').find('select').val()); + data.hideFlexTab = JSON.parse($('#hideFlexTab').find('input:checked').val()); + data.hideAvatars = JSON.parse($('#hideAvatars').find('input:checked').val()); + data.sendOnEnter = $('#sendOnEnter').find('select').val(); + data.autoImageLoad = JSON.parse($('input[name=autoImageLoad]:checked').val()); + data.emailNotificationMode = $('select[name=emailNotificationMode]').val(); + data.desktopNotificationDuration = $('input[name=desktopNotificationDuration]').val() === '' ? RocketChat.settings.get('Accounts_Default_User_Preferences_desktopNotificationDuration') : parseInt($('input[name=desktopNotificationDuration]').val()); + data.desktopNotifications = $('#desktopNotifications').find('select').val(); + data.mobileNotifications = $('#mobileNotifications').find('select').val(); + data.unreadAlert = JSON.parse($('#unreadAlert').find('input:checked').val()); + data.notificationsSoundVolume = parseInt($('#notificationsSoundVolume').val()); + data.roomCounterSidebar = JSON.parse($('#roomCounterSidebar').find('input:checked').val()); + data.highlights = _.compact(_.map($('[name=highlights]').val().split(/,|\n/), function(e) { + return s.trim(e); + })); + data.dontAskAgainList = Array.from(document.getElementById('dont-ask').options).map((option) => ({ action: option.value, label: option.text })); + + let reload = false; + + if (RocketChat.settings.get('UI_DisplayRoles')) { + data.hideRoles = JSON.parse($('#hideRoles').find('input:checked').val()); + } + + // if highlights changed we need page reload + const highlights = RocketChat.getUserPreference(Meteor.user(), 'highlights'); + if (highlights && highlights.join('\n') !== data.highlights.join('\n')) { + reload = true; + } + + const selectedLanguage = $('#language').val(); + if (this.shouldUpdateLocalStorageSetting('userLanguage', selectedLanguage)) { + localStorage.setItem('userLanguage', selectedLanguage); + data.language = selectedLanguage; + reload = true; + } + + const enableAutoAway = JSON.parse($('#enableAutoAway').find('input:checked').val()); + data.enableAutoAway = enableAutoAway; + if (this.shouldUpdateLocalStorageSetting('enableAutoAway', enableAutoAway)) { + localStorage.setItem('enableAutoAway', enableAutoAway); + reload = true; + } + + const idleTimeLimit = $('input[name=idleTimeLimit]').val() === '' ? RocketChat.settings.get('Accounts_Default_User_Preferences_idleTimeLimit') : parseInt($('input[name=idleTimeLimit]').val()); + data.idleTimeLimit = idleTimeLimit; + if (this.shouldUpdateLocalStorageSetting('idleTimeLimit', idleTimeLimit)) { + localStorage.setItem('idleTimeLimit', idleTimeLimit); + reload = true; + } + + Meteor.call('saveUserPreferences', data, function(error, results) { + if (results) { + toastr.success(t('Preferences_saved')); + instance.clearForm(); + if (reload) { + setTimeout(function() { + if (Meteor._reload && Meteor._reload.reload) { // make it compatible with old meteor + Meteor._reload.reload(); + } else { + Reload._reload(); + } + }, 1000); + } + } + if (error) { + return handleError(error); + } + }); + }; + + this.downloadMyData = function(fullExport = false) { + Meteor.call('requestDataDownload', { fullExport }, function(error, results) { + if (results) { + if (results.requested) { + modal.open({ + title: t('UserDataDownload_Requested'), + text: t('UserDataDownload_Requested_Text'), + type: 'success', + }); + + return true; + } + + if (results.exportOperation) { + if (results.exportOperation.status === 'completed') { + modal.open({ + title: t('UserDataDownload_Requested'), + text: t('UserDataDownload_CompletedRequestExisted_Text'), + type: 'success', + }); + + return true; + } + + modal.open({ + title: t('UserDataDownload_Requested'), + text: t('UserDataDownload_RequestExisted_Text'), + type: 'success', + }); + return true; + } + + modal.open({ + title: t('UserDataDownload_Requested'), + type: 'success', + }); + return true; + } + + if (error) { + return handleError(error); + } + }); + }; + + this.exportMyData = function() { + this.downloadMyData(true); + }; +}); + +Template.accountPreferences.onRendered(function() { + Tracker.afterFlush(function() { + SideNav.setFlex('accountFlex'); + SideNav.openFlex(); + }); +}); + +Template.accountPreferences.events({ + 'click .rc-header__section-button .save'(e, t) { + t.save(); + }, + 'change input[name=useEmojis]'(e, t) { + t.useEmojis.set($(e.currentTarget).val() === '1'); + }, + 'click .enable-notifications'() { + KonchatNotification.getDesktopPermission(); + }, + 'click .download-my-data'(e, t) { + e.preventDefault(); + t.downloadMyData(); + }, + 'click .export-my-data'(e, t) { + e.preventDefault(); + t.exportMyData(); + }, + 'click .test-notifications'(e) { + e.preventDefault(); + KonchatNotification.notify({ + duration: $('input[name=desktopNotificationDuration]').val(), + payload: { sender: { username: 'rocket.cat' }, + }, + title: TAPi18n.__('Desktop_Notification_Test'), + text: TAPi18n.__('This_is_a_desktop_notification'), + }); + }, + 'change .audio'(e) { + e.preventDefault(); + const audio = $(e.currentTarget).val(); + if (audio === 'none') { + return; + } + if (audio) { + const $audio = $(`audio#${ audio }`); + return $audio && $audio[0] && $audio[0].play(); + } + }, + 'click .js-dont-ask-remove'(e) { + e.preventDefault(); + const selectEl = document.getElementById('dont-ask'); + const { options } = selectEl; + const selectedOption = selectEl.value; + const optionIndex = Array.from(options).findIndex((option) => option.value === selectedOption); + + selectEl.remove(optionIndex); + }, +}); diff --git a/packages/rocketchat-ui-account/client/accountProfile.html b/packages/rocketchat-ui-account/client/accountProfile.html new file mode 100644 index 000000000000..a60e73e9df44 --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountProfile.html @@ -0,0 +1,185 @@ + + diff --git a/packages/rocketchat-ui-account/client/accountProfile.js b/packages/rocketchat-ui-account/client/accountProfile.js new file mode 100644 index 000000000000..cc8b489373d4 --- /dev/null +++ b/packages/rocketchat-ui-account/client/accountProfile.js @@ -0,0 +1,524 @@ +import _ from 'underscore'; +import s from 'underscore.string'; +import toastr from 'toastr'; + +const validateEmail = (email) => /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email); +const validateUsername = (username) => { + const reg = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + return reg.test(username); +}; +const validateName = (name) => name.length; +const validatePassword = (password, confirmationPassword) => { + if (!confirmationPassword) { + return true; + } + + return password === confirmationPassword; +}; + +const filterNames = (old) => { + const reg = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + return [...old.replace(' ', '')].filter((f) => reg.test(f)).join(''); +}; +const filterEmail = (old) => old.replace(' ', ''); + +const setAvatar = function(event, template) { + const { blob, contentType, service } = this.suggestion; + + template.avatar.set({ + service, + contentType, + blob, + }); +}; +const loginWith = function(event, template) { + const loginWithService = `loginWith${ s.capitalize(this.name) }`; + const serviceConfig = {}; + Meteor[loginWithService](serviceConfig, function(error) { + if (error && error.error) { + if (error.error === 'github-no-public-email') { + return alert(t('github_no_public_email')); + } + return toastr.error(error.message); + } + template.getSuggestions(); + }); +}; +const isUserEmailVerified = (user) => user.emails && user.emails[0] && user.emails[0].verified; +const getUserEmailAddress = (user) => user.emails && user.emails[0] && user.emails[0].address; + +Template.accountProfile.helpers({ + emailInvalid() { + return !validateEmail(Template.instance().email.get()); + }, + usernameInvalid() { + return !validateUsername(Template.instance().username.get()); + }, + usernameAvaliable() { + return Template.instance().usernameAvaliable.get() !== false; + }, + nameInvalid() { + return !validateName(Template.instance().realname.get()); + }, + confirmationPasswordInvalid() { + const { password, confirmationPassword } = Template.instance(); + return !validatePassword(password.get(), confirmationPassword.get()); + }, + selectUrl() { + return Template.instance().url.get().trim() ? '' : 'disabled'; + }, + services() { + const suggestions = Template.instance().suggestions.get(); + return ['gravatar', 'facebook', 'google', 'github', 'gitlab', 'linkedIn', 'twitter'] + .map((service) => ({ + name: service, + // TODO: improve this fix + service: !suggestions.avatars[service.toLowerCase()] ? RocketChat.settings.get(`Accounts_OAuth_${ s.capitalize(service.toLowerCase()) }`) : false, + suggestion: suggestions.avatars[service.toLowerCase()], + })) + .filter(({ service, suggestion }) => service || suggestion); + }, + initialsUsername() { + const user = Meteor.user(); + return `@${ user && user.username }`; + }, + avatarPreview() { + return Template.instance().avatar.get(); + }, + suggestions() { + return Template.instance().suggestions.get(); + }, + ifThenElse(condition, val, not = '') { + return condition ? val : not; + }, + canSave(ret) { + const instance = Template.instance(); + instance.dep.depend(); + const realname = instance.realname.get(); + const username = instance.username.get(); + const password = instance.password.get(); + const confirmationPassword = instance.confirmationPassword.get(); + const email = instance.email.get(); + const usernameAvaliable = instance.usernameAvaliable.get(); + const avatar = instance.avatar.get(); + const user = Meteor.user(); + const { customFields = {} } = user; + if (instance.view.isRendered) { + if (instance.findAll('[data-customfield="true"]').some((el) => { + const key = el.getAttribute('name'); + const value = customFields[key] || ''; + return el.value !== value; + })) { + return; + } + } + if (!avatar && user.name === realname && user.username === username && getUserEmailAddress(user) === email === email && (!password || password !== confirmationPassword)) { + return ret; + } + if (!validateEmail(email) || (!validateUsername(username) || usernameAvaliable !== true) || !validateName(realname)) { + return ret; + } + + return; + }, + allowDeleteOwnAccount() { + return RocketChat.settings.get('Accounts_AllowDeleteOwnAccount'); + }, + realname() { + return Meteor.user().name; + }, + username() { + return Meteor.user().username; + }, + email() { + const user = Meteor.user(); + return getUserEmailAddress(user); + }, + emailVerified() { + const user = Meteor.user(); + return isUserEmailVerified(user); + }, + allowRealNameChange() { + return RocketChat.settings.get('Accounts_AllowRealNameChange'); + }, + allowUsernameChange() { + return RocketChat.settings.get('Accounts_AllowUsernameChange') && RocketChat.settings.get('LDAP_Enable') !== true; + }, + allowEmailChange() { + return RocketChat.settings.get('Accounts_AllowEmailChange'); + }, + allowPasswordChange() { + return RocketChat.settings.get('Accounts_AllowPasswordChange'); + }, + canConfirmNewPassword() { + const password = Template.instance().password.get(); + return RocketChat.settings.get('Accounts_AllowPasswordChange') && password && password !== ''; + }, + allowAvatarChange() { + return RocketChat.settings.get('Accounts_AllowUserAvatarChange'); + }, + customFields() { + return Meteor.user().customFields; + }, +}); + +Template.accountProfile.onCreated(function() { + const self = this; + const user = Meteor.user(); + self.dep = new Tracker.Dependency; + self.realname = new ReactiveVar(user.name); + self.email = new ReactiveVar(getUserEmailAddress(user)); + self.username = new ReactiveVar(user.username); + self.password = new ReactiveVar; + self.confirmationPassword = new ReactiveVar; + self.suggestions = new ReactiveVar; + self.avatar = new ReactiveVar; + self.url = new ReactiveVar(''); + self.usernameAvaliable = new ReactiveVar(true); + + RocketChat.Notifications.onLogged('updateAvatar', () => self.avatar.set()); + self.getSuggestions = function() { + self.suggestions.set(undefined); + Meteor.call('getAvatarSuggestion', function(error, avatars) { + self.suggestions.set({ ready: true, avatars }); + }); + }; + self.getSuggestions(); + const settingsTemplate = this.parentTemplate(3); + if (settingsTemplate.child == null) { + settingsTemplate.child = []; + } + settingsTemplate.child.push(this); + this.clearForm = function() { + this.find('[name=password]').value = ''; + }; + this.changePassword = function(newPassword, callback) { + const instance = this; + if (!newPassword) { + return callback(); + } else if (!RocketChat.settings.get('Accounts_AllowPasswordChange')) { + toastr.remove(); + toastr.error(t('Password_Change_Disabled')); + instance.clearForm(); + return; + } + }; + this.save = function(typedPassword, cb) { + const avatar = self.avatar.get(); + if (avatar) { + const params = [avatar.blob]; + + params.push(avatar.contentType); + + params.push(avatar.service); + Meteor.call('setAvatarFromService', ...params, function(err) { + if (err && err.details && err.details.timeToReset) { + toastr.error(t('error-too-many-requests', { + seconds: parseInt(err.details.timeToReset / 1000), + })); + } else { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', avatar.service); + } + }); + } + const instance = this; + const data = {}; + const user = Meteor.user(); + if (typedPassword) { + data.typedPassword = typedPassword; + } + if (s.trim(self.password.get()) && RocketChat.settings.get('Accounts_AllowPasswordChange')) { + data.newPassword = self.password.get(); + } + if (s.trim(self.realname.get()) !== user.name) { + if (!RocketChat.settings.get('Accounts_AllowRealNameChange')) { + toastr.remove(); + toastr.error(t('RealName_Change_Disabled')); + instance.clearForm(); + return cb && cb(); + } else { + data.realname = s.trim(self.realname.get()); + } + } + if (s.trim(self.username.get()) !== user.username) { + if (!RocketChat.settings.get('Accounts_AllowUsernameChange')) { + toastr.remove(); + toastr.error(t('Username_Change_Disabled')); + instance.clearForm(); + return cb && cb(); + } else { + data.username = s.trim(self.username.get()); + } + } + if (s.trim(self.email.get()) !== getUserEmailAddress(user)) { + if (!RocketChat.settings.get('Accounts_AllowEmailChange')) { + toastr.remove(); + toastr.error(t('Email_Change_Disabled')); + instance.clearForm(); + return cb && cb(); + } else { + data.email = s.trim(self.email.get()); + } + } + const customFields = {}; + $('[data-customfield=true]').each(function() { + customFields[this.name] = $(this).val() || ''; + }); + + if (Object.keys(data).length + Object.keys(customFields).length === 0) { + return cb && cb(); + } + Meteor.call('saveUserProfile', data, customFields, function(error, results) { + cb && cb(); + if (results) { + toastr.remove(); + toastr.success(t('Profile_saved_successfully')); + modal.close(); + instance.clearForm(); + self.password.set(); + } + if (error) { + toastr.remove(); + handleError(error); + } + }); + }; +}); + +Template.accountProfile.onRendered(function() { + Tracker.afterFlush(() => { + if (!RocketChat.settings.get('Accounts_AllowUserProfileChange')) { + FlowRouter.go('home'); + } + this.clearForm(); + SideNav.setFlex('accountFlex'); + SideNav.openFlex(); + }); +}); + +const checkAvailability = _.debounce((username, { usernameAvaliable }) => { + Meteor.call('checkUsernameAvailability', username, function(error, data) { + usernameAvaliable.set(data); + }); +}, 300); + +Template.accountProfile.events({ + 'change [data-customfield="true"], input [data-customfield="true"]':_.debounce((e, i) => { + i.dep.changed(); + }, 300), + 'click .js-select-avatar-initials'() { + Meteor.call('resetAvatar', function(err) { + if (err && err.details && err.details.timeToReset) { + toastr.error(t('error-too-many-requests', { + seconds: parseInt(err.details.timeToReset / 1000), + })); + } else { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', 'initials'); + } + }); + }, + 'click .js-select-avatar-url'(e, instance, ...args) { + const url = instance.url.get().trim(); + if (!url) { + return; + } + setAvatar.apply({ + suggestion: { + service: 'url', + blob: url, + contentType: '', + }, + }, [e, instance, ...args]); + }, + 'input .js-avatar-url-input'(e, instance) { + const text = e.target.value; + instance.url.set(text); + }, + 'click .js-select-avatar'(...args) { + this.suggestion ? setAvatar.apply(this, args) : loginWith.apply(this, args); + }, + 'input [name=email]'(e, instance) { + const input = e.target; + const position = input.selectionEnd || input.selectionStart; + const { length } = input.value; + const modified = filterEmail(input.value); + input.value = modified; + document.activeElement === input && e && /input/i.test(e.type) && (input.selectionEnd = position + input.value.length - length); + instance.email.set(modified); + }, + 'input [name=username]'(e, instance) { + const input = e.target; + const position = input.selectionEnd || input.selectionStart; + const { length } = input.value; + const modified = filterNames(input.value); + input.value = modified; + document.activeElement === input && e && /input/i.test(e.type) && (input.selectionEnd = position + input.value.length - length); + instance.username.set(modified); + instance.usernameAvaliable.set(); + checkAvailability(modified, instance); + }, + 'input [name=realname]'(e, instance) { + instance.realname.set(e.target.value); + }, + 'input [name=password]'(e, instance) { + instance.password.set(e.target.value); + + if (e.target.value.length === 0) { + instance.confirmationPassword.set(''); + } + }, + 'input [name=confirmation-password]'(e, instance) { + instance.confirmationPassword.set(e.target.value); + }, + 'submit form'(e, instance) { + e.preventDefault(); + const user = Meteor.user(); + const email = instance.email.get(); + const password = instance.password.get(); + + const send = $(e.target.send); + send.addClass('loading'); + const reqPass = ((email !== getUserEmailAddress(user)) + || s.trim(password)) && (user && user.services && user.services.password && s.trim(user.services.password.bcrypt)); + if (!reqPass) { + return instance.save(undefined, () => setTimeout(() => send.removeClass('loading'), 1000)); + } + modal.open({ + title: t('Please_enter_your_password'), + text: t('For_your_security_you_must_enter_your_current_password_to_continue'), + type: 'input', + inputType: 'password', + showCancelButton: true, + closeOnConfirm: false, + confirmButtonText: t('Save'), + cancelButtonText: t('Cancel'), + }, (typedPassword) => { + if (typedPassword) { + toastr.remove(); + toastr.warning(t('Please_wait_while_your_profile_is_being_saved')); + instance.save(SHA256(typedPassword), () => send.removeClass('loading')); + } else { + modal.showInputError(t('You_need_to_type_in_your_password_in_order_to_do_this')); + return false; + } + }); + }, + 'click .js-logout'(e) { + e.preventDefault(); + $(e.target).addClass('loading'); + Meteor.logoutOtherClients(function(error) { + setTimeout(function functionName() { + if (error) { + toastr.remove(); + handleError(error); + } else { + toastr.remove(); + toastr.success(t('Logged_out_of_other_clients_successfully')); + } + + $(e.target).removeClass('loading'); + + }, 1000); + }); + }, + 'click .js-delete-account'(e) { + e.preventDefault(); + const user = Meteor.user(); + if (s.trim(user && user.services && user.services.password && user.services.password.bcrypt)) { + modal.open({ + title: t('Are_you_sure_you_want_to_delete_your_account'), + text: t('If_you_are_sure_type_in_your_password'), + type: 'input', + inputType: 'password', + showCancelButton: true, + closeOnConfirm: false, + confirmButtonText: t('Delete'), + cancelButtonText: t('Cancel'), + }, (typedPassword) => { + if (typedPassword) { + toastr.remove(); + toastr.warning(t('Please_wait_while_your_account_is_being_deleted')); + Meteor.call('deleteUserOwnAccount', SHA256(typedPassword), function(error) { + if (error) { + toastr.remove(); + modal.showInputError(t('Your_password_is_wrong')); + } else { + modal.close(); + } + }); + } else { + modal.showInputError(t('You_need_to_type_in_your_password_in_order_to_do_this')); + return false; + } + }); + } else { + modal.open({ + title: t('Are_you_sure_you_want_to_delete_your_account'), + text: t('If_you_are_sure_type_in_your_username'), + type: 'input', + showCancelButton: true, + closeOnConfirm: false, + confirmButtonText: t('Delete'), + cancelButtonText: t('Cancel'), + }, (deleteConfirmation) => { + const user = Meteor.user(); + if (deleteConfirmation === (user && user.username)) { + toastr.remove(); + toastr.warning(t('Please_wait_while_your_account_is_being_deleted')); + Meteor.call('deleteUserOwnAccount', deleteConfirmation, function(error) { + if (error) { + toastr.remove(); + modal.showInputError(t('Your_password_is_wrong')); + } else { + modal.close(); + } + }); + } else { + modal.showInputError(t('You_need_to_type_in_your_username_in_order_to_do_this')); + return false; + } + }); + } + }, + 'click #resend-verification-email'(e) { + const user = Meteor.user(); + e.preventDefault(); + e.currentTarget.innerHTML = `${ e.currentTarget.innerHTML } ...`; + e.currentTarget.disabled = true; + Meteor.call('sendConfirmationEmail', getUserEmailAddress(user), (error, results) => { + if (results) { + toastr.success(t('Verification_email_sent')); + } else if (error) { + handleError(error); + } + e.currentTarget.innerHTML = e.currentTarget.innerHTML.replace(' ...', ''); + return e.currentTarget.disabled = false; + }); + }, + 'change .js-select-avatar-upload [type=file]'(event, template) { + const e = event.originalEvent || event; + let { files } = e.target; + if (!files || files.length === 0) { + files = (e.dataTransfer && e.dataTransfer.files) || []; + } + Object.keys(files).forEach((key) => { + const blob = files[key]; + if (!/image\/.+/.test(blob.type)) { + return; + } + const reader = new FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = function() { + template.avatar.set({ + service: 'upload', + contentType: blob.type, + blob: reader.result, + }); + RocketChat.callbacks.run('userAvatarSet', 'upload'); + }; + }); + }, + +}); diff --git a/packages/rocketchat-ui-account/client/avatar/avatar.html b/packages/rocketchat-ui-account/client/avatar/avatar.html new file mode 100644 index 000000000000..65d3b4ff4a59 --- /dev/null +++ b/packages/rocketchat-ui-account/client/avatar/avatar.html @@ -0,0 +1,9 @@ + diff --git a/packages/rocketchat-ui-account/client/avatar/avatar.js b/packages/rocketchat-ui-account/client/avatar/avatar.js new file mode 100644 index 000000000000..51f8c69b30de --- /dev/null +++ b/packages/rocketchat-ui-account/client/avatar/avatar.js @@ -0,0 +1,23 @@ +Template.avatar.helpers({ + src() { + let { url } = Template.instance().data; + if (!url) { + let { username } = this; + if (username == null && this.userId != null) { + const user = Meteor.users.findOne(this.userId); + username = user && user.username; + } + if (username == null) { + return; + } + Session.get(`avatar_random_${ username }`); + + if (this.roomIcon) { + username = `@${ username }`; + } + + url = getAvatarUrlFromUsername(username); + } + return url; + }, +}); diff --git a/packages/rocketchat-ui-account/client/avatar/prompt.html b/packages/rocketchat-ui-account/client/avatar/prompt.html new file mode 100644 index 000000000000..5a6d482dd20d --- /dev/null +++ b/packages/rocketchat-ui-account/client/avatar/prompt.html @@ -0,0 +1,109 @@ + + + + + diff --git a/packages/rocketchat-ui-account/client/avatar/prompt.js b/packages/rocketchat-ui-account/client/avatar/prompt.js new file mode 100644 index 000000000000..108a56bf74f9 --- /dev/null +++ b/packages/rocketchat-ui-account/client/avatar/prompt.js @@ -0,0 +1,163 @@ +/* globals fileUploadHandler */ + +import s from 'underscore.string'; +import toastr from 'toastr'; +import mime from 'mime-type/with-db'; + +Template.avatarPrompt.onCreated(function() { + const self = this; + self.suggestions = new ReactiveVar; + self.upload = new ReactiveVar; + self.getSuggestions = function() { + self.suggestions.set(undefined); + Meteor.call('getAvatarSuggestion', function(error, avatars) { + self.suggestions.set({ ready: true, avatars }); + }); + }; + self.getSuggestions(); +}); + +Template.avatarPrompt.onRendered(function() { + Tracker.afterFlush(function() { + if (!RocketChat.settings.get('Accounts_AllowUserAvatarChange')) { + FlowRouter.go('home'); + } + SideNav.setFlex('accountFlex'); + SideNav.openFlex(); + }); +}); + +Template.avatarPrompt.helpers({ + suggestions() { + return Template.instance().suggestions.get(); + }, + suggestAvatar(service) { + const suggestions = Template.instance().suggestions.get(); + return RocketChat.settings.get(`Accounts_OAuth_${ s.capitalize(service) }`) && !suggestions.avatars[service]; + }, + upload() { + return Template.instance().upload.get(); + }, + username() { + const user = Meteor.user(); + return user && user.username; + }, + initialsUsername() { + const user = Meteor.user(); + return `@${ user && user.username }`; + }, +}); + +Template.avatarPrompt.events({ + 'click .select-service'(event, instance) { + if (this.service === 'initials') { + Meteor.call('resetAvatar', function(err) { + if (err && err.details && err.details.timeToReset) { + toastr.error(t('error-too-many-requests', { + seconds: parseInt(err.details.timeToReset / 1000), + })); + } else { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', 'initials'); + } + }); + } else if (this.service === 'url') { + if (s.trim($('#avatarurl').val())) { + Meteor.call('setAvatarFromService', $('#avatarurl').val(), '', this.service, function(err) { + if (err) { + if (err.details.timeToReset && err.details.timeToReset) { + toastr.error(t('error-too-many-requests', { + seconds: parseInt(err.details.timeToReset / 1000), + })); + } else { + toastr.error(t('Avatar_url_invalid_or_error')); + } + } else { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', 'url'); + } + }); + } else { + toastr.error(t('Please_enter_value_for_url')); + } + } else if (this.service === 'upload') { + let { files } = instance.find('input[type=file]'); + if (!files || files.length === 0) { + files = (event.dataTransfer && event.dataTransfer.files) || []; + } + + for (let i = 0; i < files.length; i++) { + const file = files[i]; + Object.defineProperty(file, 'type', { value: mime.lookup(file.name) }); + } + + const record = { + name: files[0].name, + size: files[0].size, + type: files[0].type, + // description: document.getElementById('file-description').value + }; + + const upload = fileUploadHandler('Avatars', record, files[0]); + + // upload.onProgress = (progress) -> + // console.log 'progress ->', progress + + upload.start((error, result) => { + if (result) { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', this.service); + } + }); + } else { + const tmpService = this.service; + Meteor.call('setAvatarFromService', this.blob, this.contentType, this.service, function(err) { + if (err && err.details && err.details.timeToReset) { + toastr.error(t('error-too-many-requests', { + seconds: parseInt(err.details.timeToReset / 1000), + })); + } else { + toastr.success(t('Avatar_changed_successfully')); + RocketChat.callbacks.run('userAvatarSet', tmpService); + } + }); + } + }, + 'click .login-with-service'(event, template) { + const loginWithService = `loginWith${ s.capitalize(this) }`; + const serviceConfig = {}; + Meteor[loginWithService](serviceConfig, function(error) { + if (error && error.error) { + if (error.error === 'github-no-public-email') { + return alert(t('github_no_public_email')); + } + console.log(error); + return toastr.error(error.message); + } + template.getSuggestions(); + }); + }, + 'change .avatar-file-input'(event, template) { + const e = event.originalEvent || event; + let { files } = e.target; + if (!files || files.length === 0) { + files = (e.dataTransfer && e.dataTransfer.files) || []; + } + Object.keys(files).forEach((key) => { + const blob = files[key]; + if (!/image\/.+/.test(blob.type)) { + return; + } + const reader = new FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = function() { + template.upload.set({ + service: 'upload', + contentType: blob.type, + blob: reader.result, + }); + RocketChat.callbacks.run('userAvatarSet', 'upload'); + }; + }); + }, +}); diff --git a/packages/rocketchat-ui-account/package.js b/packages/rocketchat-ui-account/package.js index 77b86dc62687..e7a65cdcee53 100644 --- a/packages/rocketchat-ui-account/package.js +++ b/packages/rocketchat-ui-account/package.js @@ -7,33 +7,31 @@ Package.describe({ git: '', // By default, Meteor will default to using README.md for documentation. // To avoid submitting documentation, set this field to null. - documentation: 'README.md' + documentation: 'README.md', }); Package.onUse(function(api) { - api.versionsFrom('1.2.1'); - api.use([ 'ecmascript', 'templating', - 'coffeescript', - 'underscore', - 'rocketchat:lib@0.0.1' + 'rocketchat:lib', + 'sha', + 'rocketchat:lazy-load', ]); - api.addFiles('account/account.html', 'client'); - api.addFiles('account/accountFlex.html', 'client'); - api.addFiles('account/accountPreferences.html', 'client'); - api.addFiles('account/accountProfile.html', 'client'); - api.addFiles('account/avatar/avatar.html', 'client'); - api.addFiles('account/avatar/prompt.html', 'client'); + api.addFiles('client/account.html', 'client'); + api.addFiles('client/accountFlex.html', 'client'); + api.addFiles('client/accountPreferences.html', 'client'); + api.addFiles('client/accountProfile.html', 'client'); + api.addFiles('client/avatar/avatar.html', 'client'); + api.addFiles('client/avatar/prompt.html', 'client'); - api.addFiles('account/account.coffee', 'client'); - api.addFiles('account/accountFlex.coffee', 'client'); - api.addFiles('account/accountPreferences.coffee', 'client'); - api.addFiles('account/accountProfile.coffee', 'client'); - api.addFiles('account/avatar/avatar.coffee', 'client'); - api.addFiles('account/avatar/prompt.coffee', 'client'); + api.addFiles('client/account.js', 'client'); + api.addFiles('client/accountFlex.js', 'client'); + api.addFiles('client/accountPreferences.js', 'client'); + api.addFiles('client/accountProfile.js', 'client'); + api.addFiles('client/avatar/avatar.js', 'client'); + api.addFiles('client/avatar/prompt.js', 'client'); // api.addAssets('styles/side-nav.less', 'client'); -}); \ No newline at end of file +}); diff --git a/packages/rocketchat-ui-account/rocketchat-ui-account-tests.js b/packages/rocketchat-ui-account/rocketchat-ui-account-tests.js deleted file mode 100644 index c5623d89b9b8..000000000000 --- a/packages/rocketchat-ui-account/rocketchat-ui-account-tests.js +++ /dev/null @@ -1,5 +0,0 @@ -// Write your tests here! -// Here is an example. -Tinytest.add('example', function (test) { - test.equal(true, true); -}); diff --git a/packages/rocketchat-ui-account/rocketchat-ui-account.js b/packages/rocketchat-ui-account/rocketchat-ui-account.js deleted file mode 100644 index 164ddd9eed03..000000000000 --- a/packages/rocketchat-ui-account/rocketchat-ui-account.js +++ /dev/null @@ -1 +0,0 @@ -// Write your package code here! diff --git a/packages/rocketchat-ui-admin/admin/admin.coffee b/packages/rocketchat-ui-admin/admin/admin.coffee deleted file mode 100644 index 1f048328ca52..000000000000 --- a/packages/rocketchat-ui-admin/admin/admin.coffee +++ /dev/null @@ -1,112 +0,0 @@ -Template.admin.helpers - group: -> - group = FlowRouter.getParam('group') - group ?= Settings.findOne({ type: 'group' })?._id - return Settings.findOne { _id: group, type: 'group' } - sections: -> - group = FlowRouter.getParam('group') - group ?= Settings.findOne({ type: 'group' })?._id - settings = Settings.find({ group: group }, {sort: {section: 1, i18nLabel: 1}}).fetch() - sections = {} - for setting in settings - sections[setting.section or ''] ?= [] - sections[setting.section or ''].push setting - - sectionsArray = [] - for key, value of sections - sectionsArray.push - section: key - settings: value - - return sectionsArray - - flexOpened: -> - return 'opened' if RocketChat.TabBar.isFlexOpen() - arrowPosition: -> - console.log 'room.helpers arrowPosition' if window.rocketDebug - return 'left' unless RocketChat.TabBar.isFlexOpen() - label: -> - label = @i18nLabel or @_id - return TAPi18n.__ label if label - description: -> - description = @i18nDescription - return TAPi18n.__ description if description - sectionIsCustomOath: (section) -> - return /^Custom OAuth:\s.+/.test section - callbackURL: (section) -> - id = s.strRight(section, 'Custom OAuth: ').toLowerCase() - return Meteor.absoluteUrl('_oauth/' + id) - -Template.admin.events - "click .submit .save": (e, t) -> - group = FlowRouter.getParam('group') - settings = Settings.find({ group: group }).fetch() - updateSettings = [] - for setting in settings - value = null - if setting.type is 'string' - value = _.trim(t.$("[name=#{setting._id}]").val()) - else if setting.type is 'int' - value = parseInt(_.trim(t.$("[name=#{setting._id}]").val())) - else if setting.type is 'boolean' and t.$("[name=#{setting._id}]:checked").length - value = if t.$("[name=#{setting._id}]:checked").val() is "1" then true else false - else if setting.type is 'color' - value = _.trim(t.$("[name=#{setting._id}]").val()) - - if value? - updateSettings.push { _id: setting._id, value: value } - - if not _.isEmpty updateSettings - RocketChat.settings.batchSet updateSettings, (err, success) -> - return toastr.error TAPi18n.__ 'Error_updating_settings' if err - toastr.success TAPi18n.__ 'Settings_updated' - - "click .submit .add-custom-oauth": (e, t) -> - config = - title: TAPi18n.__ 'Add_custom_oauth' - text: TAPi18n.__ 'Give_a_unique_name_for_the_custom_oauth' - type: "input", - showCancelButton: true, - closeOnConfirm: true, - inputPlaceholder: TAPi18n.__ 'Custom_oauth_unique_name' - - swal config, (inputValue) -> - if inputValue is false - return false - - if inputValue is "" - swal.showInputError TAPi18n.__ 'Name_cant_be_empty' - return false - - Meteor.call 'addOAuthService', inputValue - - "click .submit .remove-custom-oauth": (e, t) -> - name = this.section.replace('Custom OAuth: ', '') - config = - title: TAPi18n.__ 'Are_you_sure' - type: "input", - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: TAPi18n.__ 'Yes_delete_it' - cancelButtonText: TAPi18n.__ 'Cancel' - closeOnConfirm: true - - swal config, -> - Meteor.call 'removeOAuthService', name - - -Template.admin.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "adminFlex" - SideNav.openFlex() - - Meteor.setTimeout -> - $('input.minicolors').minicolors({theme: 'rocketchat'}) - , 500 - - Tracker.autorun -> - FlowRouter.watchPathChange() - Meteor.setTimeout -> - $('input.minicolors').minicolors({theme: 'rocketchat'}) - , 200 diff --git a/packages/rocketchat-ui-admin/admin/admin.html b/packages/rocketchat-ui-admin/admin/admin.html deleted file mode 100644 index 868662ba7e76..000000000000 --- a/packages/rocketchat-ui-admin/admin/admin.html +++ /dev/null @@ -1,86 +0,0 @@ - diff --git a/packages/rocketchat-ui-admin/admin/adminFlex.coffee b/packages/rocketchat-ui-admin/admin/adminFlex.coffee deleted file mode 100644 index 3e664a14bb29..000000000000 --- a/packages/rocketchat-ui-admin/admin/adminFlex.coffee +++ /dev/null @@ -1,23 +0,0 @@ -Template.adminFlex.helpers - groups: -> - return Settings.find({type: 'group'}, { sort: { sort: 1, i18nLabel: 1 } }).fetch() - label: -> - return TAPi18n.__(@i18nLabel or @_id) - adminBoxOptions: -> - return RocketChat.AdminBox.getOptions() - -Template.adminFlex.events - 'mouseenter header': -> - SideNav.overArrow() - - 'mouseleave header': -> - SideNav.leaveArrow() - - 'click header': -> - SideNav.closeFlex() - - 'click .cancel-settings': -> - SideNav.closeFlex() - - 'click .admin-link': -> - menu.close() diff --git a/packages/rocketchat-ui-admin/admin/adminFlex.html b/packages/rocketchat-ui-admin/admin/adminFlex.html deleted file mode 100644 index c5c7b917f4d8..000000000000 --- a/packages/rocketchat-ui-admin/admin/adminFlex.html +++ /dev/null @@ -1,50 +0,0 @@ - diff --git a/packages/rocketchat-ui-admin/admin/adminStatistics.coffee b/packages/rocketchat-ui-admin/admin/adminStatistics.coffee deleted file mode 100644 index 7cc8a41bde6f..000000000000 --- a/packages/rocketchat-ui-admin/admin/adminStatistics.coffee +++ /dev/null @@ -1,61 +0,0 @@ -Template.adminStatistics.helpers - isReady: -> - return Template.instance().ready.get() - statistics: -> - return Template.instance().statistics.get() - inGB: (size) -> - if size > 1073741824 - return _.numberFormat(size / 1024 / 1024 / 1024, 2) + ' GB' - return _.numberFormat(size / 1024 / 1024, 2) + ' MB' - humanReadable: (time) -> - days = Math.floor time / 86400 - hours = Math.floor (time % 86400) / 3600 - minutes = Math.floor ((time % 86400) % 3600) / 60 - seconds = Math.floor ((time % 86400) % 3600) % 60 - out = "" - if days > 0 - out += "#{days} #{TAPi18n.__ 'days'}, " - if hours > 0 - out += "#{hours} #{TAPi18n.__ 'hours'}, " - if minutes > 0 - out += "#{minutes} #{TAPi18n.__ 'minutes'}, " - if seconds > 0 - out += "#{seconds} #{TAPi18n.__ 'seconds'}" - return out - numFormat: (number) -> - return _.numberFormat(number, 2) - optOut: -> - return RocketChat.settings.get 'Statistics_opt_out' - -Template.adminStatistics.events - 'click input[name=opt-out-statistics]': (e) -> - if $(e.currentTarget).prop('checked') - $('#opt-out-warning').show() - RocketChat.settings.set 'Statistics_opt_out', true, -> - toastr.success TAPi18n.__ 'Settings_updated' - else - $('#opt-out-warning').hide() - RocketChat.settings.set 'Statistics_opt_out', false, -> - toastr.success TAPi18n.__ 'Settings_updated' - -Template.adminStatistics.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "adminFlex" - SideNav.openFlex() - - if RocketChat.settings.get 'Statistics_opt_out' - $('#opt-out-warning').show() - else - $('#opt-out-warning').hide() - -Template.adminStatistics.onCreated -> - instance = @ - @statistics = new ReactiveVar {} - @ready = new ReactiveVar false - - Meteor.call 'getStatistics', (error, statistics) -> - instance.ready.set true - if error - toastr.error error.reason - else - instance.statistics.set statistics diff --git a/packages/rocketchat-ui-admin/admin/adminStatistics.html b/packages/rocketchat-ui-admin/admin/adminStatistics.html deleted file mode 100644 index f039362a8ea9..000000000000 --- a/packages/rocketchat-ui-admin/admin/adminStatistics.html +++ /dev/null @@ -1,120 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.coffee b/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.coffee deleted file mode 100644 index 731ea8daf1cb..000000000000 --- a/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.coffee +++ /dev/null @@ -1,45 +0,0 @@ -Template.adminRoomInfo.helpers - canDeleteRoom: -> - return RocketChat.authz.hasAtLeastOnePermission("delete-#{@t}") - - type: -> - return if @t is 'd' then 'at' else if @t is 'p' then 'lock' else 'hash' - name: -> - if @t is 'c' or @t is 'p' - return @name - else if @t is 'd' - return @usernames.join ' x ' - route: -> - return switch this.t - when 'd' - FlowRouter.path('direct', {username: @name}) - when 'p' - FlowRouter.path('group', {name: @name}) - when 'c' - FlowRouter.path('channel', {name: @name}) - -Template.adminRoomInfo.events - 'click .delete': -> - _id = Template.currentData()._id - swal { - title: t('Are_you_sure') - text: t('Delete_Room_Warning') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes_delete_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - }, -> - swal - title: t('Deleted') - text: t('Room_has_been_deleted') - type: 'success' - timer: 2000 - showConfirmButton: false - - Meteor.call 'eraseRoom', _id, (error, result) -> - if error - toastr.error error.reason - diff --git a/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.html b/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.html deleted file mode 100644 index 090f36d5e898..000000000000 --- a/packages/rocketchat-ui-admin/admin/rooms/adminRoomInfo.html +++ /dev/null @@ -1,20 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/rooms/adminRooms.coffee b/packages/rocketchat-ui-admin/admin/rooms/adminRooms.coffee deleted file mode 100644 index 09f2a78c135b..000000000000 --- a/packages/rocketchat-ui-admin/admin/rooms/adminRooms.coffee +++ /dev/null @@ -1,105 +0,0 @@ -Template.adminRooms.helpers - isReady: -> - return Template.instance().ready?.get() - rooms: -> - return Template.instance().rooms() - flexOpened: -> - return 'opened' if RocketChat.TabBar.isFlexOpen() - arrowPosition: -> - return 'left' unless RocketChat.TabBar.isFlexOpen() - isLoading: -> - return 'btn-loading' unless Template.instance().ready?.get() - hasMore: -> - return Template.instance().limit?.get() is Template.instance().rooms?().count() - roomCount: -> - return Template.instance().rooms?().count() - name: -> - if @t is 'c' or @t is 'p' - return @name - else if @t is 'd' - return @usernames.join ' x ' - type: -> - if @t is 'c' - return TAPi18n.__ 'Channel' - else if @t is 'd' - return TAPi18n.__ 'Direct Message' - if @t is 'p' - return TAPi18n.__ 'Private Group' - roomData: -> - return ChatRoom.findOne Session.get 'adminRoomsSelected' - -Template.adminRooms.onCreated -> - instance = @ - @limit = new ReactiveVar 50 - @filter = new ReactiveVar '' - @types = new ReactiveVar [] - @ready = new ReactiveVar true - - @autorun -> - filter = instance.filter.get() - types = instance.types.get() - limit = instance.limit.get() - subscription = instance.subscribe 'adminRooms', filter, types, limit - instance.ready.set subscription.ready() - - @rooms = -> - filter = _.trim instance.filter?.get() - types = instance.types?.get() - - unless _.isArray types - types = [] - - query = {} - - filter = _.trim filter - if filter - filterReg = new RegExp filter, "i" - query = { $or: [ { name: filterReg }, { t: 'd', usernames: filterReg } ] } - - if types.length - query['t'] = { $in: types } - - return ChatRoom.find(query, { limit: instance.limit?.get(), sort: { name: 1 } }) - - @getSearchTypes = -> - return _.map $('[name=room-type]:checked'), (input) -> return $(input).val() - -Template.adminRooms.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "adminFlex" - SideNav.openFlex() - -Template.adminRooms.events - 'keydown #rooms-filter': (e) -> - if e.which is 13 - e.stopPropagation() - e.preventDefault() - - 'keyup #rooms-filter': (e, t) -> - e.stopPropagation() - e.preventDefault() - t.filter.set e.currentTarget.value - - 'click .flex-tab .more': -> - if RocketChat.TabBar.isFlexOpen() - RocketChat.TabBar.closeFlex() - else - RocketChat.TabBar.openFlex() - - 'click .room-info': (e) -> - e.preventDefault() - Session.set 'adminRoomsSelected', $(e.currentTarget).data('id') - RocketChat.TabBar.openFlex() - - 'click .room-info-tabs a': (e) -> - e.preventDefault() - $('.room-info-tabs a').removeClass 'active' - $(e.currentTarget).addClass 'active' - - 'click .load-more': (e, t) -> - e.preventDefault() - e.stopPropagation() - t.limit.set t.limit.get() + 50 - - 'change [name=room-type]': (e, t) -> - t.types.set t.getSearchTypes() diff --git a/packages/rocketchat-ui-admin/admin/rooms/adminRooms.html b/packages/rocketchat-ui-admin/admin/rooms/adminRooms.html deleted file mode 100644 index cc39896ec68f..000000000000 --- a/packages/rocketchat-ui-admin/admin/rooms/adminRooms.html +++ /dev/null @@ -1,66 +0,0 @@ - diff --git a/packages/rocketchat-ui-admin/admin/users/adminInviteUser.coffee b/packages/rocketchat-ui-admin/admin/users/adminInviteUser.coffee deleted file mode 100644 index e0dc564bd064..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminInviteUser.coffee +++ /dev/null @@ -1,33 +0,0 @@ -Template.adminInviteUser.helpers - isAdmin: -> - return RocketChat.authz.hasRole(Meteor.userId(), 'admin') - emailEnabled: -> - console.log 'emailEnabled', RocketChat.settings.get('MAIL_URL') or (RocketChat.settings.get('SMTP_Host') and RocketChat.settings.get('SMTP_Username') and RocketChat.settings.get('SMTP_Password')) - return RocketChat.settings.get('MAIL_URL') or (RocketChat.settings.get('SMTP_Host') and RocketChat.settings.get('SMTP_Username') and RocketChat.settings.get('SMTP_Password')) - inviteEmails: -> - return Template.instance().inviteEmails.get() - -Template.adminInviteUser.events - 'click .send': (e, instance) -> - emails = $('#inviteEmails').val().split /[\s,;]/ - rfcMailPattern = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - validEmails = _.compact _.map emails, (email) -> return email if rfcMailPattern.test email - if validEmails.length - Meteor.call 'sendInvitationEmail', validEmails, (error, result) -> - if result - instance.clearForm() - instance.inviteEmails.set validEmails - if error - toastr.error error.reason - else - toastr.error t('Send_invitation_email_error') - - 'click .cancel': (e, instance) -> - instance.clearForm() - instance.inviteEmails.set [] - RocketChat.TabBar.closeFlex() - -Template.adminInviteUser.onCreated -> - @inviteEmails = new ReactiveVar [] - @clearForm = -> - $('#inviteEmails').val('') diff --git a/packages/rocketchat-ui-admin/admin/users/adminInviteUser.html b/packages/rocketchat-ui-admin/admin/users/adminInviteUser.html deleted file mode 100644 index 82740a313f0e..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminInviteUser.html +++ /dev/null @@ -1,31 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserChannels.coffee b/packages/rocketchat-ui-admin/admin/users/adminUserChannels.coffee deleted file mode 100644 index f7f5520e9215..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUserChannels.coffee +++ /dev/null @@ -1,11 +0,0 @@ -Template.adminUserChannels.helpers - type: -> - return if @t is 'd' then 'at' else if @t is 'p' then 'lock' else 'hash' - route: -> - return switch @t - when 'd' - FlowRouter.path('direct', {username: @name}) - when 'p' - FlowRouter.path('group', {name: @name}) - when 'c' - FlowRouter.path('channel', {name: @name}) diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee deleted file mode 100644 index f089dff3bed1..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.coffee +++ /dev/null @@ -1,35 +0,0 @@ -Template.adminUserEdit.helpers - email: -> - return @emails?[0]?.address - -Template.adminUserEdit.events - 'click .cancel': (e, t) -> - e.stopPropagation() - e.preventDefault() - t.cancel() - - 'click .save': (e, t) -> - e.stopPropagation() - e.preventDefault() - t.save() - -Template.adminUserEdit.onCreated -> - instance = @ - - @cancel = -> - RocketChat.TabBar.setTemplate 'adminUserInfo' - - @save = -> - userData = { _id: Template.currentData()._id } - userData.name = $("#name", ".edit-form").val() - userData.username = $("#username", ".edit-form").val() - - unless userData._id and userData.name - toastr.error TAPi18n.__('The_field_is_required'), TAPi18n.__('Name') - else - Meteor.call 'updateUser', userData, (error, result) -> - if result - toastr.success t('User_updated_successfully') - instance.cancel() - if error - toastr.error error.reason \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html b/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html deleted file mode 100644 index 686f999ffdba..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUserEdit.html +++ /dev/null @@ -1,23 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserInfo.coffee b/packages/rocketchat-ui-admin/admin/users/adminUserInfo.coffee deleted file mode 100644 index bf27f68b74ee..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUserInfo.coffee +++ /dev/null @@ -1,92 +0,0 @@ -Template.adminUserInfo.helpers - name: -> - return if @name then @name else TAPi18n.__ 'Unnamed' - email: -> - return @emails?[0]?.address - phoneNumber: -> - return '' unless @phoneNumber - if @phoneNumber.length > 10 - return "(#{@phoneNumber.substr(0,2)}) #{@phoneNumber.substr(2,5)}-#{@phoneNumber.substr(7)}" - else - return "(#{@phoneNumber.substr(0,2)}) #{@phoneNumber.substr(2,4)}-#{@phoneNumber.substr(6)}" - lastLogin: -> - if @lastLogin - return moment(@lastLogin).format('LLL') - utcOffset: -> - if @utcOffset? - if @utcOffset > 0 - @utcOffset = "+#{@utcOffset}" - - return "UTC #{@utcOffset}" - hasAdminRole: -> - console.log 'hasAdmin: ', RocketChat.authz.hasRole(@_id, 'admin') - return RocketChat.authz.hasRole(@_id, 'admin') - -Template.adminUserInfo.events - 'click .deactivate': (e) -> - e.stopPropagation() - e.preventDefault() - Meteor.call 'setUserActiveStatus', Template.currentData()._id, false, (error, result) -> - if result - toastr.success t('User_has_been_deactivated') - if error - toastr.error error.reason - - 'click .activate': (e) -> - e.stopPropagation() - e.preventDefault() - Meteor.call 'setUserActiveStatus', Template.currentData()._id, true, (error, result) -> - if result - toastr.success t('User_has_been_activated') - if error - toastr.error error.reason - - 'click .make-admin': (e) -> - e.stopPropagation() - e.preventDefault() - Meteor.call 'setAdminStatus', Template.currentData()._id, true, (error, result) -> - if result - toastr.success t('User_is_now_an_admin') - if error - toastr.error error.reason - - 'click .remove-admin': (e) -> - e.stopPropagation() - e.preventDefault() - Meteor.call 'setAdminStatus', Template.currentData()._id, false, (error, result) -> - if result - toastr.success t('User_is_no_longer_an_admin') - if error - toastr.error error.reason - - 'click .delete': (e) -> - e.stopPropagation() - e.preventDefault() - _id = Template.currentData()._id - swal { - title: t('Are_you_sure') - text: t('Delete_User_Warning') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes_delete_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - }, -> - swal - title: t('Deleted') - text: t('User_has_been_deleted') - type: 'success' - timer: 2000 - showConfirmButton: false - - Meteor.call 'deleteUser', _id, (error, result) -> - if error - toastr.error error.reason - Session.set 'adminSelectedUser' - - 'click .edit-user': (e) -> - e.stopPropagation() - e.preventDefault() - RocketChat.TabBar.setTemplate 'adminUserEdit' diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserInfo.html b/packages/rocketchat-ui-admin/admin/users/adminUserInfo.html deleted file mode 100644 index bbf17a35256a..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUserInfo.html +++ /dev/null @@ -1,25 +0,0 @@ - \ No newline at end of file diff --git a/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee b/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee deleted file mode 100644 index 098901fb5b2a..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUsers.coffee +++ /dev/null @@ -1,108 +0,0 @@ -Template.adminUsers.helpers - isReady: -> - return Template.instance().ready?.get() - users: -> - return Template.instance().users() - flexOpened: -> - return 'opened' if RocketChat.TabBar.isFlexOpen() - arrowPosition: -> - return 'left' unless RocketChat.TabBar.isFlexOpen() - userData: -> - return Meteor.users.findOne Session.get 'adminSelectedUser' - userChannels: -> - return ChatSubscription.find({ "u._id": Session.get 'adminSelectedUser' }, { fields: { rid: 1, name: 1, t: 1 }, sort: { t: 1, name: 1 } }).fetch() - isLoading: -> - return 'btn-loading' unless Template.instance().ready?.get() - hasMore: -> - return Template.instance().limit?.get() is Template.instance().users?().length - - flexTemplate: -> - return RocketChat.TabBar.getTemplate() - - flexData: -> - return RocketChat.TabBar.getData() - - adminClass: -> - return 'admin' if RocketChat.authz.hasRole(Meteor.userId(), 'admin') - - username: -> - return '@' + @username if @username? - - emailAddress: -> - return _.map(@emails, (e) -> e.address).join(', ') - -Template.adminUsers.onCreated -> - instance = @ - @limit = new ReactiveVar 50 - @filter = new ReactiveVar '' - @ready = new ReactiveVar true - - RocketChat.TabBar.addButton({ id: 'invite-user', i18nTitle: t('Invite_Users'), icon: 'icon-plus', template: 'adminInviteUser', order: 1 }) - - @autorun -> - filter = instance.filter.get() - limit = instance.limit.get() - subscription = instance.subscribe 'fullUserData', filter, limit - instance.ready.set subscription.ready() - - @autorun -> - if Session.get 'adminSelectedUser' - channelSubscription = instance.subscribe 'userChannels', Session.get 'adminSelectedUser' - RocketChat.TabBar.setData Meteor.users.findOne Session.get 'adminSelectedUser' - RocketChat.TabBar.addButton({ id: 'user-info', i18nTitle: t('User_Info'), icon: 'icon-user', template: 'adminUserInfo', order: 2 }) - # RocketChat.TabBar.addButton({ id: 'user-channel', i18nTitle: t('User_Channels'), icon: 'icon-hash', template: 'adminUserChannels', order: 3 }) - else - RocketChat.TabBar.reset() - RocketChat.TabBar.addButton({ id: 'invite-user', i18nTitle: t('Invite_Users'), icon: 'icon-plus', template: 'adminInviteUser', order: 1 }) - - @users = -> - filter = _.trim instance.filter?.get() - if filter - filterReg = new RegExp filter, "i" - query = { $or: [ { username: filterReg }, { name: filterReg }, { "emails.address": filterReg } ] } - else - query = {} - - return Meteor.users.find(query, { limit: instance.limit?.get(), sort: { username: 1, name: 1 } }).fetch() - -Template.adminUsers.onRendered -> - Tracker.afterFlush -> - SideNav.setFlex "adminFlex" - SideNav.openFlex() - -Template.adminUsers.events - 'keydown #users-filter': (e) -> - if e.which is 13 - e.stopPropagation() - e.preventDefault() - - 'keyup #users-filter': (e, t) -> - e.stopPropagation() - e.preventDefault() - t.filter.set e.currentTarget.value - - 'click .flex-tab .more': -> - if RocketChat.TabBar.isFlexOpen() - RocketChat.TabBar.closeFlex() - else - RocketChat.TabBar.openFlex() - - 'click .user-info': (e) -> - e.preventDefault() - Session.set 'adminSelectedUser', $(e.currentTarget).data('id') - Session.set 'showUserInfo', Meteor.users.findOne($(e.currentTarget).data('id'))?.username or true - RocketChat.TabBar.setTemplate 'adminUserInfo' - RocketChat.TabBar.openFlex() - - 'click .info-tabs a': (e) -> - e.preventDefault() - $('.info-tabs a').removeClass 'active' - $(e.currentTarget).addClass 'active' - - $('.user-info-content').hide() - $($(e.currentTarget).attr('href')).show() - - 'click .load-more': (e, t) -> - e.preventDefault() - e.stopPropagation() - t.limit.set t.limit.get() + 50 diff --git a/packages/rocketchat-ui-admin/admin/users/adminUsers.html b/packages/rocketchat-ui-admin/admin/users/adminUsers.html deleted file mode 100644 index 828ca152200b..000000000000 --- a/packages/rocketchat-ui-admin/admin/users/adminUsers.html +++ /dev/null @@ -1,60 +0,0 @@ - diff --git a/packages/rocketchat-ui-admin/client/admin.html b/packages/rocketchat-ui-admin/client/admin.html new file mode 100644 index 000000000000..2a90fd749216 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/admin.html @@ -0,0 +1,228 @@ + diff --git a/packages/rocketchat-ui-admin/client/admin.js b/packages/rocketchat-ui-admin/client/admin.js new file mode 100644 index 000000000000..e9ec12f91213 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/admin.js @@ -0,0 +1,604 @@ +/* globals jscolor, i18nDefaultQuery */ +import _ from 'underscore'; +import s from 'underscore.string'; +import toastr from 'toastr'; + +const TempSettings = new Mongo.Collection(null); + +RocketChat.TempSettings = TempSettings; + +const getDefaultSetting = function(settingId) { + return RocketChat.settings.collectionPrivate.findOne({ + _id: settingId, + }); +}; + +const setFieldValue = function(settingId, value, type, editor) { + const input = $('.page-settings').find(`[name="${ settingId }"]`); + switch (type) { + case 'boolean': + $('.page-settings').find(`[name="${ settingId }"][value="${ Number(value) }"]`).prop('checked', true).change(); + break; + case 'code': + input.next()[0].CodeMirror.setValue(value); + break; + case 'color': + editor = value && value[0] === '#' ? 'color' : 'expression'; + input.parents('.horizontal').find('select[name="color-editor"]').val(editor).change(); + input.val(value).change(); + break; + case 'roomPick': + const selectedRooms = Template.instance().selectedRooms.get(); + selectedRooms[settingId] = value; + Template.instance().selectedRooms.set(selectedRooms); + TempSettings.update({ _id: settingId }, { $set: { value, changed: JSON.stringify(RocketChat.settings.collectionPrivate.findOne(settingId).value) !== JSON.stringify(value) } }); + break; + default: + input.val(value).change(); + } +}; + +Template.admin.onCreated(function() { + if (RocketChat.settings.cachedCollectionPrivate == null) { + RocketChat.settings.cachedCollectionPrivate = new RocketChat.CachedCollection({ + name: 'private-settings', + eventType: 'onLogged', + useCache: false, + }); + RocketChat.settings.collectionPrivate = RocketChat.settings.cachedCollectionPrivate.collection; + RocketChat.settings.cachedCollectionPrivate.init(); + } + this.selectedRooms = new ReactiveVar({}); + RocketChat.settings.collectionPrivate.find().observe({ + added: (data) => { + const selectedRooms = this.selectedRooms.get(); + if (data.type === 'roomPick') { + selectedRooms[data._id] = data.value; + this.selectedRooms.set(selectedRooms); + } + TempSettings.insert(data); + }, + changed: (data) => { + const selectedRooms = this.selectedRooms.get(); + if (data.type === 'roomPick') { + selectedRooms[data._id] = data.value; + this.selectedRooms.set(selectedRooms); + } + TempSettings.update(data._id, data); + }, + removed: (data) => { + const selectedRooms = this.selectedRooms.get(); + if (data.type === 'roomPick') { + delete selectedRooms[data._id]; + this.selectedRooms.set(selectedRooms); + } + TempSettings.remove(data._id); + }, + }); +}); + +Template.admin.onDestroyed(function() { + TempSettings.remove({}); +}); + +Template.admin.helpers({ + languages() { + const languages = TAPi18n.getLanguages(); + + const result = Object.entries(languages) + .map(([key, language]) => ({ ...language, key: key.toLowerCase() })) + .sort((a, b) => a.key - b.key); + + result.unshift({ + name: 'Default', + en: 'Default', + key: '', + }); + + return result; + }, + isAppLanguage(key) { + const languageKey = RocketChat.settings.get('Language'); + return typeof languageKey === 'string' && languageKey.toLowerCase() === key; + }, + group() { + const groupId = FlowRouter.getParam('group'); + const group = RocketChat.settings.collectionPrivate.findOne({ + _id: groupId, + type: 'group', + }); + if (!group) { + return; + } + const settings = RocketChat.settings.collectionPrivate.find({ group: groupId }, { sort: { section: 1, sorter: 1, i18nLabel: 1 } }).fetch(); + const sections = {}; + + Object.keys(settings).forEach((key) => { + const setting = settings[key]; + if (setting.i18nDefaultQuery != null) { + if (_.isString(setting.i18nDefaultQuery)) { + i18nDefaultQuery = JSON.parse(setting.i18nDefaultQuery); + } else { + i18nDefaultQuery = setting.i18nDefaultQuery; + } + if (!_.isArray(i18nDefaultQuery)) { + i18nDefaultQuery = [i18nDefaultQuery]; + } + Object.keys(i18nDefaultQuery).forEach((key) => { + const item = i18nDefaultQuery[key]; + if (RocketChat.settings.collectionPrivate.findOne(item) != null) { + setting.value = TAPi18n.__(`${ setting._id }_Default`); + } + }); + } + const settingSection = setting.section || ''; + if (sections[settingSection] == null) { + sections[settingSection] = []; + } + sections[settingSection].push(setting); + }); + + group.sections = Object.keys(sections).map((key) => { + const value = sections[key]; + return { + section: key, + settings: value, + }; + }); + return group; + }, + i18nDefaultValue() { + return TAPi18n.__(`${ this._id }_Default`); + }, + isDisabled() { + let enableQuery; + if (this.blocked) { + return { + disabled: 'disabled', + }; + } + if (this.enableQuery == null) { + return {}; + } + if (_.isString(this.enableQuery)) { + enableQuery = JSON.parse(this.enableQuery); + } else { + enableQuery = this.enableQuery; + } + if (!_.isArray(enableQuery)) { + enableQuery = [enableQuery]; + } + let found = 0; + + Object.keys(enableQuery).forEach((key) => { + const item = enableQuery[key]; + if (TempSettings.findOne(item) != null) { + found++; + } + }); + if (found === enableQuery.length) { + return {}; + } else { + return { + disabled: 'disabled', + }; + } + }, + isReadonly() { + if (this.readonly === true) { + return { + readonly: 'readonly', + }; + } + }, + canAutocomplete() { + if (this.autocomplete === false) { + return { + autocomplete: 'off', + }; + } + }, + hasChanges(section) { + const group = FlowRouter.getParam('group'); + const query = { + group, + changed: true, + }; + if (section != null) { + if (section === '') { + query.$or = [ + { + section: '', + }, { + section: { + $exists: false, + }, + }, + ]; + } else { + query.section = section; + } + } + return TempSettings.find(query).count() > 0; + }, + isSettingChanged(id) { + return TempSettings.findOne({ + _id: id, + }, { + fields: { + changed: 1, + }, + }).changed; + }, + translateSection(section) { + if (section.indexOf(':') > -1) { + return section; + } + return t(section); + }, + label() { + const label = this.i18nLabel || this._id; + if (label) { + return TAPi18n.__(label); + } + }, + description() { + let description; + if (this.i18nDescription) { + description = TAPi18n.__(this.i18nDescription); + } + if ((description != null) && description !== this.i18nDescription) { + return description; + } + }, + sectionIsCustomOAuth(section) { + return /^Custom OAuth:\s.+/.test(section); + }, + callbackURL(section) { + const id = s.strRight(section, 'Custom OAuth: ').toLowerCase(); + return Meteor.absoluteUrl(`_oauth/${ id }`); + }, + relativeUrl(url) { + return Meteor.absoluteUrl(url); + }, + selectedOption(_id, val) { + const option = RocketChat.settings.collectionPrivate.findOne({ _id }); + return option && option.value === val; + }, + random() { + return Random.id(); + }, + getEditorOptions(readOnly = false) { + return { + lineNumbers: true, + mode: this.code || 'javascript', + gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'], + foldGutter: true, + matchBrackets: true, + autoCloseBrackets: true, + matchTags: true, + showTrailingSpace: true, + highlightSelectionMatches: true, + readOnly, + }; + }, + setEditorOnBlur(_id) { + Meteor.defer(function() { + if (!$(`.code-mirror-box[data-editor-id="${ _id }"] .CodeMirror`)[0]) { + return; + } + const codeMirror = $(`.code-mirror-box[data-editor-id="${ _id }"] .CodeMirror`)[0].CodeMirror; + if (codeMirror.changeAdded === true) { + return; + } + const onChange = function() { + const value = codeMirror.getValue(); + TempSettings.update({ _id }, { $set: { value, changed: RocketChat.settings.collectionPrivate.findOne(_id).value !== value } }); + }; + const onChangeDelayed = _.debounce(onChange, 500); + codeMirror.on('change', onChangeDelayed); + codeMirror.changeAdded = true; + }); + }, + assetAccept(fileConstraints) { + if (fileConstraints.extensions && fileConstraints.extensions.length) { + return `.${ fileConstraints.extensions.join(', .') }`; + } + }, + autocompleteRoom() { + return { + limit: 10, + // inputDelay: 300 + rules: [ + { + // @TODO maybe change this 'collection' and/or template + collection: 'CachedChannelList', + subscription: 'channelAndPrivateAutocomplete', + field: 'name', + template: Template.roomSearch, + noMatchTemplate: Template.roomSearchEmpty, + matchAll: true, + selector(match) { + return { + name: match, + }; + }, + sort: 'name', + }, + ], + }; + }, + selectedRooms() { + return Template.instance().selectedRooms.get()[this._id] || []; + }, + getColorVariable(color) { + return color.replace(/theme-color-/, '@'); + }, + showResetButton() { + const setting = TempSettings.findOne({ _id: this._id }, { fields: { value: 1, packageValue: 1 } }); + return this.type !== 'asset' && setting.value !== setting.packageValue && !this.blocked; + }, +}); + +Template.admin.events({ + 'change .input-monitor, keyup .input-monitor': _.throttle(function(e) { + let value = s.trim($(e.target).val()); + switch (this.type) { + case 'int': + value = parseInt(value); + break; + case 'boolean': + value = value === '1'; + break; + case 'color': + $(e.target).siblings('.colorpicker-swatch').css('background-color', value); + } + TempSettings.update({ + _id: this._id, + }, { + $set: { + value, + changed: RocketChat.settings.collectionPrivate.findOne(this._id).value !== value, + }, + }); + }, 500), + 'change select[name=color-editor]'(e) { + const value = s.trim($(e.target).val()); + TempSettings.update({ _id: this._id }, { $set: { editor: value } }); + RocketChat.settings.collectionPrivate.update({ _id: this._id }, { $set: { editor: value } }); + }, + 'click .rc-header__section-button .discard'() { + const group = FlowRouter.getParam('group'); + const query = { + group, + changed: true, + }; + const settings = TempSettings.find(query, { + fields: { _id: 1, value: 1, packageValue: 1 } }).fetch(); + settings.forEach(function(setting) { + const oldSetting = RocketChat.settings.collectionPrivate.findOne({ _id: setting._id }, { fields: { value: 1, type: 1, editor: 1 } }); + setFieldValue(setting._id, oldSetting.value, oldSetting.type, oldSetting.editor); + }); + }, + 'click .reset-setting'(e) { + e.preventDefault(); + let settingId = $(e.target).data('setting'); + if (typeof settingId === 'undefined') { + settingId = $(e.target).parent().data('setting'); + } + const defaultValue = getDefaultSetting(settingId); + setFieldValue(settingId, defaultValue.packageValue, defaultValue.type, defaultValue.editor); + }, + 'click .reset-group'(e) { + let settings; + e.preventDefault(); + const group = FlowRouter.getParam('group'); + const section = $(e.target).data('section'); + if (section === '') { + settings = TempSettings.find({ group, section: { $exists: false } }, { fields: { _id: 1 } }).fetch(); + } else { + settings = TempSettings.find({ group, section }, { fields: { _id: 1 } }).fetch(); + } + settings.forEach(function(setting) { + const defaultValue = getDefaultSetting(setting._id); + setFieldValue(setting._id, defaultValue.packageValue, defaultValue.type, defaultValue.editor); + TempSettings.update({ _id: setting._id }, { + $set: { + value: defaultValue.packageValue, + changed: RocketChat.settings.collectionPrivate.findOne(setting._id).value !== defaultValue.packageValue, + }, + }); + }); + }, + 'click .rc-header__section-button .save'() { + const group = FlowRouter.getParam('group'); + const query = { group, changed: true }; + const settings = TempSettings.find(query, { fields: { _id: 1, value: 1, editor: 1 } }).fetch() || []; + if (settings.length === 0) { + return; + } + + RocketChat.settings.batchSet(settings, (err) => { + if (err) { + return handleError(err); + } + + TempSettings.update({ changed: true }, { $unset: { changed: 1 } }); + + if (settings.some(({ _id }) => _id === 'Language')) { + const lng = Meteor.user().language + || settings.filter(({ _id }) => _id === 'Language').shift().value + || 'en'; + return TAPi18n._loadLanguage(lng).then(() => toastr.success(TAPi18n.__('Settings_updated', { lng }))); + } + toastr.success(TAPi18n.__('Settings_updated')); + }); + + }, + 'click .rc-header__section-button .refresh-clients'() { + Meteor.call('refreshClients', function() { + toastr.success(TAPi18n.__('Clients_will_refresh_in_a_few_seconds')); + }); + }, + 'click .rc-header__section-button .add-custom-oauth'() { + const config = { + title: TAPi18n.__('Add_custom_oauth'), + text: TAPi18n.__('Give_a_unique_name_for_the_custom_oauth'), + type: 'input', + showCancelButton: true, + closeOnConfirm: true, + inputPlaceholder: TAPi18n.__('Custom_oauth_unique_name'), + }; + modal.open(config, function(inputValue) { + if (inputValue === false) { + return false; + } + if (inputValue === '') { + modal.showInputError(TAPi18n.__('Name_cant_be_empty')); + return false; + } + Meteor.call('addOAuthService', inputValue, function(err) { + if (err) { + handleError(err); + } + }); + }); + }, + 'click .rc-header__section-button .refresh-oauth'() { + toastr.info(TAPi18n.__('Refreshing')); + return Meteor.call('refreshOAuthService', function(err) { + if (err) { + return handleError(err); + } else { + return toastr.success(TAPi18n.__('Done')); + } + }); + }, + 'click .rc-header__section-button .remove-custom-oauth'() { + const name = this.section.replace('Custom OAuth: ', ''); + const config = { + title: TAPi18n.__('Are_you_sure'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: TAPi18n.__('Yes_delete_it'), + cancelButtonText: TAPi18n.__('Cancel'), + closeOnConfirm: true, + }; + modal.open(config, function() { + Meteor.call('removeOAuthService', name); + }); + }, + 'click .delete-asset'() { + Meteor.call('unsetAsset', this.asset); + }, + 'change input[type=file]'(ev) { + const e = ev.originalEvent || ev; + let { files } = e.target; + if (!files || files.length === 0) { + if (e.dataTransfer && e.dataTransfer.files) { + files = e.dataTransfer.files; + } else { + files = []; + } + } + + Object.keys(files).forEach((key) => { + const blob = files[key]; + toastr.info(TAPi18n.__('Uploading_file')); + const reader = new FileReader(); + reader.readAsBinaryString(blob); + reader.onloadend = () => Meteor.call('setAsset', reader.result, blob.type, this.asset, function(err) { + if (err != null) { + handleError(err); + console.log(err); + return; + } + return toastr.success(TAPi18n.__('File_uploaded')); + }); + }); + }, + 'click .expand'(e) { + $(e.currentTarget).closest('.section').removeClass('section-collapsed'); + $(e.currentTarget).closest('button').removeClass('expand').addClass('collapse').find('span').text(TAPi18n.__('Collapse')); + $('.CodeMirror').each(function(index, codeMirror) { + codeMirror.CodeMirror.refresh(); + }); + }, + 'click .collapse'(e) { + $(e.currentTarget).closest('.section').addClass('section-collapsed'); + $(e.currentTarget).closest('button').addClass('expand').removeClass('collapse').find('span').text(TAPi18n.__('Expand')); + }, + 'click button.action'() { + if (this.type !== 'action') { + return; + } + Meteor.call(this.value, function(err, data) { + if (err != null) { + err.details = _.extend(err.details || {}, { + errorTitle: 'Error', + }); + handleError(err); + return; + } + const args = [data.message].concat(data.params); + toastr.success(TAPi18n.__.apply(TAPi18n, args), TAPi18n.__('Success')); + }); + }, + 'click .button-fullscreen'() { + const codeMirrorBox = $(`.code-mirror-box[data-editor-id="${ this._id }"]`); + codeMirrorBox.addClass('code-mirror-box-fullscreen content-background-color'); + codeMirrorBox.find('.CodeMirror')[0].CodeMirror.refresh(); + }, + 'click .button-restore'() { + const codeMirrorBox = $(`.code-mirror-box[data-editor-id="${ this._id }"]`); + codeMirrorBox.removeClass('code-mirror-box-fullscreen content-background-color'); + codeMirrorBox.find('.CodeMirror')[0].CodeMirror.refresh(); + }, + 'autocompleteselect .autocomplete'(event, instance, doc) { + const selectedRooms = instance.selectedRooms.get(); + selectedRooms[this.id] = (selectedRooms[this.id] || []).concat(doc); + instance.selectedRooms.set(selectedRooms); + const value = selectedRooms[this.id]; + TempSettings.update({ _id: this.id }, { $set: { value } }); + event.currentTarget.value = ''; + event.currentTarget.focus(); + }, + 'click .remove-room'(event, instance) { + const docId = this._id; + const settingId = event.currentTarget.getAttribute('data-setting'); + const selectedRooms = instance.selectedRooms.get(); + selectedRooms[settingId] = _.reject(selectedRooms[settingId] || [], function(setting) { + return setting._id === docId; + }); + instance.selectedRooms.set(selectedRooms); + const value = selectedRooms[settingId]; + TempSettings.update({ _id: settingId }, { + $set: { + value, + }, + }); + }, +}); + +Template.admin.onRendered(function() { + Tracker.afterFlush(function() { + SideNav.setFlex('adminFlex'); + SideNav.openFlex(); + }); + Tracker.autorun(function() { + const hasColor = TempSettings.find({ + group: FlowRouter.getParam('group'), + type: 'color', + }, { fields: { _id: 1, editor: 1 } }).fetch().length; + if (hasColor) { + Meteor.setTimeout(function() { + $('.colorpicker-input').each(function(index, el) { + if (!el._jscLinkedInstance) { + new jscolor(el); //eslint-disable-line + } + }); + }, 400); + } + }); +}); diff --git a/packages/rocketchat-ui-admin/client/adminFlex.html b/packages/rocketchat-ui-admin/client/adminFlex.html new file mode 100644 index 000000000000..cb8b16ff24ff --- /dev/null +++ b/packages/rocketchat-ui-admin/client/adminFlex.html @@ -0,0 +1,54 @@ + diff --git a/packages/rocketchat-ui-admin/client/adminFlex.js b/packages/rocketchat-ui-admin/client/adminFlex.js new file mode 100644 index 000000000000..93a12a2bac49 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/adminFlex.js @@ -0,0 +1,84 @@ +import _ from 'underscore'; +import s from 'underscore.string'; + +Template.adminFlex.onCreated(function() { + this.settingsFilter = new ReactiveVar(''); + if (RocketChat.settings.cachedCollectionPrivate == null) { + RocketChat.settings.cachedCollectionPrivate = new RocketChat.CachedCollection({ + name: 'private-settings', + eventType: 'onLogged', + useCache: false, + }); + RocketChat.settings.collectionPrivate = RocketChat.settings.cachedCollectionPrivate.collection; + RocketChat.settings.cachedCollectionPrivate.init(); + } +}); + +const label = function() { + return TAPi18n.__(this.i18nLabel || this._id); +}; + +// Template.adminFlex.onRendered(function() { +// $(this.find('.rooms-list')).perfectScrollbar(); +// }); + +Template.adminFlex.helpers({ + groups() { + const filter = Template.instance().settingsFilter.get(); + const query = { + type: 'group', + }; + if (filter) { + const filterRegex = new RegExp(s.escapeRegExp(filter), 'i'); + const records = RocketChat.settings.collectionPrivate.find().fetch(); + let groups = []; + records.forEach(function(record) { + if (filterRegex.test(TAPi18n.__(record.i18nLabel || record._id))) { + groups.push(record.group || record._id); + } + }); + groups = _.unique(groups); + if (groups.length > 0) { + query._id = { + $in: groups, + }; + } + } + return RocketChat.settings.collectionPrivate.find(query).fetch().map(function(el) { + el.label = label.apply(el); + return el; + }).sort(function(a, b) { + if (a.label.toLowerCase() >= b.label.toLowerCase()) { + return 1; + } else { + return -1; + } + }); + }, + label, + adminBoxOptions() { + return RocketChat.AdminBox.getOptions(); + }, + menuItem(name, icon, section, group) { + return { + name: t(name), + icon, + pathSection: section, + pathGroup: group, + darken: true, + isLightSidebar: true, + }; + }, + embeddedVersion() { + return RocketChat.Layout.isEmbedded(); + }, +}); + +Template.adminFlex.events({ + 'click [data-action="close"]'() { + SideNav.closeFlex(); + }, + 'keyup [name=settings-search]'(e, t) { + t.settingsFilter.set(e.target.value); + }, +}); diff --git a/packages/rocketchat-ui-admin/client/adminInfo.html b/packages/rocketchat-ui-admin/client/adminInfo.html new file mode 100644 index 000000000000..6ec77aea588d --- /dev/null +++ b/packages/rocketchat-ui-admin/client/adminInfo.html @@ -0,0 +1,275 @@ + diff --git a/packages/rocketchat-ui-admin/client/adminInfo.js b/packages/rocketchat-ui-admin/client/adminInfo.js new file mode 100644 index 000000000000..75b7fcfdc1a9 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/adminInfo.js @@ -0,0 +1,101 @@ +import s from 'underscore.string'; +import moment from 'moment'; + +Template.adminInfo.helpers({ + isReady() { + return Template.instance().ready.get(); + }, + statistics() { + return Template.instance().statistics.get(); + }, + instances() { + return Template.instance().instances.get(); + }, + inGB(size) { + if (size > 1073741824) { + return `${ s.numberFormat(size / 1024 / 1024 / 1024, 2) } GB`; + } + return `${ s.numberFormat(size / 1024 / 1024, 2) } MB`; + }, + humanReadableTime(time) { + const days = Math.floor(time / 86400); + const hours = Math.floor((time % 86400) / 3600); + const minutes = Math.floor(((time % 86400) % 3600) / 60); + const seconds = Math.floor(((time % 86400) % 3600) % 60); + let out = ''; + if (days > 0) { + out += `${ days } ${ TAPi18n.__('days') }, `; + } + if (hours > 0) { + out += `${ hours } ${ TAPi18n.__('hours') }, `; + } + if (minutes > 0) { + out += `${ minutes } ${ TAPi18n.__('minutes') }, `; + } + if (seconds > 0) { + out += `${ seconds } ${ TAPi18n.__('seconds') }`; + } + return out; + }, + formatDate(date) { + if (date) { + return moment(date).format('LLL'); + } + }, + numFormat(number) { + return s.numberFormat(number, 2); + }, + info() { + return RocketChat.Info; + }, + build() { + return RocketChat.Info && (RocketChat.Info.compile || RocketChat.Info.build); + }, +}); + +Template.adminInfo.events({ + 'click .refresh'(e, instance) { + instance.ready.set(false); + return Meteor.call('getStatistics', true, function(error, statistics) { + instance.ready.set(true); + if (error) { + return handleError(error); + } else { + return instance.statistics.set(statistics); + } + }); + }, +}); + +Template.adminInfo.onRendered(function() { + return Tracker.afterFlush(function() { + SideNav.setFlex('adminFlex'); + return SideNav.openFlex(); + }); +}); + +Template.adminInfo.onCreated(function() { + const instance = this; + this.statistics = new ReactiveVar({}); + this.instances = new ReactiveVar({}); + this.ready = new ReactiveVar(false); + if (RocketChat.authz.hasAllPermission('view-statistics')) { + Meteor.call('getStatistics', function(error, statistics) { + instance.ready.set(true); + if (error) { + handleError(error); + } else { + instance.statistics.set(statistics); + } + }); + + Meteor.call('instances/get', function(error, instances) { + instance.ready.set(true); + if (error) { + handleError(error); + } else { + instance.instances.set(instances); + } + }); + } +}); diff --git a/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.html b/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.html new file mode 100644 index 000000000000..8edb049bfa7a --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.html @@ -0,0 +1,94 @@ + diff --git a/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.js b/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.js new file mode 100644 index 000000000000..1ea3038ea49c --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/adminRoomInfo.js @@ -0,0 +1,254 @@ +/* globals AdminChatRoom */ +import toastr from 'toastr'; +Template.adminRoomInfo.helpers({ + selectedRoom() { + return Session.get('adminRoomsSelected'); + }, + canEdit() { + return RocketChat.authz.hasAllPermission('edit-room', this.rid); + }, + editing(field) { + return Template.instance().editing.get() === field; + }, + notDirect() { + const room = AdminChatRoom.findOne(this.rid, { fields: { t: 1 } }); + return room && room.t !== 'd'; + }, + roomType() { + const room = AdminChatRoom.findOne(this.rid, { fields: { t: 1 } }); + return room && room.t; + }, + channelSettings() { + return RocketChat.ChannelSettings.getOptions(undefined, 'admin-room'); + }, + roomTypeDescription() { + const room = AdminChatRoom.findOne(this.rid, { fields: { t: 1 } }); + const roomType = room && room.t; + if (roomType === 'c') { + return t('Channel'); + } else if (roomType === 'p') { + return t('Private_Group'); + } + }, + roomName() { + const room = AdminChatRoom.findOne(this.rid, { fields: { name: 1 } }); + return room && room.name; + }, + roomTopic() { + const room = AdminChatRoom.findOne(this.rid, { fields: { topic: 1 } }); + return room && room.topic; + }, + archivationState() { + const room = AdminChatRoom.findOne(this.rid, { fields: { archived: 1 } }); + return room && room.archived; + }, + archivationStateDescription() { + const room = AdminChatRoom.findOne(this.rid, { fields: { archived: 1 } }); + const archivationState = room && room.archived; + if (archivationState === true) { + return t('Room_archivation_state_true'); + } else { + return t('Room_archivation_state_false'); + } + }, + canDeleteRoom() { + const room = AdminChatRoom.findOne(this.rid, { fields: { t: 1 } }); + const roomType = room && room.t; + return (roomType != null) && RocketChat.authz.hasAtLeastOnePermission(`delete-${ roomType }`); + }, + readOnly() { + const room = AdminChatRoom.findOne(this.rid, { fields: { ro: 1 } }); + return room && room.ro; + }, + readOnlyDescription() { + const room = AdminChatRoom.findOne(this.rid, { fields: { ro: 1 } }); + const readOnly = room && room.ro; + + if (readOnly === true) { + return t('True'); + } else { + return t('False'); + } + }, +}); + +Template.adminRoomInfo.events({ + 'click .delete'() { + modal.open({ + title: t('Are_you_sure'), + text: t('Delete_Room_Warning'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes_delete_it'), + cancelButtonText: t('Cancel'), + closeOnConfirm: false, + html: false, + }, () => { + Meteor.call('eraseRoom', this.rid, function(error) { + if (error) { + handleError(error); + } else { + modal.open({ + title: t('Deleted'), + text: t('Room_has_been_deleted'), + type: 'success', + timer: 2000, + showConfirmButton: false, + }); + } + }); + }); + }, + 'keydown input[type=text]'(e, t) { + if (e.keyCode === 13) { + e.preventDefault(); + t.saveSetting(this.rid); + } + }, + 'click [data-edit]'(e, t) { + e.preventDefault(); + t.editing.set($(e.currentTarget).data('edit')); + return setTimeout((function() { + t.$('input.editing').focus().select(); + }), 100); + }, + 'click .cancel'(e, t) { + e.preventDefault(); + t.editing.set(); + }, + 'click .save'(e, t) { + e.preventDefault(); + t.saveSetting(this.rid); + }, +}); + +Template.adminRoomInfo.onCreated(function() { + this.editing = new ReactiveVar; + this.validateRoomType = () => { + const type = this.$('input[name=roomType]:checked').val(); + if (type !== 'c' && type !== 'p') { + toastr.error(t('error-invalid-room-type', { type })); + } + return true; + }; + this.validateRoomName = (rid) => { + const room = AdminChatRoom.findOne(rid); + let nameValidation; + if (!RocketChat.authz.hasAllPermission('edit-room', rid) || (room.t !== 'c' && room.t !== 'p')) { + toastr.error(t('error-not-allowed')); + return false; + } + name = $('input[name=roomName]').val(); + try { + nameValidation = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + } catch (_error) { + nameValidation = new RegExp('^[0-9a-zA-Z-_.]+$'); + } + if (!nameValidation.test(name)) { + toastr.error(t('error-invalid-room-name', { + room_name: name, + })); + return false; + } + return true; + }; + this.validateRoomTopic = () => true; + this.saveSetting = (rid) => { + switch (this.editing.get()) { + case 'roomName': + if (this.validateRoomName(rid)) { + RocketChat.callbacks.run('roomNameChanged', AdminChatRoom.findOne(rid)); + Meteor.call('saveRoomSettings', rid, 'roomName', this.$('input[name=roomName]').val(), function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_name_changed_successfully')); + }); + } + break; + case 'roomTopic': + if (this.validateRoomTopic(rid)) { + Meteor.call('saveRoomSettings', rid, 'roomTopic', this.$('input[name=roomTopic]').val(), function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_topic_changed_successfully')); + RocketChat.callbacks.run('roomTopicChanged', AdminChatRoom.findOne(rid)); + }); + } + break; + case 'roomAnnouncement': + if (this.validateRoomTopic(rid)) { + Meteor.call('saveRoomSettings', rid, 'roomAnnouncement', this.$('input[name=roomAnnouncement]').val(), function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_announcement_changed_successfully')); + RocketChat.callbacks.run('roomAnnouncementChanged', AdminChatRoom.findOne(rid)); + }); + } + break; + case 'roomType': + const val = this.$('input[name=roomType]:checked').val(); + if (this.validateRoomType(rid)) { + RocketChat.callbacks.run('roomTypeChanged', AdminChatRoom.findOne(rid)); + const saveRoomSettings = function() { + Meteor.call('saveRoomSettings', rid, 'roomType', val, function(err) { + if (err) { + return handleError(err); + } else { + toastr.success(TAPi18n.__('Room_type_changed_successfully')); + } + }); + }; + if (!AdminChatRoom.findOne(rid, { fields: { default: 1 } }).default) { + return saveRoomSettings(); + } + modal.open({ + title: t('Room_default_change_to_private_will_be_default_no_more'), + type: 'warning', + showCancelButton: true, + confirmButtonColor: '#DD6B55', + confirmButtonText: t('Yes'), + cancelButtonText: t('Cancel'), + closeOnConfirm: true, + html: false, + }, function(confirmed) { + return !confirmed || saveRoomSettings(); + }); + } + break; + case 'archivationState': + const room = AdminChatRoom.findOne(rid); + if (this.$('input[name=archivationState]:checked').val() === 'true') { + if (room && room.archived !== true) { + Meteor.call('archiveRoom', rid, function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_archived')); + RocketChat.callbacks.run('archiveRoom', AdminChatRoom.findOne(rid)); + }); + } + } else if ((room && room.archived) === true) { + Meteor.call('unarchiveRoom', rid, function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_unarchived')); + RocketChat.callbacks.run('unarchiveRoom', AdminChatRoom.findOne(rid)); + }); + } + break; + case 'readOnly': + Meteor.call('saveRoomSettings', rid, 'readOnly', this.$('input[name=readOnly]:checked').val() === 'true', function(err) { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Read_only_changed_successfully')); + }); + } + this.editing.set(); + }; +}); diff --git a/packages/rocketchat-ui-admin/client/rooms/adminRooms.html b/packages/rocketchat-ui-admin/client/rooms/adminRooms.html new file mode 100644 index 000000000000..dcf918ff9aa7 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/adminRooms.html @@ -0,0 +1,62 @@ + diff --git a/packages/rocketchat-ui-admin/client/rooms/adminRooms.js b/packages/rocketchat-ui-admin/client/rooms/adminRooms.js new file mode 100644 index 000000000000..d67267b336ae --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/adminRooms.js @@ -0,0 +1,152 @@ +/* globals AdminChatRoom, RocketChat */ +import _ from 'underscore'; +import s from 'underscore.string'; + +import { RocketChatTabBar } from 'meteor/rocketchat:lib'; + +this.AdminChatRoom = new Mongo.Collection('rocketchat_room'); + +Template.adminRooms.helpers({ + isReady() { + const instance = Template.instance(); + return instance.ready && instance.ready.get(); + }, + rooms() { + return Template.instance().rooms(); + }, + isLoading() { + const instance = Template.instance(); + if (!(instance.ready && instance.ready.get())) { + return 'btn-loading'; + } + }, + hasMore() { + const instance = Template.instance(); + if (instance.limit && instance.limit.get() && instance.rooms() && instance.rooms().count()) { + return instance.limit.get() === instance.rooms().count(); + } + }, + roomCount() { + const rooms = Template.instance().rooms(); + return rooms && rooms.count(); + }, + name() { + return RocketChat.roomTypes.roomTypes[this.t].getDisplayName(this); + }, + type() { + return TAPi18n.__(RocketChat.roomTypes.roomTypes[this.t].label); + }, + 'default'() { + if (this.default) { + return t('True'); + } else { + return t('False'); + } + }, + flexData() { + return { + tabBar: Template.instance().tabBar, + }; + }, +}); + +Template.adminRooms.onCreated(function() { + const instance = this; + this.limit = new ReactiveVar(50); + this.filter = new ReactiveVar(''); + this.types = new ReactiveVar([]); + this.ready = new ReactiveVar(true); + this.tabBar = new RocketChatTabBar(); + this.tabBar.showGroup(FlowRouter.current().route.name); + RocketChat.TabBar.addButton({ + groups: ['admin-rooms'], + id: 'admin-room', + i18nTitle: 'Room_Info', + icon: 'info-circled', + template: 'adminRoomInfo', + order: 1, + }); + RocketChat.ChannelSettings.addOption({ + group: ['admin-room'], + id: 'make-default', + template: 'channelSettingsDefault', + data() { + return Session.get('adminRoomsSelected'); + }, + validation() { + return RocketChat.authz.hasAllPermission('view-room-administration'); + }, + }); + this.autorun(function() { + const filter = instance.filter.get(); + let types = instance.types.get(); + if (types.length === 0) { + types = ['c', 'd', 'p']; + } + const limit = instance.limit.get(); + const subscription = instance.subscribe('adminRooms', filter, types, limit); + instance.ready.set(subscription.ready()); + }); + this.rooms = function() { + let filter; + if (instance.filter && instance.filter.get()) { + filter = s.trim(instance.filter.get()); + } + let types = instance.types && instance.types.get(); + if (!_.isArray(types)) { + types = []; + } + let query = {}; + filter = s.trim(filter); + if (filter) { + const filterReg = new RegExp(s.escapeRegExp(filter), 'i'); + query = { $or: [{ name: filterReg }, { t: 'd', usernames: filterReg }] }; + } + if (types.length) { + query.t = { $in: types }; + } + const limit = instance.limit && instance.limit.get(); + return AdminChatRoom.find(query, { limit, sort: { default: -1, name: 1 } }); + }; + this.getSearchTypes = function() { + return _.map($('[name=room-type]:checked'), function(input) { + return $(input).val(); + }); + }; +}); + +Template.adminRooms.onRendered(function() { + Tracker.afterFlush(function() { + SideNav.setFlex('adminFlex'); + SideNav.openFlex(); + }); +}); + +Template.adminRooms.events({ + 'keydown #rooms-filter'(e) { + if (e.which === 13) { + e.stopPropagation(); + e.preventDefault(); + } + }, + 'keyup #rooms-filter'(e, t) { + e.stopPropagation(); + e.preventDefault(); + t.filter.set(e.currentTarget.value); + }, + 'click .room-info'(e, instance) { + e.preventDefault(); + Session.set('adminRoomsSelected', { + rid: this._id, + }); + instance.tabBar.open('admin-room'); + }, + 'click .load-more'(e, t) { + e.preventDefault(); + e.stopPropagation(); + t.limit.set(t.limit.get() + 50); + }, + 'change [name=room-type]'(e, t) { + t.types.set(t.getSearchTypes()); + }, +}); diff --git a/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.html b/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.html new file mode 100644 index 000000000000..d26a033f2b26 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.html @@ -0,0 +1,17 @@ + diff --git a/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.js b/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.js new file mode 100644 index 000000000000..63c30c5f58c0 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/rooms/channelSettingsDefault.js @@ -0,0 +1,57 @@ +import toastr from 'toastr'; +/* globals AdminChatRoom */ + +Template.channelSettingsDefault.helpers({ + canMakeDefault() { + const room = AdminChatRoom.findOne(this.rid, { fields: { t: 1 } }); + return room && room.t === 'c'; + }, + editing(field) { + return Template.instance().editing.get() === field; + }, + roomDefault() { + const room = AdminChatRoom.findOne(this.rid, { fields: { default: 1 } }); + + if (room) { + return room.default; + } + }, + defaultDescription() { + const room = AdminChatRoom.findOne(this.rid, { fields: { default: 1 } }); + if (room && room.default) { + return t('True'); + } else { + return t('False'); + } + }, +}); + +Template.channelSettingsDefault.events({ + 'click [data-edit]'(e, t) { + e.preventDefault(); + t.editing.set($(e.currentTarget).data('edit')); + setTimeout(() => { + t.$('input.editing').focus().select(); + }, 100); + }, + 'click .cancel'(e, t) { + e.preventDefault(); + t.editing.set(); + }, + 'click .save'(e, t) { + e.preventDefault(); + + Meteor.call('saveRoomSettings', this.rid, 'default', $('input[name=default]:checked').val(), (err/* , result*/) => { + if (err) { + return handleError(err); + } + toastr.success(TAPi18n.__('Room_type_changed_successfully')); + }); + + t.editing.set(); + }, +}); + +Template.channelSettingsDefault.onCreated(function() { + this.editing = new ReactiveVar(); +}); diff --git a/packages/rocketchat-ui-admin/client/users/adminInviteUser.html b/packages/rocketchat-ui-admin/client/users/adminInviteUser.html new file mode 100644 index 000000000000..32b0c3bf2db8 --- /dev/null +++ b/packages/rocketchat-ui-admin/client/users/adminInviteUser.html @@ -0,0 +1,31 @@ + diff --git a/packages/rocketchat-ui-admin/client/users/adminInviteUser.js b/packages/rocketchat-ui-admin/client/users/adminInviteUser.js new file mode 100644 index 000000000000..f6057c017bae --- /dev/null +++ b/packages/rocketchat-ui-admin/client/users/adminInviteUser.js @@ -0,0 +1,48 @@ +import _ from 'underscore'; +import toastr from 'toastr'; + +Template.adminInviteUser.helpers({ + isAdmin() { + return RocketChat.authz.hasRole(Meteor.userId(), 'admin'); + }, + inviteEmails() { + return Template.instance().inviteEmails.get(); + }, +}); + +Template.adminInviteUser.events({ + 'click .send'(e, instance) { + const emails = $('#inviteEmails').val().split(/[\s,;]/); + const rfcMailPattern = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; + const validEmails = _.compact(_.map(emails, function(email) { + if (rfcMailPattern.test(email)) { + return email; + } + })); + if (validEmails.length) { + Meteor.call('sendInvitationEmail', validEmails, function(error, result) { + if (result) { + instance.clearForm(); + instance.inviteEmails.set(validEmails); + } + if (error) { + handleError(error); + } + }); + } else { + toastr.error(t('Send_invitation_email_error')); + } + }, + 'click .cancel'(e, instance) { + instance.clearForm(); + instance.inviteEmails.set([]); + Template.currentData().tabBar.close(); + }, +}); + +Template.adminInviteUser.onCreated(function() { + this.inviteEmails = new ReactiveVar([]); + this.clearForm = function() { + $('#inviteEmails').val(''); + }; +}); diff --git a/packages/rocketchat-ui-admin/admin/users/adminUserChannels.html b/packages/rocketchat-ui-admin/client/users/adminUserChannels.html similarity index 77% rename from packages/rocketchat-ui-admin/admin/users/adminUserChannels.html rename to packages/rocketchat-ui-admin/client/users/adminUserChannels.html index af72dcbbad0e..a1b85e7fc76f 100644 --- a/packages/rocketchat-ui-admin/admin/users/adminUserChannels.html +++ b/packages/rocketchat-ui-admin/client/users/adminUserChannels.html @@ -1,6 +1,6 @@