diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel
index 6bea75501c1c..5d173ffbd0de 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 1.3.1
+ENV RC_VERSION 1.3.2
MAINTAINER buildmaster@rocket.chat
diff --git a/.github/history.json b/.github/history.json
index 369d03f3975c..c916720042ec 100644
--- a/.github/history.json
+++ b/.github/history.json
@@ -33563,6 +33563,66 @@
]
}
]
+ },
+ "1.3.2": {
+ "node_version": "8.11.4",
+ "npm_version": "6.4.1",
+ "mongo_versions": [
+ "3.2",
+ "3.4",
+ "3.6",
+ "4.0"
+ ],
+ "pull_requests": [
+ {
+ "pr": "15172",
+ "title": "[FIX] Attachment download button behavior",
+ "userLogin": "tassoevan",
+ "milestone": "1.3.2",
+ "contributors": [
+ "tassoevan",
+ "sampaiodiego"
+ ]
+ },
+ {
+ "pr": "15175",
+ "title": "[FIX] Messages search scroll",
+ "userLogin": "ggazzo",
+ "milestone": "1.3.2",
+ "contributors": [
+ "ggazzo"
+ ]
+ },
+ {
+ "pr": "15157",
+ "title": "[FIX] IE11 - callback createTreeWalker doesnt accept acceptNode",
+ "userLogin": "ggazzo",
+ "milestone": "1.3.2",
+ "contributors": [
+ "ggazzo",
+ "tassoevan"
+ ]
+ },
+ {
+ "pr": "15173",
+ "title": "Update latest Livechat widget version to 1.1.4",
+ "userLogin": "renatobecker",
+ "milestone": "1.3.2",
+ "contributors": [
+ "renatobecker"
+ ]
+ },
+ {
+ "pr": "15154",
+ "title": "Update latest Livechat widget version(1.1.3)",
+ "userLogin": "renatobecker",
+ "milestone": "1.3.2",
+ "contributors": [
+ "renatobecker",
+ "web-flow"
+ ]
+ }
+ ]
}
}
}
\ No newline at end of file
diff --git a/.travis/snap.sh b/.travis/snap.sh
index a3d692f673f9..83a17c0fcf81 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=1.3.1
+ RC_VERSION=1.3.2
fi
echo "Preparing to trigger a snap release for $CHANNEL channel"
diff --git a/HISTORY.md b/HISTORY.md
index c1281fd07ba9..f3e0e8af972e 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,6 +1,6 @@
-# 1.3.1
-`2019-08-08 · 2 🐛 · 2 👩💻👨💻`
+# 1.3.2
+`2019-08-13 · 3 🐛 · 2 🔍 · 4 👩💻👨💻`
### Engine versions
- Node: `8.11.4`
@@ -9,21 +9,42 @@
### 🐛 Bug fixes
-- Custom emoji table scroll ([#15119](https://github.com/RocketChat/Rocket.Chat/pull/15119))
-- Direct Message names not visible on Admin panel ([#15114](https://github.com/RocketChat/Rocket.Chat/pull/15114))
+- Attachment download button behavior ([#15172](https://github.com/RocketChat/Rocket.Chat/pull/15172))
+- Messages search scroll ([#15175](https://github.com/RocketChat/Rocket.Chat/pull/15175))
+- IE11 - callback createTreeWalker doesnt accept acceptNode ([#15157](https://github.com/RocketChat/Rocket.Chat/pull/15157))
🔍 Minor changes
-- Fix custom auth ([#15141](https://github.com/RocketChat/Rocket.Chat/pull/15141))
+- Update latest Livechat widget version to 1.1.4 ([#15173](https://github.com/RocketChat/Rocket.Chat/pull/15173))
+- Update latest Livechat widget version(1.1.3) ([#15154](https://github.com/RocketChat/Rocket.Chat/pull/15154))
### 👩💻👨💻 Core Team 🤓
+- [@ggazzo](https://github.com/ggazzo)
+- [@renatobecker](https://github.com/renatobecker)
+- [@sampaiodiego](https://github.com/sampaiodiego)
+- [@tassoevan](https://github.com/tassoevan)
+
+# 1.3.1
+`2019-08-08 · 2 🐛 · 2 👩💻👨💻`
+
+### Engine versions
+- Node: `8.11.4`
+- NPM: `6.4.1`
+- MongoDB: `3.2, 3.4, 3.6, 4.0`
+
+### 🐛 Bug fixes
+
+- Custom emoji table scroll ([#15119](https://github.com/RocketChat/Rocket.Chat/pull/15119))
+- Direct Message names not visible on Admin panel ([#15114](https://github.com/RocketChat/Rocket.Chat/pull/15114))
+
+### 👩💻👨💻 Core Team 🤓
+
- [@ggazzo](https://github.com/ggazzo)
- [@sampaiodiego](https://github.com/sampaiodiego)
-- [@MarcosSpessatto](https://github.com/MarcosSpessatto)
# 1.3.0
`2019-08-02 · 9 🎉 · 6 🚀 · 31 🐛 · 31 🔍 · 29 👩💻👨💻`
@@ -5369,4 +5390,4 @@
- [@marceloschmidt](https://github.com/marceloschmidt)
- [@mrsimpson](https://github.com/mrsimpson)
- [@rodrigok](https://github.com/rodrigok)
-- [@sampaiodiego](https://github.com/sampaiodiego)
+- [@sampaiodiego](https://github.com/sampaiodiego)
\ No newline at end of file
diff --git a/app/emoji/client/emojiParser.js b/app/emoji/client/emojiParser.js
index 00ef84402bee..d7f7980df11a 100644
--- a/app/emoji/client/emojiParser.js
+++ b/app/emoji/client/emojiParser.js
@@ -3,6 +3,7 @@ import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { getUserPreference } from '../../utils';
+import { isIE11 } from '../../ui-utils/client/lib/isIE11';
import { callbacks } from '../../callbacks';
import { emoji } from '../lib/rocketchat';
@@ -32,41 +33,44 @@ Tracker.autorun(() => {
const emojis = Array.from(checkEmojiOnly.querySelectorAll('.emoji:not(:empty), .emojione:not(:empty)'));
- const walker = document.createTreeWalker(
- checkEmojiOnly,
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
- {
- acceptNode: (node) => {
- if (node.nodeType === Node.ELEMENT_NODE && (
- node.classList.contains('emojione')
- || node.classList.contains('emoji')
- )) {
- return NodeFilter.FILTER_REJECT;
- }
- return NodeFilter.FILTER_ACCEPT;
- },
- },
- );
-
let hasText = false;
- while (walker.nextNode()) {
- if (walker.currentNode.nodeType === Node.TEXT_NODE && walker.currentNode.nodeValue.trim() !== '') {
- hasText = true;
- break;
+ if (!isIE11()) {
+ const filter = (node) => {
+ if (node.nodeType === Node.ELEMENT_NODE && (
+ node.classList.contains('emojione')
+ || node.classList.contains('emoji')
+ )) {
+ return NodeFilter.FILTER_REJECT;
+ }
+ return NodeFilter.FILTER_ACCEPT;
+ };
+
+ const walker = document.createTreeWalker(
+ checkEmojiOnly,
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
+ filter
+ );
+
+
+ while (walker.nextNode()) {
+ if (walker.currentNode.nodeType === Node.TEXT_NODE && walker.currentNode.nodeValue.trim() !== '') {
+ hasText = true;
+ break;
+ }
}
- }
-
- const emojiOnly = emojis.length && !hasText;
-
- if (emojiOnly) {
- for (let i = 0, len = emojis.length; i < len; i++) {
- const { classList } = emojis[i];
- classList.add('big');
+ const emojiOnly = emojis.length && !hasText;
+
+ if (emojiOnly) {
+ for (let i = 0, len = emojis.length; i < len; i++) {
+ const { classList } = emojis[i];
+ classList.add('big');
+ }
+ html = checkEmojiOnly.innerHTML;
}
- html = checkEmojiOnly.innerHTML;
}
+
// apostrophe (') back to '
html = html.replace(/\'/g, ''');
diff --git a/app/file-upload/server/config/AmazonS3.js b/app/file-upload/server/config/AmazonS3.js
index c262351fc0da..48aea6aea167 100644
--- a/app/file-upload/server/config/AmazonS3.js
+++ b/app/file-upload/server/config/AmazonS3.js
@@ -8,23 +8,21 @@ import { FileUploadClass, FileUpload } from '../lib/FileUpload';
import '../../ufs/AmazonS3/server.js';
const get = function(file, req, res) {
- const fileUrl = this.store.getRedirectURL(file);
+ const forceDownload = typeof req.query.download !== 'undefined';
+ const fileUrl = this.store.getRedirectURL(file, forceDownload);
- if (fileUrl) {
- const storeType = file.store.split(':').pop();
- if (settings.get(`FileUpload_S3_Proxy_${ storeType }`)) {
- const request = /^https:/.test(fileUrl) ? https : http;
- request.get(fileUrl, (fileRes) => fileRes.pipe(res));
- } else {
- res.removeHeader('Content-Length');
- res.removeHeader('Cache-Control');
- res.setHeader('Location', fileUrl);
- res.writeHead(302);
- res.end();
- }
- } else {
- res.end();
+ if (!fileUrl) {
+ return res.end();
+ }
+
+ const storeType = file.store.split(':').pop();
+ if (settings.get(`FileUpload_S3_Proxy_${ storeType }`)) {
+ const request = /^https:/.test(fileUrl) ? https : http;
+
+ return FileUpload.proxyFile(file.name, fileUrl, forceDownload, request, req, res);
}
+
+ return FileUpload.redirectToFile(fileUrl, req, res);
};
const copy = function(file, out) {
diff --git a/app/file-upload/server/config/GoogleStorage.js b/app/file-upload/server/config/GoogleStorage.js
index 0af606ead1f0..c8e11bfe1fb5 100644
--- a/app/file-upload/server/config/GoogleStorage.js
+++ b/app/file-upload/server/config/GoogleStorage.js
@@ -8,31 +8,30 @@ import { settings } from '../../../settings';
import '../../ufs/GoogleStorage/server.js';
const get = function(file, req, res) {
- this.store.getRedirectURL(file, (err, fileUrl) => {
+ const forceDownload = typeof req.query.download !== 'undefined';
+
+ this.store.getRedirectURL(file, forceDownload, (err, fileUrl) => {
if (err) {
- console.error(err);
+ return console.error(err);
}
- if (fileUrl) {
- const storeType = file.store.split(':').pop();
- if (settings.get(`FileUpload_GoogleStorage_Proxy_${ storeType }`)) {
- const request = /^https:/.test(fileUrl) ? https : http;
- request.get(fileUrl, (fileRes) => fileRes.pipe(res));
- } else {
- res.removeHeader('Content-Length');
- res.removeHeader('Cache-Control');
- res.setHeader('Location', fileUrl);
- res.writeHead(302);
- res.end();
- }
- } else {
- res.end();
+ if (!fileUrl) {
+ return res.end();
}
+
+ const storeType = file.store.split(':').pop();
+ if (settings.get(`FileUpload_GoogleStorage_Proxy_${ storeType }`)) {
+ const request = /^https:/.test(fileUrl) ? https : http;
+
+ return FileUpload.proxyFile(file.name, fileUrl, forceDownload, request, req, res);
+ }
+
+ return FileUpload.redirectToFile(fileUrl, req, res);
});
};
const copy = function(file, out) {
- this.store.getRedirectURL(file, (err, fileUrl) => {
+ this.store.getRedirectURL(file, false, (err, fileUrl) => {
if (err) {
console.error(err);
}
diff --git a/app/file-upload/server/lib/FileUpload.js b/app/file-upload/server/lib/FileUpload.js
index 9258da3fcd1e..aed9f1b41f82 100644
--- a/app/file-upload/server/lib/FileUpload.js
+++ b/app/file-upload/server/lib/FileUpload.js
@@ -371,6 +371,20 @@ export const FileUpload = {
return false;
},
+
+ redirectToFile(fileUrl, req, res) {
+ res.removeHeader('Content-Length');
+ res.removeHeader('Cache-Control');
+ res.setHeader('Location', fileUrl);
+ res.writeHead(302);
+ res.end();
+ },
+
+ proxyFile(fileName, fileUrl, forceDownload, request, req, res) {
+ res.setHeader('Content-Disposition', `${ forceDownload ? 'attachment' : 'inline' }; filename="${ encodeURI(fileName) }"`);
+
+ request.get(fileUrl, (fileRes) => fileRes.pipe(res));
+ },
};
export class FileUploadClass {
diff --git a/app/file-upload/ufs/AmazonS3/server.js b/app/file-upload/ufs/AmazonS3/server.js
index 656bfb2c0656..a22014a73904 100644
--- a/app/file-upload/ufs/AmazonS3/server.js
+++ b/app/file-upload/ufs/AmazonS3/server.js
@@ -47,10 +47,11 @@ export class AmazonS3Store extends UploadFS.Store {
}
};
- this.getRedirectURL = function(file) {
+ this.getRedirectURL = function(file, forceDownload = false) {
const params = {
Key: this.getPath(file),
Expires: classOptions.URLExpiryTimeSpan,
+ ResponseContentDisposition: `${ forceDownload ? 'attachment' : 'inline' }; filename="${ encodeURI(file.name) }"`,
};
return s3.getSignedUrl('getObject', params);
@@ -140,7 +141,6 @@ export class AmazonS3Store extends UploadFS.Store {
Key: this.getPath(file),
Body: writeStream,
ContentType: file.type,
- ContentDisposition: `inline; filename="${ encodeURI(file.name) }"`,
}, (error) => {
if (error) {
diff --git a/app/file-upload/ufs/GoogleStorage/server.js b/app/file-upload/ufs/GoogleStorage/server.js
index b350caa6df38..47b384466549 100644
--- a/app/file-upload/ufs/GoogleStorage/server.js
+++ b/app/file-upload/ufs/GoogleStorage/server.js
@@ -30,10 +30,10 @@ export class GoogleStorageStore extends UploadFS.Store {
}
};
- this.getRedirectURL = function(file, callback) {
+ this.getRedirectURL = function(file, forceDownload = false, callback) {
const params = {
action: 'read',
- responseDisposition: 'inline',
+ responseDisposition: forceDownload ? 'attachment' : 'inline',
expires: Date.now() + this.options.URLExpiryTimeSpan * 1000,
};
diff --git a/app/markdown/lib/parser/original/markdown.js b/app/markdown/lib/parser/original/markdown.js
index 09517cd6fd4e..e0817c542f38 100644
--- a/app/markdown/lib/parser/original/markdown.js
+++ b/app/markdown/lib/parser/original/markdown.js
@@ -23,7 +23,7 @@ const parseNotEscaped = function(msg, message) {
return token;
};
- const schemes = settings.get('Markdown_SupportSchemesForLink').split(',').join('|');
+ const schemes = (settings.get('Markdown_SupportSchemesForLink') || '').split(',').join('|');
if (settings.get('Markdown_Headers')) {
// Support # Text for h1
diff --git a/app/message-attachments/client/messageAttachment.html b/app/message-attachments/client/messageAttachment.html
index d5165110ce89..03b3a606a4c8 100644
--- a/app/message-attachments/client/messageAttachment.html
+++ b/app/message-attachments/client/messageAttachment.html
@@ -57,7 +57,7 @@
{{#if title_link}}
{{title}}
{{#if title_link_download}}
- {{> icon icon="download"}}
+ {{> icon icon="download"}}
{{/if}}
{{else}}
{{title}}
diff --git a/app/search/client/provider/result.js b/app/search/client/provider/result.js
index 03367888e29c..1d62162bd202 100644
--- a/app/search/client/provider/result.js
+++ b/app/search/client/provider/result.js
@@ -46,7 +46,7 @@ Template.DefaultSearchResultTemplate.onRendered(function() {
const result = this.data.result.get();
if (result && this.hasMore.get()) {
Tracker.afterFlush(() => {
- if (list.scrollHeight <= list.offsetHeight) {
+ if (list.scrollHeight < list.offsetHeight) {
this.data.payload.limit = (this.data.payload.limit || this.pageSize) + this.pageSize;
this.data.search();
}
diff --git a/app/search/client/style/style.css b/app/search/client/style/style.css
index 93e7c4aa8d00..cd7509548840 100644
--- a/app/search/client/style/style.css
+++ b/app/search/client/style/style.css
@@ -25,7 +25,7 @@
display: flex;
overflow: hidden;
flex-direction: column;
- flex: 1;
+ flex: 1 1 0;
}
.rocket-default-search-settings {
diff --git a/app/ui-utils/client/lib/isIE11.js b/app/ui-utils/client/lib/isIE11.js
new file mode 100644
index 000000000000..c494c5c63202
--- /dev/null
+++ b/app/ui-utils/client/lib/isIE11.js
@@ -0,0 +1,15 @@
+export const isIE11 = () => {
+ const { userAgent } = window.navigator;
+ const msieIdx = userAgent.indexOf('MSIE');
+
+ if (msieIdx > 0) {
+ return parseInt(userAgent.substring(msieIdx + 5, userAgent.indexOf('.', msieIdx))) === 11;
+ }
+
+ // If MSIE detection fails, check the Trident engine version
+ if (navigator.userAgent.match(/Trident\/7\./)) {
+ return true;
+ }
+
+ return false;
+};
diff --git a/app/utils/rocketchat.info b/app/utils/rocketchat.info
index 8a9436e88d3b..7ad34b9e2b96 100644
--- a/app/utils/rocketchat.info
+++ b/app/utils/rocketchat.info
@@ -1,3 +1,3 @@
{
- "version": "1.3.1"
+ "version": "1.3.2"
}
diff --git a/imports/client/@rocket.chat/apps-engine b/imports/client/@rocket.chat/apps-engine
new file mode 120000
index 000000000000..9a368c3d1407
--- /dev/null
+++ b/imports/client/@rocket.chat/apps-engine
@@ -0,0 +1 @@
+../../../node_modules/@rocket.chat/apps-engine
\ No newline at end of file
diff --git a/package.json b/package.json
index aa24a8eb7c9b..30667a155038 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "Rocket.Chat",
"description": "The Ultimate Open Source WebChat Platform",
- "version": "1.3.1",
+ "version": "1.3.2",
"author": {
"name": "Rocket.Chat",
"url": "https://rocket.chat/"
diff --git a/packages/rocketchat-livechat/plugin/build.sh b/packages/rocketchat-livechat/plugin/build.sh
index 37d09b1db2a3..f5a8a02760fd 100644
--- a/packages/rocketchat-livechat/plugin/build.sh
+++ b/packages/rocketchat-livechat/plugin/build.sh
@@ -3,8 +3,7 @@ export LIVECHAT_DIR="../../../public/livechat"
export BUILD_DIR="../build"
export BUNDLE_DIR="../build/bundle/programs/web.browser.legacy"
export LIVECHAT_ASSETS_DIR="../../../private/livechat"
-export LATEST_LIVECHAT_VERSION="1.1.0"
-export LIVECHAT_VERSION_DIR="1.0.0"
+export LATEST_LIVECHAT_VERSION="1.1.4"
cd packages/rocketchat-livechat/.app
meteor npm install --production
@@ -23,10 +22,8 @@ cp $BUNDLE_DIR/head.html $LIVECHAT_ASSETS_DIR/head.html
rm -rf $BUILD_DIR
#NEW LIVECHAT#
-echo "Installing new Livechat..."
+echo "Installing Livechat ${LATEST_LIVECHAT_VERSION}..."
cd $LIVECHAT_DIR
-mkdir -p $LIVECHAT_VERSION_DIR
-cd $LIVECHAT_VERSION_DIR
curl -sOL "https://github.com/RocketChat/Rocket.Chat.Livechat/releases/download/v${LATEST_LIVECHAT_VERSION}/build.tar.gz"
tar -xf build.tar.gz
@@ -36,5 +33,4 @@ rm build.tar.gz
# this is not harmful since doctype is case-insesitive: https://www.w3.org/TR/html5/syntax.html#the-doctype
node -e 'fs.writeFileSync("index.html", fs.readFileSync("index.html").toString().replace("