diff --git a/.circleci/config.yml b/.circleci/config.yml index a47db9b5ed10..55c71b9fd7eb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -276,7 +276,6 @@ jobs: name: Build Docker image command: | cd /tmp/build - cp ~/repo/.docker/Dockerfile . tar xzf Rocket.Chat.tar.gz rm Rocket.Chat.tar.gz @@ -284,15 +283,29 @@ jobs: 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 - if [[ $CIRCLE_TAG =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + 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 - else + + 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 @@ -301,9 +314,17 @@ jobs: 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; @@ -330,15 +351,22 @@ jobs: fi; cd /tmp/build - cp ~/repo/.docker/Dockerfile . 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: 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..89a347637ac1 --- /dev/null +++ b/.docker-mongo/entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +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.rhel b/.docker/Dockerfile.rhel index 4b6c8b3e1cc6..3cdb4e368b78 100644 --- a/.docker/Dockerfile.rhel +++ b/.docker/Dockerfile.rhel @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/rhscl/nodejs-8-rhel7 -ENV RC_VERSION 0.66.0-develop +ENV RC_VERSION 0.67.0-develop MAINTAINER buildmaster@rocket.chat diff --git a/.github/history.json b/.github/history.json index b1c3bd04b42a..21cfa973438b 100644 --- a/.github/history.json +++ b/.github/history.json @@ -15363,9 +15363,1370 @@ ] }, "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": [] + "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" + ] + } + ] } } -} +} \ No newline at end of file diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp index 1ccd77554696..b8b8cabc1b77 100644 --- a/.sandstorm/sandstorm-pkgdef.capnp +++ b/.sandstorm/sandstorm-pkgdef.capnp @@ -19,9 +19,9 @@ const pkgdef :Spk.PackageDefinition = ( appTitle = (defaultText = "Rocket.Chat"), - appVersion = 71, # Increment this for every release. + appVersion = 78, # Increment this for every release. - appMarketingVersion = (defaultText = "0.66.0-develop"), + appMarketingVersion = (defaultText = "0.67.0-develop"), # Human-readable representation of appVersion. Should match the way you # identify versions of your app in documentation and marketing. diff --git a/.snapcraft/README.md b/.snapcraft/README.md deleted file mode 100644 index f0197f2dc65b..000000000000 --- a/.snapcraft/README.md +++ /dev/null @@ -1,61 +0,0 @@ -![Rocket.Chat logo](https://rocket.chat/images/logo/logo-dark.svg?v3) - -# rocketchat-server snap for Ubuntu Core (all arch) - -Features: -* bundles ubuntu distribution specific and RC compatible mongodb version -* oplog tailing for mongo by default -* mongodb backup command -* mongodb restore command -* caddy reverse proxy built-in - capable of handling free lestencrypt ssl - -Note: - -Currently, this repository is mirrored on launchpad, and used to build latest ARMHF and i386 snaps. - -You can download recent builds here: -https://code.launchpad.net/~sing-li/+snap/rocketchat-server - -Due an issue with the existing installed base of amd64 users (existing snap always installed mongodb 3.2 [#issue](https://github.com/RocketChat/rocketchat-server-snap/issues/3)), this snap is not currently used for amd64 builds. - -### Test installation - -Download the latest snap file of the corresponding architecture to your Ubuntu Core 16 or 16.04LTS server. - -`sudo snap install ./rocketchat-server-xxxxxxxx.snap --dangerous` - - -### Development or compile your own snap - -Make sure you have `snapcraft` installed. - -``` -git clone https://github.com/RocketChat/rocketchat-server-snap -cd rocketchat-server-snap -snapcraft snap -``` - -### Regression tests (run for amd64, i386 and armhf): -- snapcraft runs properly -- snap installs properly -- all services start automatically -- rc service shows a 5-second restart delay while waiting for mongo - - to test manually, stop rc, stop mongo, start rc, wait 20s or so, start mongo -- rc can be successfully restarted via the "Restart the server" button under Admin > Settings > General -- rc service shows a 5-second delay when restarted via this button -- all commands execute successfully: - - initcaddy - - modify the Caddyfile to test: - - self-signed TLS certificate (use the "tls self_signed" caddy directive) - - changing ports (with and without TLS) - - using IP address (only works without TLS) - - successfully acquiring a Let's Encrypt certificate (requires a registered domain) - - backupdb - - should run only with sudo - - restoredb - - ideally, stop rc service prior to running this (mongo must be running) - - should run only with sudo - - use any file outside of $snap_common (should fail) - - use the file created with backupdb - - use a dummy .tgz file without actual data - - with and without a "parties" directory in the archive diff --git a/.snapcraft/resources/prepareRocketChat b/.snapcraft/resources/prepareRocketChat index 882998b9f82a..2251551e6d0b 100755 --- a/.snapcraft/resources/prepareRocketChat +++ b/.snapcraft/resources/prepareRocketChat @@ -2,11 +2,18 @@ curl -SLf "https://releases.rocket.chat/#{RC_VERSION}/download/" -o rocket.chat.tgz -tar xvf rocket.chat.tgz --strip 1 +tar xf rocket.chat.tgz --strip 1 cd programs/server +rm -rf npm/node_modules/meteor/emojione_emojione/node_modules/grunt-contrib-qunit -npm install +if [[ $(uname -m) == *armv6l* ]] || [[ $(uname -m) == *armv7l* ]] +then + rm -rf npm/node_modules/sharp/vendor +fi + +export NODE_ENV=production +npm i # Ideally this will go away. For some reason on install its installing node-v57-linux-x64-glibc but when actually running it is looking for node-v57-linux-x64-unknown if [[ $(uname -m) == "x86_64" ]] @@ -15,4 +22,5 @@ then fi # sharp needs execution stack removed - https://forum.snapcraft.io/t/snap-and-executable-stacks/1812 -execstack --clear-execstack npm/node_modules/sharp/vendor/lib/librsvg-2.so.2.42.0 +ls -l npm/node_modules/sharp/vendor +execstack --clear-execstack npm/node_modules/sharp/vendor/lib/librsvg-2.so* diff --git a/.snapcraft/resources/preparenode b/.snapcraft/resources/preparenode new file mode 100755 index 000000000000..f6e0c58d3cc5 --- /dev/null +++ b/.snapcraft/resources/preparenode @@ -0,0 +1,23 @@ +#!/bin/bash + +node_version="v8.11.3" + +unamem="$(uname -m)" +if [[ $unamem == *aarch64* ]]; then + node_arch="arm64" +elif [[ $unamem == *64* ]]; then + node_arch="x64" +elif [[ $unamem == *86* ]]; then + node_arch="x86" +elif [[ $unamem == *armv6l* ]]; then + node_arch="armv6l" +elif [[ $unamem == *armv7l* ]]; then + node_arch="armv7l" +else + echo "Aborted, unsupported or unknown architecture: $unamem" + return 2 +fi + + +wget https://nodejs.org/dist/$node_version/node-$node_version-linux-$node_arch.tar.xz +tar xf node-$node_version-linux-$node_arch.tar.xz --strip 1 diff --git a/.snapcraft/snapcraft.yaml b/.snapcraft/snapcraft.yaml index 48378873580c..77bd479d66e9 100644 --- a/.snapcraft/snapcraft.yaml +++ b/.snapcraft/snapcraft.yaml @@ -39,7 +39,7 @@ apps: parts: node: plugin: dump - prepare: wget https://nodejs.org/dist/v8.11.2/node-v8.11.2-linux-x64.tar.xz; tar xvf node-v8.11.2-linux-x64.tar.xz --strip 1; + prepare: ./resources/preparenode build-packages: # For fibers - python diff --git a/.travis/snap.sh b/.travis/snap.sh index 3a2254b83a4f..6e54bc03d119 100755 --- a/.travis/snap.sh +++ b/.travis/snap.sh @@ -17,7 +17,7 @@ elif [[ $TRAVIS_TAG ]]; then RC_VERSION=$TRAVIS_TAG else CHANNEL=edge - RC_VERSION=0.66.0-develop + RC_VERSION=0.67.0-develop fi echo "Preparing to trigger a snap release for $CHANNEL channel" diff --git a/HISTORY.md b/HISTORY.md index 324bde0e944a..f7da984a470e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,212 @@ +# 0.66.0 +`2018-06-27 · 1 ️️️⚠️ · 23 🎉 · 61 🐛 · 50 🔍 · 45 👩‍💻👨‍💻` + +### Engine versions +- Node: `8.11.3` +- NPM: `5.6.0` + +### ⚠️ BREAKING CHANGES + +- Always remove the field `services` from user data responses in REST API ([#10799](https://github.com/RocketChat/Rocket.Chat/pull/10799)) + +### 🎉 New features + +- Youtube Broadcasting ([#10127](https://github.com/RocketChat/Rocket.Chat/pull/10127)) +- REST API endpoints `permissions.list` and `permissions.update`. Deprecated endpoint `permissions` ([#10975](https://github.com/RocketChat/Rocket.Chat/pull/10975) by [@vynmera](https://github.com/vynmera)) +- REST API endpoint `channels.setDefault` ([#10941](https://github.com/RocketChat/Rocket.Chat/pull/10941) by [@vynmera](https://github.com/vynmera)) +- Set Document Domain property in IFrame ([#9751](https://github.com/RocketChat/Rocket.Chat/pull/9751) by [@kb0304](https://github.com/kb0304)) +- Custom login wallpapers ([#11025](https://github.com/RocketChat/Rocket.Chat/pull/11025) by [@vynmera](https://github.com/vynmera)) +- Support for dynamic slack and rocket.chat channels ([#10205](https://github.com/RocketChat/Rocket.Chat/pull/10205) by [@kable-wilmoth](https://github.com/kable-wilmoth)) +- Add prometheus port config ([#11115](https://github.com/RocketChat/Rocket.Chat/pull/11115) by [@brylie](https://github.com/brylie) & [@stuartpb](https://github.com/stuartpb) & [@thaiphv](https://github.com/thaiphv)) +- Button to remove closed LiveChat rooms ([#10301](https://github.com/RocketChat/Rocket.Chat/pull/10301)) +- Update katex to v0.9.0 ([#8402](https://github.com/RocketChat/Rocket.Chat/pull/8402) by [@pitamar](https://github.com/pitamar)) +- WebDAV(Nextcloud/ownCloud) Storage Server Option ([#11027](https://github.com/RocketChat/Rocket.Chat/pull/11027) by [@karakayasemi](https://github.com/karakayasemi)) +- Don't ask me again checkbox on hide room modal ([#10973](https://github.com/RocketChat/Rocket.Chat/pull/10973)) +- Add input to set time for avatar cache control ([#10958](https://github.com/RocketChat/Rocket.Chat/pull/10958)) +- Command /hide to hide channels ([#10727](https://github.com/RocketChat/Rocket.Chat/pull/10727) by [@mikaelmello](https://github.com/mikaelmello)) +- Do not wait method calls response on websocket before next method call ([#11087](https://github.com/RocketChat/Rocket.Chat/pull/11087)) +- Disconnect users from websocket when away from the login screen for 10min ([#11086](https://github.com/RocketChat/Rocket.Chat/pull/11086)) +- Reduce the amount of DDP API calls on login screen ([#11083](https://github.com/RocketChat/Rocket.Chat/pull/11083)) +- Option to trace Methods and Subscription calls ([#11085](https://github.com/RocketChat/Rocket.Chat/pull/11085)) +- Replace variable 'mergeChannels' with 'groupByType'. ([#10954](https://github.com/RocketChat/Rocket.Chat/pull/10954) by [@mikaelmello](https://github.com/mikaelmello)) +- Send LiveChat visitor navigation history as messages ([#10091](https://github.com/RocketChat/Rocket.Chat/pull/10091)) +- Make supplying an AWS access key and secret optional for S3 uploads ([#10673](https://github.com/RocketChat/Rocket.Chat/pull/10673) by [@saplla](https://github.com/saplla)) +- Direct Reply: separate Reply-To email from account username field ([#10988](https://github.com/RocketChat/Rocket.Chat/pull/10988) by [@pkgodara](https://github.com/pkgodara)) +- Changes all 'mergeChannels' to 'groupByType'. ([#10055](https://github.com/RocketChat/Rocket.Chat/pull/10055) by [@mikaelmello](https://github.com/mikaelmello)) +- Update WeDeploy deployment ([#10841](https://github.com/RocketChat/Rocket.Chat/pull/10841) by [@jonnilundy](https://github.com/jonnilundy)) + +### 🐛 Bug fixes + +- i18n - add semantic markup ([#9534](https://github.com/RocketChat/Rocket.Chat/pull/9534) by [@brylie](https://github.com/brylie)) +- Wordpress oauth configuration not loading properly ([#11187](https://github.com/RocketChat/Rocket.Chat/pull/11187)) +- REST API: Add more test cases for `/login` ([#10999](https://github.com/RocketChat/Rocket.Chat/pull/10999)) +- Wrong font-family order ([#11191](https://github.com/RocketChat/Rocket.Chat/pull/11191) by [@myfonj](https://github.com/myfonj)) +- REST endpoint `users.updateOwnBasicInfo` was not returning errors for invalid names and trying to save custom fields when empty ([#11204](https://github.com/RocketChat/Rocket.Chat/pull/11204)) +- Livechat visitor not being prompted for transcript when himself is closing the chat ([#10767](https://github.com/RocketChat/Rocket.Chat/pull/10767)) +- HipChat Cloud import fails to import rooms ([#11188](https://github.com/RocketChat/Rocket.Chat/pull/11188)) +- Failure to download user data ([#11190](https://github.com/RocketChat/Rocket.Chat/pull/11190)) +- Add parameter to REST chat.react endpoint, to make it work like a setter ([#10447](https://github.com/RocketChat/Rocket.Chat/pull/10447)) +- Default selected language ([#11150](https://github.com/RocketChat/Rocket.Chat/pull/11150)) +- Rendering of emails and mentions in messages ([#11165](https://github.com/RocketChat/Rocket.Chat/pull/11165)) +- Livechat icon with status ([#11177](https://github.com/RocketChat/Rocket.Chat/pull/11177)) +- remove sidebar on embedded view ([#11183](https://github.com/RocketChat/Rocket.Chat/pull/11183)) +- Missing language constants ([#11173](https://github.com/RocketChat/Rocket.Chat/pull/11173) by [@rw4lll](https://github.com/rw4lll)) +- Room creation error due absence of subscriptions ([#11178](https://github.com/RocketChat/Rocket.Chat/pull/11178)) +- Remove failed upload messages when switching rooms ([#11132](https://github.com/RocketChat/Rocket.Chat/pull/11132)) +- Wordpress OAuth not providing enough info to log in ([#11152](https://github.com/RocketChat/Rocket.Chat/pull/11152)) +- /groups.invite not allow a user to invite even with permission ([#11010](https://github.com/RocketChat/Rocket.Chat/pull/11010)) +- Various lang fixes [RU] ([#10095](https://github.com/RocketChat/Rocket.Chat/pull/10095) by [@rw4lll](https://github.com/rw4lll)) +- set-toolbar-items postMessage ([#11109](https://github.com/RocketChat/Rocket.Chat/pull/11109)) +- title and value attachments are optionals on sendMessage method ([#11021](https://github.com/RocketChat/Rocket.Chat/pull/11021)) +- Some typos in the error message names ([#11136](https://github.com/RocketChat/Rocket.Chat/pull/11136) by [@vynmera](https://github.com/vynmera)) +- open conversation from room info ([#11050](https://github.com/RocketChat/Rocket.Chat/pull/11050)) +- Users model was not receiving options ([#11129](https://github.com/RocketChat/Rocket.Chat/pull/11129)) +- Popover position ([#11113](https://github.com/RocketChat/Rocket.Chat/pull/11113)) +- Generated random password visible to the user ([#11096](https://github.com/RocketChat/Rocket.Chat/pull/11096)) +- LiveChat appearance changes not being saved ([#11111](https://github.com/RocketChat/Rocket.Chat/pull/11111)) +- Confirm password on set new password user profile ([#11095](https://github.com/RocketChat/Rocket.Chat/pull/11095)) +- Message_AllowedMaxSize fails for emoji sequences ([#10431](https://github.com/RocketChat/Rocket.Chat/pull/10431) by [@c0dzilla](https://github.com/c0dzilla)) +- Can't access the `/account/profile` ([#11089](https://github.com/RocketChat/Rocket.Chat/pull/11089)) +- Idle time limit wasn’t working as expected ([#11084](https://github.com/RocketChat/Rocket.Chat/pull/11084)) +- Rooms list sorting by activity multiple re-renders and case sensitive sorting alphabetically ([#9959](https://github.com/RocketChat/Rocket.Chat/pull/9959) by [@JoseRenan](https://github.com/JoseRenan)) +- Notification not working for group mentions and not respecting ignored users ([#11024](https://github.com/RocketChat/Rocket.Chat/pull/11024)) +- Overlapping of search text and cancel search icon (X) ([#10294](https://github.com/RocketChat/Rocket.Chat/pull/10294) by [@taeven](https://github.com/taeven)) +- Link previews not being removed from messages after removed on editing ([#11063](https://github.com/RocketChat/Rocket.Chat/pull/11063)) +- avoid send presence without login ([#11074](https://github.com/RocketChat/Rocket.Chat/pull/11074)) +- Exception in metrics generation ([#11072](https://github.com/RocketChat/Rocket.Chat/pull/11072)) +- Build for Sandstorm missing dependence for capnp ([#11056](https://github.com/RocketChat/Rocket.Chat/pull/11056) by [@peterlee0127](https://github.com/peterlee0127)) +- flex-tab icons missing ([#11049](https://github.com/RocketChat/Rocket.Chat/pull/11049)) +- Update ja.i18n.json ([#11020](https://github.com/RocketChat/Rocket.Chat/pull/11020) by [@noobbbbb](https://github.com/noobbbbb)) +- Strange msg when setting room announcement, topic or description to be empty ([#11012](https://github.com/RocketChat/Rocket.Chat/pull/11012) by [@vynmera](https://github.com/vynmera)) +- Exception thrown on avatar validation ([#11009](https://github.com/RocketChat/Rocket.Chat/pull/11009)) +- Preview of large images not resizing to fit the area and having scrollbars ([#10998](https://github.com/RocketChat/Rocket.Chat/pull/10998) by [@vynmera](https://github.com/vynmera)) +- Allow inviting livechat managers to the same LiveChat room ([#10956](https://github.com/RocketChat/Rocket.Chat/pull/10956)) +- Cannot read property 'debug' of undefined when trying to use REST API ([#10805](https://github.com/RocketChat/Rocket.Chat/pull/10805) by [@haffla](https://github.com/haffla)) +- Icons svg xml structure ([#10771](https://github.com/RocketChat/Rocket.Chat/pull/10771)) +- Leave room wasn't working as expected ([#10851](https://github.com/RocketChat/Rocket.Chat/pull/10851)) +- Application crashing on startup when trying to log errors to `exceptions` channel ([#10934](https://github.com/RocketChat/Rocket.Chat/pull/10934)) +- Image lazy load was breaking attachments ([#10904](https://github.com/RocketChat/Rocket.Chat/pull/10904)) +- Incomplete email notification link ([#10928](https://github.com/RocketChat/Rocket.Chat/pull/10928)) +- Remove outdated 2FA warning for mobile clients ([#10916](https://github.com/RocketChat/Rocket.Chat/pull/10916)) +- Update Sandstorm build config ([#10867](https://github.com/RocketChat/Rocket.Chat/pull/10867) by [@ocdtrekkie](https://github.com/ocdtrekkie)) +- i18n - add semantic markup ([#9534](https://github.com/RocketChat/Rocket.Chat/pull/9534) by [@brylie](https://github.com/brylie)) +- "blank messages" on iOS < 11 ([#11221](https://github.com/RocketChat/Rocket.Chat/pull/11221)) +- "blank" screen on iOS < 11 ([#11199](https://github.com/RocketChat/Rocket.Chat/pull/11199)) +- The process was freezing in some cases when HTTP calls exceeds timeout on integrations ([#11253](https://github.com/RocketChat/Rocket.Chat/pull/11253)) +- LDAP was accepting login with empty passwords for certain AD configurations ([#11264](https://github.com/RocketChat/Rocket.Chat/pull/11264)) +- Update capnproto dependence for Sandstorm Build ([#11263](https://github.com/RocketChat/Rocket.Chat/pull/11263) by [@peterlee0127](https://github.com/peterlee0127)) +- Internal Server Error on first login with CAS integration ([#11257](https://github.com/RocketChat/Rocket.Chat/pull/11257)) +- Armhf snap build ([#11268](https://github.com/RocketChat/Rocket.Chat/pull/11268)) +- Reaction Toggle was not working when omitting the last parameter from the API (DDP and REST) ([#11276](https://github.com/RocketChat/Rocket.Chat/pull/11276)) + +
+🔍 Minor changes + +- Merge master into develop & Set version to 0.66.0-develop ([#11277](https://github.com/RocketChat/Rocket.Chat/pull/11277) by [@brylie](https://github.com/brylie) & [@stuartpb](https://github.com/stuartpb)) +- [IMPROVE] Listing of apps in the admin page ([#11166](https://github.com/RocketChat/Rocket.Chat/pull/11166)) +- Regression: Directory css ([#11206](https://github.com/RocketChat/Rocket.Chat/pull/11206)) +- LingoHub based on develop ([#11208](https://github.com/RocketChat/Rocket.Chat/pull/11208)) +- IRC Federation: RFC2813 implementation (ngIRCd) ([#10113](https://github.com/RocketChat/Rocket.Chat/pull/10113) by [@cpitman](https://github.com/cpitman) & [@lindoelio](https://github.com/lindoelio)) +- Add verification to make sure the user exists in REST insert object helper ([#11008](https://github.com/RocketChat/Rocket.Chat/pull/11008)) +- Regression: Directory user table infinite scroll doesn't working ([#11200](https://github.com/RocketChat/Rocket.Chat/pull/11200)) +- [IMPROVE] UI design for Tables and tabs component on Directory ([#11026](https://github.com/RocketChat/Rocket.Chat/pull/11026)) +- [FIX Readme] Nodejs + Python version spicifications ([#11181](https://github.com/RocketChat/Rocket.Chat/pull/11181) by [@mahdiyari](https://github.com/mahdiyari)) +- Regression: sorting direct message by asc on favorites group ([#11090](https://github.com/RocketChat/Rocket.Chat/pull/11090)) +- [IMPROVE] User mentions ([#11001](https://github.com/RocketChat/Rocket.Chat/pull/11001) by [@vynmera](https://github.com/vynmera)) +- Fix PR Docker image creation by splitting in two build jobs ([#11107](https://github.com/RocketChat/Rocket.Chat/pull/11107)) +- Update v126.js ([#11103](https://github.com/RocketChat/Rocket.Chat/pull/11103)) +- Speed up the build time by removing JSON Minify from i18n package ([#11097](https://github.com/RocketChat/Rocket.Chat/pull/11097)) +- Fix Docker image for develop commits ([#11093](https://github.com/RocketChat/Rocket.Chat/pull/11093)) +- Build Docker image on CI ([#11076](https://github.com/RocketChat/Rocket.Chat/pull/11076)) +- Update issue templates ([#11070](https://github.com/RocketChat/Rocket.Chat/pull/11070)) +- LingoHub based on develop ([#11062](https://github.com/RocketChat/Rocket.Chat/pull/11062)) +- LingoHub based on develop ([#11054](https://github.com/RocketChat/Rocket.Chat/pull/11054)) +- LingoHub based on develop ([#11053](https://github.com/RocketChat/Rocket.Chat/pull/11053)) +- LingoHub based on develop ([#11051](https://github.com/RocketChat/Rocket.Chat/pull/11051)) +- LingoHub based on develop ([#11045](https://github.com/RocketChat/Rocket.Chat/pull/11045)) +- LingoHub based on develop ([#11044](https://github.com/RocketChat/Rocket.Chat/pull/11044)) +- LingoHub based on develop ([#11043](https://github.com/RocketChat/Rocket.Chat/pull/11043)) +- LingoHub based on develop ([#11042](https://github.com/RocketChat/Rocket.Chat/pull/11042)) +- Changed 'confirm password' placeholder text on user registration form ([#9969](https://github.com/RocketChat/Rocket.Chat/pull/9969) by [@kumarnitj](https://github.com/kumarnitj)) +- LingoHub based on develop ([#11039](https://github.com/RocketChat/Rocket.Chat/pull/11039)) +- LingoHub based on develop ([#11035](https://github.com/RocketChat/Rocket.Chat/pull/11035)) +- Update Documentation: README.md ([#10207](https://github.com/RocketChat/Rocket.Chat/pull/10207) by [@rakhi2104](https://github.com/rakhi2104)) +- NPM Dependencies Update ([#10913](https://github.com/RocketChat/Rocket.Chat/pull/10913)) +- update meteor to 1.6.1 for sandstorm build ([#10131](https://github.com/RocketChat/Rocket.Chat/pull/10131) by [@peterlee0127](https://github.com/peterlee0127)) +- Renaming username.username to username.value for clarity ([#10986](https://github.com/RocketChat/Rocket.Chat/pull/10986)) +- Fix readme typo ([#5](https://github.com/RocketChat/Rocket.Chat/pull/5)) +- Remove wrong and not needed time unit ([#10807](https://github.com/RocketChat/Rocket.Chat/pull/10807) by [@cliffparnitzky](https://github.com/cliffparnitzky)) +- Develop sync commits ([#10909](https://github.com/RocketChat/Rocket.Chat/pull/10909) by [@nsuchy](https://github.com/nsuchy)) +- Develop sync2 ([#10908](https://github.com/RocketChat/Rocket.Chat/pull/10908) by [@nsuchy](https://github.com/nsuchy)) +- Merge master into develop & Set version to 0.66.0-develop ([#10903](https://github.com/RocketChat/Rocket.Chat/pull/10903) by [@nsuchy](https://github.com/nsuchy)) +- Regression: Fix directory table loading ([#11223](https://github.com/RocketChat/Rocket.Chat/pull/11223)) +- Regression: Fix latest and release-candidate docker images building ([#11215](https://github.com/RocketChat/Rocket.Chat/pull/11215)) +- Regression: check username or usersCount on browseChannels ([#11216](https://github.com/RocketChat/Rocket.Chat/pull/11216)) +- Regression: Sending message with a mention is not showing to sender ([#11211](https://github.com/RocketChat/Rocket.Chat/pull/11211)) +- Regression: Prometheus was not being enabled in some cases ([#11249](https://github.com/RocketChat/Rocket.Chat/pull/11249)) +- Regression: Skip operations if no actions on livechat migration ([#11232](https://github.com/RocketChat/Rocket.Chat/pull/11232)) +- Regression: Directory sort users, fix null results, text for empty results ([#11224](https://github.com/RocketChat/Rocket.Chat/pull/11224)) +- LingoHub based on develop ([#11246](https://github.com/RocketChat/Rocket.Chat/pull/11246)) +- Update Meteor to 1.6.1.3 ([#11247](https://github.com/RocketChat/Rocket.Chat/pull/11247)) +- New history source format & add Node and NPM versions ([#11237](https://github.com/RocketChat/Rocket.Chat/pull/11237)) +- Add Dockerfile with MongoDB ([#10971](https://github.com/RocketChat/Rocket.Chat/pull/10971)) +- Regression: sidebar sorting was being wrong in some cases where the rooms records were returned before the subscriptions ([#11273](https://github.com/RocketChat/Rocket.Chat/pull/11273)) +- Fix Docker image build on tags ([#11271](https://github.com/RocketChat/Rocket.Chat/pull/11271)) + +
+ +### 👩‍💻👨‍💻 Contributors 😍 + +- [@JoseRenan](https://github.com/JoseRenan) +- [@brylie](https://github.com/brylie) +- [@c0dzilla](https://github.com/c0dzilla) +- [@cliffparnitzky](https://github.com/cliffparnitzky) +- [@cpitman](https://github.com/cpitman) +- [@haffla](https://github.com/haffla) +- [@jonnilundy](https://github.com/jonnilundy) +- [@kable-wilmoth](https://github.com/kable-wilmoth) +- [@karakayasemi](https://github.com/karakayasemi) +- [@kb0304](https://github.com/kb0304) +- [@kumarnitj](https://github.com/kumarnitj) +- [@lindoelio](https://github.com/lindoelio) +- [@mahdiyari](https://github.com/mahdiyari) +- [@mikaelmello](https://github.com/mikaelmello) +- [@myfonj](https://github.com/myfonj) +- [@noobbbbb](https://github.com/noobbbbb) +- [@nsuchy](https://github.com/nsuchy) +- [@ocdtrekkie](https://github.com/ocdtrekkie) +- [@peterlee0127](https://github.com/peterlee0127) +- [@pitamar](https://github.com/pitamar) +- [@pkgodara](https://github.com/pkgodara) +- [@rakhi2104](https://github.com/rakhi2104) +- [@rw4lll](https://github.com/rw4lll) +- [@saplla](https://github.com/saplla) +- [@stuartpb](https://github.com/stuartpb) +- [@taeven](https://github.com/taeven) +- [@thaiphv](https://github.com/thaiphv) +- [@vynmera](https://github.com/vynmera) + +### 👩‍💻👨‍💻 Core Team 🤓 + +- [@Hudell](https://github.com/Hudell) +- [@MarcosSpessatto](https://github.com/MarcosSpessatto) +- [@alansikora](https://github.com/alansikora) +- [@cardoso](https://github.com/cardoso) +- [@engelgabriel](https://github.com/engelgabriel) +- [@filipealva](https://github.com/filipealva) +- [@gdelavald](https://github.com/gdelavald) +- [@geekgonecrazy](https://github.com/geekgonecrazy) +- [@ggazzo](https://github.com/ggazzo) +- [@graywolf336](https://github.com/graywolf336) +- [@karlprieb](https://github.com/karlprieb) +- [@rafaelks](https://github.com/rafaelks) +- [@renatobecker](https://github.com/renatobecker) +- [@rodrigok](https://github.com/rodrigok) +- [@sampaiodiego](https://github.com/sampaiodiego) +- [@tassoevan](https://github.com/tassoevan) +- [@timkinnane](https://github.com/timkinnane) + # 0.65.2 `2018-06-16 · 1 🐛 · 1 🔍 · 4 👩‍💻👨‍💻` diff --git a/package-lock.json b/package-lock.json index e696dd348d37..1587fdbdda34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Rocket.Chat", - "version": "0.66.0-develop", + "version": "0.67.0-develop", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -742,7 +742,7 @@ "autolinker": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-1.6.2.tgz", - "integrity": "sha1-Z66donLoCODY644Cy8jN4wOUdFc=" + "integrity": "sha512-IKLGtYFb3jzGTtgCpb4bm//1sXmmmgmr0msKshhYoc7EsWmLCFvuyxLcEIfcZ5gbCgZGXrnXkOkcBblOFEnlog==" }, "autoprefixer": { "version": "8.6.0", @@ -2957,7 +2957,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -3002,7 +3002,7 @@ "mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha1-fYbPvPNcuCnidUwy4XNV7AUzh5Q=", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "requires": { "browser-stdout": "1.3.0", @@ -3020,13 +3020,13 @@ "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha1-FXFS/R56bI2YpbcVzzdt+SgARWM=", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -3054,7 +3054,7 @@ "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha1-iD992rwWUUKyphQn8zUt7RldGj4=", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "2.0.0" @@ -4024,6 +4024,14 @@ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "dbly-linked-list": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dbly-linked-list/-/dbly-linked-list-0.2.0.tgz", + "integrity": "sha512-Ool7y15f6JRDs0YKx7Dh9uiTb1jS1SZLNdT3Y2q16DlaEghXbMsmODS/XittjR2xztt1gJUpz7jVxpqAPF8VGg==", + "requires": { + "lodash.isequal": "4.5.0" + } + }, "ddp-ejson": { "version": "0.8.1-3", "resolved": "https://registry.npmjs.org/ddp-ejson/-/ddp-ejson-0.8.1-3.tgz", @@ -6218,7 +6226,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -8178,7 +8186,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-retry-allowed": { @@ -8753,6 +8761,11 @@ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -8776,7 +8789,7 @@ "lodash.merge": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha1-rcJdnLmbk5HFliTzefu6YNcRHVQ=" + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" }, "lodash.once": { "version": "4.1.1", @@ -8944,7 +8957,7 @@ "mailsplit": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-4.1.2.tgz", - "integrity": "sha1-xhi8MRpM/IOyJqHtwbUD9akk0IM=", + "integrity": "sha512-5UWjUfhKlC4OR5PqZKcl4h7vnz2EP4M3Zg2SBbrztvAYX5lM/rA7tvaXkZ6zRcvK32Uul0GkRA037icDbiJIOw==", "requires": { "libbase64": "1.0.2", "libmime": "3.1.0", @@ -8954,7 +8967,7 @@ "libbase64": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.0.2.tgz", - "integrity": "sha1-L/E//mmx5AFZ9JNo4w0N2LsWNbU=" + "integrity": "sha512-CyPjvTFbsGps2Sdvy9GVjSRPvUGpji8Hxb+iunp466guzxcd3QaK0k8Hur1sPkgD9FonW8V1z2F1y066YiliEg==" } } }, @@ -9195,7 +9208,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "1.1.11" } @@ -9601,7 +9614,7 @@ "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "requires": { "are-we-there-yet": "1.1.5", "console-control-strings": "1.1.0", @@ -10006,7 +10019,7 @@ "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha1-zvMdyOCho7sNEFwM2Xzzv0f0428=", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "requires": { "pify": "3.0.0" } @@ -10338,7 +10351,7 @@ "postcss-import": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", - "integrity": "sha1-Vck2LJGSmU7GiGXSJEGd8dspgfA=", + "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", "dev": true, "requires": { "postcss": "6.0.22", @@ -10387,7 +10400,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { @@ -11275,6 +11288,14 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=" }, + "queue-fifo": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/queue-fifo/-/queue-fifo-0.2.5.tgz", + "integrity": "sha512-GrHy3RDy0BOEVjelr+htts/QJyZAJr+7m4TisCA+RlUSsegQT6EGOf+NyxLDhSRflFI5vq3aADFOR/tNZCasxg==", + "requires": { + "dbly-linked-list": "0.2.0" + } + }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -11814,7 +11835,7 @@ "retry-request": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-3.3.1.tgz", - "integrity": "sha1-+3EnYjWmF+l1Uem+c3q1uRWR+54=", + "integrity": "sha512-PjAmtWIxjNj4Co/6FRtBl8afRP3CxrrIAnUzb1dzydfROd+6xt7xAebFeskgQgkfFf8NmzrXIoaB3HxmswXyxw==", "requires": { "request": "2.87.0", "through2": "2.0.3" @@ -13014,7 +13035,7 @@ "stylelint-order": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-0.8.1.tgz", - "integrity": "sha1-Nfca86FZVBVODpnlZGuj1vvjT40=", + "integrity": "sha512-8mp1P2wnI9XShYXVXDsxVigE2eXnc0C2O4ktbwUvTBwjCP4xZskIbUVxp1evSG3OK4R7hXVNl/2BnJCZkrcc/w==", "dev": true, "requires": { "lodash": "4.17.10", @@ -13062,7 +13083,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "supports-color": { @@ -13632,7 +13653,7 @@ "uc.micro": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz", - "integrity": "sha1-DGXxX4FaoItWCmHOi023/8P0U3Y=" + "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==" }, "uglify-js": { "version": "2.8.29", @@ -14429,7 +14450,7 @@ "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha1-aGwg8hMgnpSr8NG88e+qKRx4J6c=", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "requires": { "sax": "1.2.1", "xmlbuilder": "9.0.7" diff --git a/package.json b/package.json index d1a92a39f1dc..1d369b2de64f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Rocket.Chat", "description": "The Ultimate Open Source WebChat Platform", - "version": "0.66.0-develop", + "version": "0.67.0-develop", "author": { "name": "Rocket.Chat", "url": "https://rocket.chat/" diff --git a/packages/meteor-accounts-saml/saml_utils.js b/packages/meteor-accounts-saml/saml_utils.js index e1274111ba67..d749f02e9ddc 100644 --- a/packages/meteor-accounts-saml/saml_utils.js +++ b/packages/meteor-accounts-saml/saml_utils.js @@ -395,8 +395,7 @@ SAML.prototype.validateResponse = function(samlResponse, relayState, callback) { if (attributes) { attributes.forEach(function(attribute) { const value = self.getElement(attribute, 'AttributeValue'); - let key = attribute.$.Name.value; - key=key.replace(/\./g, '-'); + const key = attribute.$.Name.value; if (typeof value[0] === 'string') { profile[key] = value[0]; } else { @@ -422,6 +421,16 @@ SAML.prototype.validateResponse = function(samlResponse, relayState, callback) { console.log(`NameID: ${ JSON.stringify(profile) }`); } + const profileKeys = Object.keys(profile); + for (let i = 0; i < profileKeys.length; i++) { + const key = profileKeys[i]; + + if (key.match(/\./)) { + profile[key.replace(/\./g, '-')] = profile[key]; + delete profile[key]; + } + } + callback(null, profile, false); } else { const logoutResponse = self.getElement(doc, 'LogoutResponse'); diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.html b/packages/rocketchat-channel-settings/client/views/channelSettings.html index 5ac205f7eda4..1aac833d775b 100644 --- a/packages/rocketchat-channel-settings/client/views/channelSettings.html +++ b/packages/rocketchat-channel-settings/client/views/channelSettings.html @@ -94,7 +94,7 @@
- {{_ "Colaborative"}}{{equal default value '*'}} + {{_ "Collaborative"}}{{equal default value '*'}}
{{_ "All_users_in_the_channel_can_write_new_messages"}}
diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 622e715153ff..96b4e6c56eee 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -234,6 +234,7 @@ "Allow_Invalid_SelfSigned_Certs": "Allow Invalid Self-Signed Certs", "Allow_Invalid_SelfSigned_Certs_Description": "Allow invalid and self-signed SSL certificate's for link validation and previews.", "Allow_switching_departments": "Allow Visitor to Switch Departments", + "Allow_Marketing_Emails": "Allow Marketing Emails", "Alphabetical": "Alphabetical", "Always_open_in_new_window": "Always Open in New Window", "Analytics_features_enabled": "Features Enabled", @@ -1370,6 +1371,7 @@ "InternalHubot_Username_Description": "This must be a valid username of a bot registered on your server.", "Invalid_confirm_pass": "The password confirmation does not match password", "Invalid_email": "The email entered is invalid", + "Invalid_username": "The username entered is invalid", "Invalid_Export_File": "The file uploaded isn't a valid %s export file.", "Invalid_Import_File_Type": "Invalid Import file type.", "Invalid_name": "The name must not be empty", @@ -1499,6 +1501,8 @@ "LDAP_Enable_Description": "Attempt to utilize LDAP for authentication.", "LDAP_Encryption": "Encryption", "LDAP_Encryption_Description": "The encryption method used to secure communications to the LDAP server. Examples include `plain` (no encryption), `SSL/LDAPS` (encrypted from the start), and `StartTLS` (upgrade to encrypted communication once connected).", + "LDAP_Find_User_After_Login": "Find user after login", + "LDAP_Find_User_After_Login_Description": "Will perform a search of the user's DN after bind to ensure the bind was successful preventing login with empty passwords when allowed by the AD configuration.", "LDAP_Group_Filter_Enable": "Enable LDAP User Group Filter", "LDAP_Group_Filter_Enable_Description": "Restrict access to users in a LDAP group
Useful for OpenLDAP servers without overlays that not permit *memberOf* filter", "LDAP_Group_Filter_Group_Id_Attribute": "Group ID Attribute", @@ -2033,6 +2037,17 @@ "Regenerate_codes": "Regenerate codes", "Register": "Register a new account", "Register_Server": "Register Server", + "Register_Server_Info": "Use the preconfigured gateways and proxies provided by Rocket.Chat Technologies Corp.", + "Register_Server_Registered": "Register to access", + "Register_Server_Registered_Push_Notifications": "Mobile push notifications gateway", + "Register_Server_Registered_Livechat": "Livechat omnichannel proxy", + "Register_Server_Registered_OAuth": "OAuth proxy for social network", + "Register_Server_Registered_Marketplace": "Apps Marketplace", + "Register_Server_Opt_In": "Newsletter, offers and product updates", + "Register_Server_Standalone": "Keep standalone, you'll need to", + "Register_Server_Standalone_Service_Providers": "Create accounts with service providers", + "Register_Server_Standalone_Update_Settings": "Update the preconfigured settings", + "Register_Server_Standalone_Own_Certificates": "Recompile the mobile apps with your own certificates", "Registration": "Registration", "Registration_Succeeded": "Registration Succeeded", "Registration_via_Admin": "Registration via Admin", @@ -2213,6 +2228,7 @@ "Shared_Location": "Shared Location", "Should_be_a_URL_of_an_image": "Should be a URL of an image.", "Should_exists_a_user_with_this_username": "The user must already exist.", + "Show_Setup_Wizard": "Show Setup Wizard", "Show_agent_email": "Show agent email", "Show_all": "Show All", "Show_Avatars": "Show Avatars", @@ -2738,4 +2754,4 @@ "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices", "Your_server_link": "Your server link", "Your_workspace_is_ready": "Your workspace is ready to use 🎉" -} \ No newline at end of file +} diff --git a/packages/rocketchat-integrations/server/api/api.js b/packages/rocketchat-integrations/server/api/api.js index bbd9efa92b63..2d78933c2274 100644 --- a/packages/rocketchat-integrations/server/api/api.js +++ b/packages/rocketchat-integrations/server/api/api.js @@ -1,6 +1,8 @@ /* globals Meteor Restivus logger processWebhookMessage*/ // TODO: remove globals +import Fiber from 'fibers'; +import Future from 'fibers/future'; import _ from 'underscore'; import s from 'underscore.string'; import vm from 'vm'; @@ -60,10 +62,15 @@ const Api = new Restivus({ const compiledScripts = {}; function buildSandbox(store = {}) { const sandbox = { + scriptTimeout(reject) { + return setTimeout(() => reject('timed out'), 3000); + }, _, s, console, moment, + Fiber, + Promise, Livechat: RocketChat.Livechat, Store: { set(key, val) { @@ -236,9 +243,20 @@ function executeIntegrationRest() { sandbox.script = script; sandbox.request = request; - const result = vm.runInNewContext('script.process_incoming_request({ request: request })', sandbox, { + const result = Future.fromPromise(vm.runInNewContext(` + new Promise((resolve, reject) => { + Fiber(() => { + scriptTimeout(reject); + try { + resolve(script.process_incoming_request({ request: request })); + } catch(e) { + reject(e); + } + }).run(); + }).catch((error) => { throw new Error(error); }); + `, sandbox, { timeout: 3000 - }); + })).wait(); if (!result) { logger.incoming.debug('[Process Incoming Request result of Trigger', this.integration.name, ':] No data'); diff --git a/packages/rocketchat-integrations/server/lib/triggerHandler.js b/packages/rocketchat-integrations/server/lib/triggerHandler.js index 887fada828bb..36a9b4777634 100644 --- a/packages/rocketchat-integrations/server/lib/triggerHandler.js +++ b/packages/rocketchat-integrations/server/lib/triggerHandler.js @@ -3,6 +3,8 @@ import _ from 'underscore'; import s from 'underscore.string'; import moment from 'moment'; import vm from 'vm'; +import Fiber from 'fibers'; +import Future from 'fibers/future'; RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler { constructor() { @@ -202,7 +204,15 @@ RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler buildSandbox(store = {}) { const sandbox = { - _, s, console, moment, + scriptTimeout(reject) { + return setTimeout(() => reject('timed out'), 3000); + }, + _, + s, + console, + moment, + Fiber, + Promise, Store: { set: (key, val) => store[key] = val, get: (key) => store[key] @@ -303,7 +313,21 @@ RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler sandbox.params = params; this.updateHistory({ historyId, step: `execute-script-before-running-${ method }` }); - const result = this.vm.runInNewContext('script[method](params)', sandbox, { timeout: 3000 }); + + const result = Future.fromPromise(this.vm.runInNewContext(` + new Promise((resolve, reject) => { + Fiber(() => { + scriptTimeout(reject); + try { + resolve(script[method](params)) + } catch(e) { + reject(e); + } + }).run(); + }).catch((error) => { throw new Error(error); }); + `, sandbox, { + timeout: 3000 + })).wait(); logger.outgoing.debug(`Script method "${ method }" result of the Integration "${ integration.name }" is:`); logger.outgoing.debug(result); diff --git a/packages/rocketchat-ldap/server/ldap.js b/packages/rocketchat-ldap/server/ldap.js index 894d00264bed..0f48a486ffc0 100644 --- a/packages/rocketchat-ldap/server/ldap.js +++ b/packages/rocketchat-ldap/server/ldap.js @@ -41,7 +41,8 @@ export default class LDAP { group_filter_group_id_attribute: RocketChat.settings.get('LDAP_Group_Filter_Group_Id_Attribute'), group_filter_group_member_attribute: RocketChat.settings.get('LDAP_Group_Filter_Group_Member_Attribute'), group_filter_group_member_format: RocketChat.settings.get('LDAP_Group_Filter_Group_Member_Format'), - group_filter_group_name: RocketChat.settings.get('LDAP_Group_Filter_Group_Name') + group_filter_group_name: RocketChat.settings.get('LDAP_Group_Filter_Group_Name'), + find_user_after_login: RocketChat.settings.get('LDAP_Find_User_After_Login') }; } @@ -479,6 +480,16 @@ export default class LDAP { try { this.bindSync(dn, password); + if (this.options.find_user_after_login) { + const searchOptions = { + scope: this.options.User_Search_Scope || 'sub' + }; + const result = this.searchAllSync(dn, searchOptions); + if (result.length === 0) { + logger.auth.info('Bind successful but user was not found via search', dn, searchOptions); + return false; + } + } logger.auth.info('Authenticated', dn); return true; } catch (error) { diff --git a/packages/rocketchat-ldap/server/loginHandler.js b/packages/rocketchat-ldap/server/loginHandler.js index 85fbdd87fe0f..b7fc71589fe7 100644 --- a/packages/rocketchat-ldap/server/loginHandler.js +++ b/packages/rocketchat-ldap/server/loginHandler.js @@ -126,7 +126,7 @@ Accounts.registerLoginHandler('ldap', function(loginRequest) { syncUserData(user, ldapUser); - if (RocketChat.settings.get('LDAP_Login_Fallback') === true) { + if (RocketChat.settings.get('LDAP_Login_Fallback') === true && typeof loginRequest.ldapPass === 'string' && loginRequest.ldapPass.trim() !== '') { Accounts.setPassword(user._id, loginRequest.ldapPass, {logout: false}); } diff --git a/packages/rocketchat-ldap/server/settings.js b/packages/rocketchat-ldap/server/settings.js index b51d0549f2c5..df61a2ad5fea 100644 --- a/packages/rocketchat-ldap/server/settings.js +++ b/packages/rocketchat-ldap/server/settings.js @@ -23,6 +23,7 @@ RocketChat.settings.addGroup('LDAP', function() { this.add('LDAP_Enable', false, { type: 'boolean', public: true }); this.add('LDAP_Login_Fallback', true, { type: 'boolean', enableQuery }); + this.add('LDAP_Find_User_After_Login', true, { type: 'boolean', enableQuery }); this.add('LDAP_Host', '', { type: 'string', enableQuery }); this.add('LDAP_Port', '389', { type: 'string', enableQuery }); this.add('LDAP_Reconnect', false, { type: 'boolean', enableQuery }); diff --git a/packages/rocketchat-lib/rocketchat.info b/packages/rocketchat-lib/rocketchat.info index d9571c35a9b1..301d768313e5 100644 --- a/packages/rocketchat-lib/rocketchat.info +++ b/packages/rocketchat-lib/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "0.66.0-develop" + "version": "0.67.0-develop" } diff --git a/packages/rocketchat-lib/server/models/_BaseDb.js b/packages/rocketchat-lib/server/models/_BaseDb.js index 60dee3248d2b..b93f3e917701 100644 --- a/packages/rocketchat-lib/server/models/_BaseDb.js +++ b/packages/rocketchat-lib/server/models/_BaseDb.js @@ -160,7 +160,7 @@ class ModelsBaseDb extends EventEmitter { } updateHasPositionalOperator(update) { - return Object.keys(update).some(key => key.includes('.$') || (!Match.test(update[key], Object) && this.updateHasPositionalOperator(update[key]))); + return Object.keys(update).some(key => key.includes('.$') || (Match.test(update[key], Object) && this.updateHasPositionalOperator(update[key]))); } processOplogRecord(action) { diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 4d8a0e329f3f..cd870f383ef4 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -2902,6 +2902,9 @@ RocketChat.settings.addGroup('Setup_Wizard', function() { order: 2 } }); + this.add('Allow_Marketing_Emails', true, { + type: 'boolean' + }); }); }); diff --git a/packages/rocketchat-livestream/client/views/liveStreamView.html b/packages/rocketchat-livestream/client/views/liveStreamView.html index 43bec7b18288..765b2b52bcf7 100644 --- a/packages/rocketchat-livestream/client/views/liveStreamView.html +++ b/packages/rocketchat-livestream/client/views/liveStreamView.html @@ -1,15 +1,5 @@ diff --git a/packages/rocketchat-reactions/setReaction.js b/packages/rocketchat-reactions/setReaction.js index 2cf5a8c7bdc7..cdbb3f3f334c 100644 --- a/packages/rocketchat-reactions/setReaction.js +++ b/packages/rocketchat-reactions/setReaction.js @@ -47,7 +47,12 @@ Meteor.methods({ return false; } - const userAlreadyReacted = Boolean(message.reactions) && message.reactions[reaction] && message.reactions[reaction].usernames.indexOf(user.username) !== -1; + const userAlreadyReacted = Boolean(message.reactions) && Boolean(message.reactions[reaction]) && message.reactions[reaction].usernames.indexOf(user.username) !== -1; + // When shouldReact was not informed, toggle the reaction. + if (shouldReact === undefined) { + shouldReact = !userAlreadyReacted; + } + if (userAlreadyReacted === shouldReact) { return; } diff --git a/packages/rocketchat-setup-wizard/client/final.html b/packages/rocketchat-setup-wizard/client/final.html new file mode 100644 index 000000000000..f44289e9b1c5 --- /dev/null +++ b/packages/rocketchat-setup-wizard/client/final.html @@ -0,0 +1,18 @@ + diff --git a/packages/rocketchat-setup-wizard/client/final.js b/packages/rocketchat-setup-wizard/client/final.js new file mode 100644 index 000000000000..3fea0f68212c --- /dev/null +++ b/packages/rocketchat-setup-wizard/client/final.js @@ -0,0 +1,51 @@ +Template.setupWizardFinal.onCreated(function() { + const isSetupWizardDone = localStorage.getItem('wizardFinal'); + if (isSetupWizardDone === null) { + FlowRouter.go('setup-wizard'); + } + + this.autorun(c => { + const showSetupWizard = RocketChat.settings.get('Show_Setup_Wizard'); + if (!showSetupWizard) { + // Setup Wizard state is not defined yet + return; + } + + const userId = Meteor.userId(); + const user = userId && RocketChat.models.Users.findOne(userId, { fields: { status: true } }); + if (userId && (!user || !user.status)) { + // User and its status are not defined yet + return; + } + + c.stop(); + + const isComplete = showSetupWizard === 'completed'; + const noUserLoggedInAndIsNotPending = !userId && showSetupWizard !== 'pending'; + const userIsLoggedButIsNotAdmin = userId && !RocketChat.authz.hasRole(userId, 'admin'); + if (isComplete || noUserLoggedInAndIsNotPending || userIsLoggedButIsNotAdmin) { + FlowRouter.go('home'); + return; + } + }); +}); + +Template.setupWizardFinal.onRendered(function() { + $('#initial-page-loading').remove(); +}); + +Template.setupWizardFinal.events({ + 'click .js-finish'() { + RocketChat.settings.set('Show_Setup_Wizard', 'completed', function() { + localStorage.removeItem('wizard'); + localStorage.removeItem('wizardFinal'); + FlowRouter.go('home'); + }); + } +}); + +Template.setupWizardFinal.helpers({ + siteUrl() { + return RocketChat.settings.get('Site_Url'); + } +}); diff --git a/packages/rocketchat-setup-wizard/client/setupWizard.html b/packages/rocketchat-setup-wizard/client/setupWizard.html index 6f082939f37c..26a4613d4f3b 100644 --- a/packages/rocketchat-setup-wizard/client/setupWizard.html +++ b/packages/rocketchat-setup-wizard/client/setupWizard.html @@ -1,196 +1,214 @@ - - + + + + + + + + diff --git a/packages/rocketchat-setup-wizard/client/setupWizard.js b/packages/rocketchat-setup-wizard/client/setupWizard.js index 445cb3b504c9..715ea2e83518 100644 --- a/packages/rocketchat-setup-wizard/client/setupWizard.js +++ b/packages/rocketchat-setup-wizard/client/setupWizard.js @@ -1,90 +1,135 @@ -import s from 'underscore.string'; +const cannotSetup = () => { + const showSetupWizard = RocketChat.settings.get('Show_Setup_Wizard'); + if (!showSetupWizard) { + // Setup Wizard state is not defined yet + return; + } -const setSettingsAndGo = (settings, registerServer = true) => { - const settingsFilter = Object.entries(settings) - .filter(([key]) => !/registration-|registerServer|currentStep/.test(key)) - .map(([_id, value]) => ({_id, value})); + const userId = Meteor.userId(); + const user = userId && RocketChat.models.Users.findOne(userId, { fields: { status: true } }); + if (userId && (!user || !user.status)) { + // User and its status are not defined yet + return; + } - settingsFilter.push({ - _id: 'Statistics_reporting', - value: registerServer - }); + const isComplete = showSetupWizard === 'completed'; + const noUserLoggedInAndIsNotPending = !userId && showSetupWizard !== 'pending'; + const userIsLoggedButIsNotAdmin = userId && !RocketChat.authz.hasRole(userId, 'admin'); - RocketChat.settings.batchSet(settingsFilter, function(err) { - if (err) { - return handleError(err); + return isComplete || noUserLoggedInAndIsNotPending || userIsLoggedButIsNotAdmin; +}; + +const registerAdminUser = (state, callback) => { + const registrationData = Object.entries(state) + .filter(([ key ]) => /registration-/.test(key)) + .map(([ key, value ]) => ([ key.replace('registration-', ''), value ])) + .reduce((o, [ key, value ]) => ({ ...o, [key]: value }), {}); + + Meteor.call('registerUser', registrationData, error => { + if (error) { + return handleError(error); } - localStorage.setItem('wizardFinal', true); - FlowRouter.go('setup-wizard-final'); + RocketChat.callbacks.run('userRegistered'); + Meteor.loginWithPassword(registrationData.email, registrationData.pass, error => { + if (error) { + if (error.error === 'error-invalid-email') { + toastr.success(t('We_have_sent_registration_email')); + return false; + } else { + return handleError(error); + } + } + + Session.set('forceLogin', false); + Meteor.call('setUsername', registrationData.username, error => { + if (error) { + return handleError(error); + } + + RocketChat.callbacks.run('usernameSet'); + callback && callback(); + }); + }); }); }; -Template.setupWizard.onCreated(function() { - const userId = Meteor.userId(); - - this.autorun((c) => { - const Show_Setup_Wizard = RocketChat.settings.get('Show_Setup_Wizard'); - const user = Meteor.user(); +const persistSettings = (state, callback) => { + const settings = Object.entries(state) + .filter(([ key ]) => !/registration-|registerServer|optIn|currentStep|invalidUsername|invalidEmail/.test(key)) + .map(([ _id, value ]) => ({ _id, value })) + .concat([ + { + _id: 'Statistics_reporting', + value: state['registerServer'] + }, + { + _id: 'Allow_Marketing_Emails', + value: state['optIn'] + } + ]); - // Wait for roles and setup wizard setting - if ((userId && (!user || !user.status)) || !Show_Setup_Wizard) { - return; + RocketChat.settings.batchSet(settings, error => { + if (error) { + return handleError(error); } - c.stop(); - - if ((!userId && Show_Setup_Wizard !== 'pending') || Show_Setup_Wizard === 'completed' || (userId && !RocketChat.authz.hasRole(userId, 'admin'))) { - FlowRouter.go('home'); - } + callback && callback(); }); +}; + +Template.setupWizard.onCreated(function() { + this.state = new ReactiveDict(); + this.state.set('currentStep', 1); + this.state.set('registerServer', true); + this.state.set('optIn', true); + + this.wizardSettings = new ReactiveVar([]); + this.allowStandaloneServer = new ReactiveVar(false); if (localStorage.getItem('wizardFinal')) { FlowRouter.go('setup-wizard-final'); + return; } - this.hasAdmin = new ReactiveVar(false); - this.state = new ReactiveDict(); - this.wizardSettings = new ReactiveVar([]); - this.invalidEmail = new ReactiveVar(false); + const jsonString = localStorage.getItem('wizard'); + const state = jsonString && JSON.parse(jsonString) || {}; + Object.entries(state).forEach(entry => this.state.set(...entry)); - const storage = JSON.parse(localStorage.getItem('wizard')); - if (storage) { - Object.entries(storage).forEach(([key, value]) => { - this.state.set(key, value); - }); - } + this.autorun(c => { + const cantSetup = cannotSetup(); + if (typeof cantSetup === 'undefined') { + return; + } - this.autorun(() => { - const user = Meteor.user(); - if (user) { - if (!this.hasAdmin.get()) { - if (user.roles && user.roles.includes('admin')) { - this.state.set('currentStep', 2); - this.hasAdmin.set(true); - } else { - this.hasAdmin.set(false); - } - } + if (cantSetup) { + c.stop(); + FlowRouter.go('home'); + return; + } + + const state = this.state.all(); + state['registration-pass'] = ''; + localStorage.setItem('wizard', JSON.stringify(state)); - Meteor.call('getWizardSettings', (error, result) => { + if (Meteor.userId()) { + Meteor.call('getSetupWizardParameters', (error, { settings, allowStandaloneServer }) => { if (error) { return handleError(error); } - this.wizardSettings.set(result); + this.wizardSettings.set(settings); + this.allowStandaloneServer.set(allowStandaloneServer); }); - } else { - this.state.set('currentStep', 1); - } - if (RocketChat.settings.get('Show_Setup_Wizard') === 'completed') { - FlowRouter.go('home'); + if (this.state.get('currentStep') === 1) { + this.state.set('currentStep', 2); + } else { + this.state.set('registration-pass', ''); + } + } else if (this.state.get('currentStep') !== 1) { + this.state.set('currentStep', 1); } - - const states = this.state.all(); - states['registration-pass'] = ''; - localStorage.setItem('wizard', JSON.stringify(states)); }); }); @@ -93,67 +138,83 @@ Template.setupWizard.onRendered(function() { }); Template.setupWizard.events({ + 'submit .setup-wizard-forms__box'() { + return false; + }, 'click .setup-wizard-forms__footer-next'(e, t) { - const currentStep = t.state.get('currentStep'); - const hasAdmin = t.hasAdmin.get(); - - if (!hasAdmin && currentStep === 1) { - const emailValue = t.state.get('registration-email'); - const invalidEmail = !/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+\b/i.test(emailValue); - t.invalidEmail.set(invalidEmail); + switch (t.state.get('currentStep')) { + case 1: { + const usernameValue = t.state.get('registration-username'); + const usernameRegex = new RegExp(`^${ RocketChat.settings.get('UTF8_Names_Validation') }$`); + t.state.set('invalidUsername', !usernameRegex.test(usernameValue)); + + const emailValue = t.state.get('registration-email'); + const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]+$/i; + t.state.set('invalidEmail', !emailRegex.test(emailValue)); + + if (t.state.get('invalidUsername') || t.state.get('invalidEmail')) { + return false; + } - if (invalidEmail) { + registerAdminUser(t.state.all(), () => t.state.set('currentStep', 2)); return false; } - - const state = t.state.all(); - const registration = Object.entries(state).filter(([key]) => /registration-/.test(key)); - const registrationData = Object.assign(...registration.map(d => ({[d[0].replace('registration-', '')]: d[1]}))); - - Meteor.call('registerUser', registrationData, error => { - if (error) { - return handleError(error); - } - - RocketChat.callbacks.run('userRegistered'); - - Meteor.loginWithPassword(s.trim(registrationData.email), registrationData.pass, error => { - if (error && error.error === 'error-invalid-email') { - toastr.success(t('We_have_sent_registration_email')); - return false; - } - - Session.set('forceLogin', false); - - Meteor.call('setUsername', registrationData.username, error => { - if (error) { - return handleError(error); - } - - RocketChat.callbacks.run('usernameSet'); - }); + case 2: { + t.state.set('currentStep', 3); + return false; + } + case 3: { + t.state.set('currentStep', 4); + return false; + } + case 4: { + persistSettings(t.state.all(), () => { + localStorage.removeItem('wizard'); + localStorage.setItem('wizardFinal', true); + FlowRouter.go('setup-wizard-final'); }); - }); + return false; + } } - if (hasAdmin && currentStep === 3) { - setSettingsAndGo(t.state.all()); - return false; + return false; + }, + 'click .setup-wizard-forms__footer-back'(e, t) { + switch (t.state.get('currentStep')) { + case 2: + t.state.set('currentStep', 1); + break; + case 3: + t.state.set('currentStep', 2); + break; + case 4: + t.state.set('currentStep', 3); + break; } - if (currentStep === 4) { - setSettingsAndGo(t.state.all(), JSON.parse(t.state.get('registerServer') || true)); + return false; + }, + 'input .js-setting-data'({ currentTarget: { name, value } }, t) { + t.state.set(name, value); + }, + 'click input[name="registerServer"]'({ currentTarget: { value } }, t) { + const oldValue = t.state.get('registerServer'); + const newValue = value === 'true'; + t.state.set('registerServer', newValue); - return false; + if (!oldValue && newValue) { + t.state.set('optIn', true); } - t.state.set('currentStep', currentStep + 1); - }, - 'click .setup-wizard-forms__footer-back'(e, t) { - t.state.set('currentStep', t.state.get('currentStep') - 1); + if (!newValue) { + t.state.set('optIn', false); + } + + return false; }, - 'input .js-setting-data'(e, t) { - t.state.set(e.currentTarget.name, e.currentTarget.value); + 'click input[name="optIn"]'({ currentTarget: { checked } }, t) { + t.state.set('optIn', checked); + return false; } }); @@ -161,144 +222,138 @@ Template.setupWizard.helpers({ currentStep() { return Template.instance().state.get('currentStep'); }, - itemModifier(step) { - const current = Template.instance().state.get('currentStep'); - - if (current === step) { - return 'setup-wizard-info__steps-item--active'; - } - - if (current > step) { - return 'setup-wizard-info__steps-item--past'; + currentStepTitle() { + switch (Template.instance().state.get('currentStep')) { + case 1: + return 'Admin_Info'; + case 2: + return 'Organization_Info'; + case 3: + return 'Server_Info'; + case 4: + return 'Register_Server'; } - - return ''; - }, - getValue(name) { - return Template.instance().state.get(name); - }, - selectedValue(setting, optionValue) { - return Template.instance().state.get(setting) === optionValue; }, - isDisabled() { - const user = Meteor.user(); - if (user && user.roles && !user.roles.includes('admin')) { - return 'disabled'; - } - - if (Template.instance().state.get('currentStep') === 1) { - const state = Template.instance().state.all(); - - if (Object.entries(state).filter(([key, value]) => /registration-/.test(key) && !value).length) { - return 'disabled'; - } + formLoadStateClass() { + switch (Template.instance().state.get('currentStep')) { + case 1: + return RocketChat.settings.get('Show_Setup_Wizard') === 'pending' && 'setup-wizard-forms__box--loaded'; + case 2: + case 3: + return Template.instance().wizardSettings.get().length > 0 && 'setup-wizard-forms__box--loaded'; + case 4: + return 'setup-wizard-forms__box--loaded'; } - - return ''; }, - headerTitle(step) { - if (!step) { - step = Template.instance().state.get('currentStep'); + showBackButton() { + switch (Template.instance().state.get('currentStep')) { + case 3: + return true; + case 4: + return true; } - switch (step) { - case 1: return t('Admin_Info'); - case 2: return t('Organization_Info'); - case 3: return t('Server_Info'); - case 4: return t('Register_Server'); - } + return false; }, - showStep() { - const currentStep = Template.instance().state.get('currentStep'); - if (currentStep === 2 || currentStep === 3) { - return 'setup-wizard-forms__content-step--active'; + isContinueDisabled() { + switch (Template.instance().state.get('currentStep')) { + case 1: + return Object.entries(Template.instance().state.all()) + .filter(([key, value]) => /registration-/.test(key) && !value) + .length !== 0; } - return ''; - }, - getSettings(step) { - return Template.instance().wizardSettings.get() - .filter(setting => setting.wizard.step === step) - .sort((a, b) => a.wizard.order - b.wizard.order); + return false; }, - languages() { - const languages = TAPi18n.getLanguages(); - - const result = Object.entries(languages).map(language => { - const obj = language[1]; - obj.key = language[0]; - return obj; - }).sort((a, b) => a.key - b.key); - - result.unshift({ - 'name': 'Default', - 'en': 'Default', - 'key': '' - }); + infoArgs() { + const t = Template.instance(); - return result; + return { + currentStep: t.state.get('currentStep') + }; }, - hasAdmin() { - return Template.instance().hasAdmin.get(); + adminInfoArgs() { + const t = Template.instance(); + + return { + currentStep: t.state.get('currentStep'), + name: t.state.get('registration-name'), + username: t.state.get('registration-username'), + email: t.state.get('registration-email'), + password: t.state.get('registration-pass'), + invalidUsername: t.state.get('invalidUsername'), + invalidEmail: t.state.get('invalidEmail') + }; }, - invalidEmail() { - return Template.instance().invalidEmail.get(); + registerServerArgs() { + const t = Template.instance(); + + return { + currentStep: t.state.get('currentStep'), + allowStandaloneServer: t.allowStandaloneServer.get(), + registerServer: t.allowStandaloneServer.get() ? t.state.get('registerServer') : true, + optIn: t.state.get('optIn') + }; }, - showBackButton() { - if (Template.instance().hasAdmin.get()) { - if (Template.instance().state.get('currentStep') > 2) { - return true; - } - - return false; - } - - if (Template.instance().state.get('currentStep') > 1) { - return true; - } - - return false; + customStepArgs(step) { + const t = Template.instance(); + + return { + currentStep: t.state.get('currentStep'), + step, + settings: t.wizardSettings.get() + .filter(setting => setting.wizard.step === step) + .sort((a, b) => a.wizard.order - b.wizard.order) + .map(({ type, _id, i18nLabel, values }) => ({ + type, + id: _id, + label: i18nLabel, + value: t.state.get(_id), + options: ( + type === 'select' && + values && + values.map(({ i18nLabel, key }) => ({ optionLabel: i18nLabel, optionValue: key })) + ) || ( + type === 'language' && + ([{ + optionLabel: 'Default', + optionValue: '' + }].concat( + Object.entries(TAPi18n.getLanguages()) + .map(([ key, { name } ]) => ({ optionLabel: name, optionValue: key })) + .sort((a, b) => a.key - b.key) + )) + ), + isValueSelected: (value) => value === t.state.get(_id) + })) + }; } }); -Template.setupWizardFinal.onCreated(function() { - this.autorun(() => { - const userId = Meteor.userId(); - - this.autorun((c) => { - const Show_Setup_Wizard = RocketChat.settings.get('Show_Setup_Wizard'); - const user = Meteor.user(); - - // Wait for roles and setup wizard setting - if ((userId && (!user || !user.status)) || !Show_Setup_Wizard) { - return; - } - - c.stop(); - - if ((!userId && Show_Setup_Wizard !== 'pending') || Show_Setup_Wizard === 'completed' || (userId && !RocketChat.authz.hasRole(userId, 'admin'))) { - FlowRouter.go('home'); - } - }); - }); -}); +Template.setupWizardInfo.helpers({ + stepItemModifier(step) { + const { currentStep } = Template.currentData(); -Template.setupWizardFinal.onRendered(function() { - $('#initial-page-loading').remove(); -}); + if (currentStep === step) { + return 'setup-wizard-info__steps-item--active'; + } -Template.setupWizardFinal.events({ - 'click .js-finish'() { - RocketChat.settings.set('Show_Setup_Wizard', 'completed', function() { - localStorage.removeItem('wizard'); - localStorage.removeItem('wizardFinal'); - FlowRouter.go('home'); - }); - } -}); + if (currentStep > step) { + return 'setup-wizard-info__steps-item--past'; + } -Template.setupWizardFinal.helpers({ - siteUrl() { - return RocketChat.settings.get('Site_Url'); + return ''; + }, + stepTitle(step) { + switch (step) { + case 1: + return 'Admin_Info'; + case 2: + return 'Organization_Info'; + case 3: + return 'Server_Info'; + case 4: + return 'Register_Server'; + } } }); diff --git a/packages/rocketchat-setup-wizard/package.js b/packages/rocketchat-setup-wizard/package.js index b9d07f3caeb3..ba70d31fd112 100644 --- a/packages/rocketchat-setup-wizard/package.js +++ b/packages/rocketchat-setup-wizard/package.js @@ -12,6 +12,8 @@ Package.onUse(function(api) { api.addFiles('client/setupWizard.html', 'client'); api.addFiles('client/setupWizard.js', 'client'); + api.addFiles('client/final.html', 'client'); + api.addFiles('client/final.js', 'client'); - api.addFiles('server/lib/getWizardSettings.js', 'server'); + api.addFiles('server/getSetupWizardParameters.js', 'server'); }); diff --git a/packages/rocketchat-setup-wizard/server/getSetupWizardParameters.js b/packages/rocketchat-setup-wizard/server/getSetupWizardParameters.js new file mode 100644 index 000000000000..910947c0418e --- /dev/null +++ b/packages/rocketchat-setup-wizard/server/getSetupWizardParameters.js @@ -0,0 +1,18 @@ +Meteor.methods({ + getSetupWizardParameters() { + const userId = Meteor.userId(); + const userHasAdminRole = userId && RocketChat.authz.hasRole(userId, 'admin'); + + if (!userHasAdminRole) { + throw new Meteor.Error('error-not-allowed'); + } + + const settings = RocketChat.models.Settings.findSetupWizardSettings().fetch(); + const allowStandaloneServer = process.env.DEPLOY_PLATFORM !== 'rocket-cloud'; + + return { + settings, + allowStandaloneServer + }; + } +}); diff --git a/packages/rocketchat-setup-wizard/server/lib/getWizardSettings.js b/packages/rocketchat-setup-wizard/server/lib/getWizardSettings.js deleted file mode 100644 index 918c3225bd23..000000000000 --- a/packages/rocketchat-setup-wizard/server/lib/getWizardSettings.js +++ /dev/null @@ -1,9 +0,0 @@ -Meteor.methods({ - getWizardSettings() { - if (RocketChat.authz.hasRole(Meteor.userId(), 'admin') && RocketChat.models && RocketChat.models.Settings) { - return RocketChat.models.Settings.findSetupWizardSettings().fetch(); - } - - throw new Meteor.Error('settings-are-not-ready', 'Settings are not ready'); - } -}); diff --git a/packages/rocketchat-theme/client/imports/components/popout.css b/packages/rocketchat-theme/client/imports/components/popout.css index 96ba48dec29d..8b774f08bc5f 100644 --- a/packages/rocketchat-theme/client/imports/components/popout.css +++ b/packages/rocketchat-theme/client/imports/components/popout.css @@ -180,7 +180,7 @@ &.rc-popout__content { height: 0px; - visibility: hidden; + overflow: hidden; & .streaming-object { visibility: 'hidden'; diff --git a/packages/rocketchat-theme/client/imports/components/setup-wizard.css b/packages/rocketchat-theme/client/imports/components/setup-wizard.css index fa2825348d28..3dea99d8cd8d 100644 --- a/packages/rocketchat-theme/client/imports/components/setup-wizard.css +++ b/packages/rocketchat-theme/client/imports/components/setup-wizard.css @@ -1,4 +1,7 @@ .setup-wizard { + --step-color: var(--rc-color-button-primary); + --highlight-color: var(--rc-color-button-primary); + display: flex; width: 100%; @@ -12,6 +15,7 @@ flex: 0 1 350px; margin: 55px 65px 30px 80px; + overflow: hidden; &__header{ display: flex; @@ -125,28 +129,30 @@ } &--active { - color: #1d74f5; + color: var(--rc-color-button-primary); &::before { - color: #1d74f5; - border-color: #1d74f5; + color: var(--rc-color-button-primary); + background-color: transparent; + border-color: var(--rc-color-button-primary); } } &--past { - color: #2f343d; + color: var(--rc-color-primary); &::before { - color: #ffffff; - background-color: #1d74f5; + color: var(--rc-color-content); + background-color: var(--rc-color-button-primary); + border-color: var(--rc-color-button-primary); } &::after { - background-color: #1d74f5 !important; + background-color: var(--rc-color-button-primary) !important; } & .setup-wizard-info__steps-item-bonding { - background-color: #1d74f5; + background-color: var(--rc-color-button-primary); } } @@ -177,8 +183,6 @@ height: calc(100% - 2rem); margin: 1rem 1rem 1rem 0; - padding: 3rem; - border-radius: 2px; background: #ffffff; box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08); @@ -190,6 +194,17 @@ flex-direction: column; width: 350px; + min-height: min-content; + margin: 3rem; + + visibility: hidden; + opacity: 0; + transition: opacity 1s linear; + + &--loaded { + visibility: visible; + opacity: 1; + } } &__header { @@ -259,7 +274,7 @@ cursor: pointer; color: #2f343d; - border: 1px solid #e7ebf2; + border: 2px solid #e7ebf2; border-radius: 2px; @@ -267,6 +282,14 @@ line-height: 1.25rem; + &--selected { + border-color: var(--highlight-color); + } + + &--disabled { + opacity: 0.25; + } + &:first-child { margin-bottom: 1rem; } @@ -292,22 +315,21 @@ position: relative; - border-color: #1d74f5; + border-color: var(--highlight-color); &::before { - position: absolute; - - top: 3px; - left: 3px; + content: ""; - width: 12px; - height: 12px; + position: absolute; - content: ""; + width: 100%; + height: 100%; + background-clip: padding-box; border-radius: 50%; + border: 2px solid transparent; - background-color: #1d74f5; + background-color: var(--highlight-color); } } } @@ -319,7 +341,7 @@ height: 20px; margin: 0 0.5rem; - border: 1px solid #cfd8e6; + border: 2px solid #cfd8e6; border-radius: 50px; } @@ -328,6 +350,63 @@ } } + &-checkbox { + position: relative; + + display: flex; + + margin: 0 -0.5rem 1rem; + + cursor: inherit; + + &-element { + position: absolute; + z-index: -1; + top: 0; + left: 0; + + width: 0; + height: 0; + + &:checked + .setup-wizard-forms__content-register-checkbox-fake { + position: relative; + + border-color: var(--highlight-color); + background-color: var(--highlight-color); + color: var(--rc-color-content); + + .setup-wizard-forms__content-register-checkbox-fake-icon { + display: block; + } + } + } + + &-fake { + display: block; + + width: 16px; + height: 16px; + margin: 2px 0.5rem; + + border: 2px solid #cfd8e6; + border-radius: 2px; + + &-icon { + width: 100%; + height: 100%; + display: none; + } + } + + &-text { + color: #666666; + } + } + + &-items + * { + margin-top: 1rem; + } + &-item { display: flex; @@ -340,13 +419,20 @@ } & .setup-wizard-forms__content-register-radio-icon { - margin: 0 calc(4px + 0.5rem); + min-width: 20px; + width: 20px; + height: 20px; + margin: 0 0.5rem; + align-self: baseline; - font-size: 10px; - } + &--check { + color: var(--highlight-color); + } - & .setup-wizard-forms__content-register-radio-icon--check { - color: #1d74f5; + &--circle { + height: 6px; + margin: 7px 0.5rem; + } } } } @@ -354,8 +440,9 @@ &__footer { display: flex; + flex-direction: row; - margin: 0 -0.5rem; + margin: 0 -0.5rem 2rem -0.5rem; & .rc-button { margin: 0 0.5rem; @@ -390,7 +477,7 @@ letter-spacing: 0; - color: #1d74f5; + color: var(--highlight-color); font-size: 1rem; diff --git a/packages/rocketchat-ui-sidenav/client/roomList.js b/packages/rocketchat-ui-sidenav/client/roomList.js index fcb0116a6b77..8088f8d67376 100644 --- a/packages/rocketchat-ui-sidenav/client/roomList.js +++ b/packages/rocketchat-ui-sidenav/client/roomList.js @@ -1,6 +1,5 @@ /* globals RocketChat */ import { UiTextContext } from 'meteor/rocketchat:lib'; -import _ from 'underscore'; Template.roomList.helpers({ rooms() { @@ -110,26 +109,35 @@ const getLowerCaseNames = (room, nameDefault = '') => { }; }; -// RocketChat.Notifications['onUser']('rooms-changed', ); - -const mergeSubRoom = (record/*, t*/) => { - const room = Tracker.nonreactive(() => RocketChat.models.Rooms.findOne({ _id: record.rid })); - if (!room) { - return record; - } - record.lastMessage = room.lastMessage; - record.lm = room._updatedAt; - return _.extend(record, getLowerCaseNames(record)); +const mergeSubRoom = subscription => { + const room = RocketChat.models.Rooms.findOne(subscription.rid) || { _updatedAt: subscription.ts }; + subscription.lastMessage = room.lastMessage; + subscription.lm = room._updatedAt; + return Object.assign(subscription, getLowerCaseNames(subscription)); }; -RocketChat.callbacks.add('cachedCollection-received-rooms', (room) => { +const mergeRoomSub = room => { const sub = RocketChat.models.Subscriptions.findOne({ rid: room._id }); if (!sub) { - return; + return room; } - const $set = {lastMessage : room.lastMessage, lm: room._updatedAt, ...getLowerCaseNames(room, sub.name)}; - RocketChat.models.Subscriptions.update({ rid: room._id }, {$set}); -}); + + RocketChat.models.Subscriptions.update({ + rid: room._id + }, { + $set: { + lastMessage: room.lastMessage, + lm: room._updatedAt, + ...getLowerCaseNames(room, sub.name) + } + }); + + return room; +}; + +RocketChat.callbacks.add('cachedCollection-received-rooms', mergeRoomSub); +RocketChat.callbacks.add('cachedCollection-sync-rooms', mergeRoomSub); +RocketChat.callbacks.add('cachedCollection-loadFromServer-rooms', mergeRoomSub); RocketChat.callbacks.add('cachedCollection-received-subscriptions', mergeSubRoom); RocketChat.callbacks.add('cachedCollection-sync-subscriptions', mergeSubRoom); diff --git a/server/methods/saveUserPreferences.js b/server/methods/saveUserPreferences.js index f0516a11cf9f..b13ecc3d41bc 100644 --- a/server/methods/saveUserPreferences.js +++ b/server/methods/saveUserPreferences.js @@ -69,7 +69,7 @@ Meteor.methods({ // propagate changed notification preferences Meteor.defer(() => { - if (oldDesktopNotifications !== settings.desktopNotifications) { + if (settings.desktopNotifications && oldDesktopNotifications !== settings.desktopNotifications) { if (settings.desktopNotifications === 'default') { RocketChat.models.Subscriptions.clearDesktopNotificationUserPreferences(user._id); } else { @@ -77,7 +77,7 @@ Meteor.methods({ } } - if (oldMobileNotifications !== settings.mobileNotifications) { + if (settings.mobileNotifications && oldMobileNotifications !== settings.mobileNotifications) { if (settings.mobileNotifications === 'default') { RocketChat.models.Subscriptions.clearMobileNotificationUserPreferences(user._id); } else { @@ -85,7 +85,7 @@ Meteor.methods({ } } - if (oldEmailNotifications !== settings.emailNotificationMode) { + if (settings.emailNotificationMode && oldEmailNotifications !== settings.emailNotificationMode) { if (settings.emailNotificationMode === 'default') { RocketChat.models.Subscriptions.clearEmailNotificationUserPreferences(user._id); } else { diff --git a/server/startup/migrations/v129.js b/server/startup/migrations/v129.js new file mode 100644 index 000000000000..17a92c8a7ceb --- /dev/null +++ b/server/startup/migrations/v129.js @@ -0,0 +1,60 @@ +RocketChat.Migrations.add({ + version: 129, + up() { + RocketChat.models.Users.find({ + $or: [ + { 'settings.preferences.desktopNotifications': { $exists: true, $ne: 'default' } }, + { 'settings.preferences.mobileNotifications': { $exists: true, $ne: 'default' } }, + { 'settings.preferences.emailNotificationMode': { $exists: true, $ne: 'default' } } + ] + }, { + fields: { + 'settings.preferences.desktopNotifications': 1, + 'settings.preferences.mobileNotifications': 1, + 'settings.preferences.emailNotificationMode': 1 + } + }).forEach(user => { + if (user.settings.preferences.desktopNotifications && user.settings.preferences.desktopNotifications !== 'default') { + RocketChat.models.Subscriptions.update({ + 'u._id': user._id, + desktopPrefOrigin: 'user', + desktopNotifications: null + }, { + $set: { + desktopNotifications: user.settings.preferences.desktopNotifications + } + }, { + multi: true + }); + } + + if (user.settings.preferences.mobileNotifications && user.settings.preferences.mobileNotifications !== 'default') { + RocketChat.models.Subscriptions.update({ + 'u._id': user._id, + mobilePrefOrigin: 'user', + mobilePushNotifications: null + }, { + $set: { + mobilePushNotifications: user.settings.preferences.mobileNotifications + } + }, { + multi: true + }); + } + + if (user.settings.preferences.emailNotificationMode && user.settings.preferences.emailNotificationMode !== 'default') { + RocketChat.models.Subscriptions.update({ + 'u._id': user._id, + emailPrefOrigin: 'user', + emailNotifications: null + }, { + $set: { + emailNotifications: user.settings.preferences.emailNotificationMode === 'disabled' || user.settings.preferences.emailNotificationMode === 'nothing' ? 'nothing' : 'mentions' + } + }, { + multi: true + }); + } + }); + } +}); diff --git a/tests/end-to-end/ui/00-login.js b/tests/end-to-end/ui/00-login.js index 4cd6c69f86e6..3934bfb9da9e 100644 --- a/tests/end-to-end/ui/00-login.js +++ b/tests/end-to-end/ui/00-login.js @@ -123,6 +123,24 @@ describe('[Setup Wizard]', () => { }); }); + describe('[Render - Step 3]', () => { + it('it should have option for registered server', () => { + setupWizard.registeredServer.isExisting().should.be.true; + }); + + it('it should have option for standalone server', () => { + setupWizard.standaloneServer.isExisting().should.be.true; + }); + + it('it should check option for registered server by default', () => { + setupWizard.registeredServer.isSelected().should.be.true; + }); + + after(() => { + setupWizard.goNext(); + }); + }); + describe('[Render - Final Step]', () => { it('it should render "Go to your workspace button', () => { setupWizard.goToWorkspace.waitForVisible(15000); diff --git a/tests/pageobjects/setup-wizard.page.js b/tests/pageobjects/setup-wizard.page.js index 593b9b646e75..f6a652fee44a 100644 --- a/tests/pageobjects/setup-wizard.page.js +++ b/tests/pageobjects/setup-wizard.page.js @@ -14,6 +14,8 @@ class SetupWizard extends Page { get siteName() { return browser.element('input[name="Site_Name"]'); } get language() { return browser.element('select[name="Language"]'); } get serverType() { return browser.element('select[name="Server_Type"]'); } + get registeredServer() { return browser.element('input[name="registerServer"][value="true"]'); } + get standaloneServer() { return browser.element('input[name="registerServer"][value="false"]'); } login() { browser.execute(function(email, password) {