From a39ca5e08f8654724466d038be160a1172d836cf Mon Sep 17 00:00:00 2001 From: trojan Date: Wed, 14 Jun 2017 03:26:12 +0530 Subject: [PATCH 01/56] Phase-I --- package.json | 205 +++++++++--------- packages/rocketchat-i18n/i18n/en.i18n.json | 8 + .../server/lib/sendEmailOnMessage.js | 2 +- .../rocketchat-lib/server/startup/settings.js | 44 ++++ 4 files changed, 160 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index 0f2186e96baf..4c4de9dac01d 100644 --- a/package.json +++ b/package.json @@ -1,100 +1,109 @@ { - "name": "Rocket.Chat", - "description": "The Ultimate Open Source WebChat Platform", - "version": "0.57.0-develop", - "author": { - "name": "Rocket.Chat", - "url": "https://rocket.chat/" - }, - "contributors": [{ - "name": "Aaron Ogle", - "email": "aaron.ogle@rocket.chat" - }, { - "name": "Bradley Hilton", - "email": "bradley.hilton@rocket.chat" - }, { - "name": "Diego Sampaio", - "email": "diego.sampaio@rocket.chat" - }, { - "name": "Gabriel Engel", - "email": "gabriel.engel@rocket.chat" - }, { - "name": "Marcelo Schmidt", - "email": "marcelo.schmidt@rocket.chat" - }, { - "name": "Rodrigo Nascimento", - "email": "rodrigo.nascimento@rocket.chat" - }, { - "name": "Sing Li", - "email": "sing.li@rocket.chat" - }], - "mocha": { - "tests": [ - "packages/**/*.tests.js" - ], - "files": [ - "packages/**/*.js", - "!packages/**/*.tests.js" - ] - }, - "keywords": [ - "rocketchat", - "rocket", - "chat" - ], - "scripts": { - "start": "meteor npm i && meteor", - "lint": "eslint .", - "lint-fix": "eslint . --fix", - "stylelint": "stylelint packages/**/*.{less,css}", - "test": "node .scripts/start.js", - "deploy": "npm run build && pm2 startOrRestart pm2.json", - "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests/end-to-end", - "chimp-test": "chimp tests/chimp-config.js", - "postinstall": "cd packages/rocketchat-katex && npm i", - "testunit-watch": "mocha --watch --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "coverage": "nyc -r html mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "testunit": "mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "version": "node .scripts/version.js", - "set-version": "node .scripts/set-version.js", - "release": "npm run set-version --silent" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/RocketChat/Rocket.Chat.git" - }, - "bugs": { - "url": "https://github.com/RocketChat/Rocket.Chat/issues", - "email": "support@rocket.chat" - }, - "devDependencies": { - "babel-mocha-es6-compiler": "^0.1.0", - "babel-plugin-array-includes": "^2.0.3", - "chimp": "^0.49.0", - "conventional-changelog": "^1.1.3", - "eslint": "^3.19.0", - "postcss-cssnext": "^2.11.0", - "postcss-smart-import": "^0.7.2", - "stylelint": "^7.10.1", - "supertest": "^3.0.0" - }, - "dependencies": { - "@google-cloud/storage": "^1.1.1", - "aws-sdk": "^2.55.0", - "babel-runtime": "^6.23.0", - "bcrypt": "^1.0.2", - "codemirror": "^5.26.0", - "file-type": "^4.3.0", - "highlight.js": "^9.12.0", - "jquery": "^3.2.1", - "mime-db": "^1.28.0", - "mime-type": "^3.0.5", - "moment": "^2.18.1", - "moment-timezone": "^0.5.13", - "photoswipe": "^4.1.2", - "prom-client": "^9.0.0", - "semver": "^5.3.0", - "toastr": "^2.1.2" - } + "name": "Rocket.Chat", + "description": "The Ultimate Open Source WebChat Platform", + "version": "0.57.0-develop", + "author": { + "name": "Rocket.Chat", + "url": "https://rocket.chat/" + }, + "contributors": [ + { + "name": "Aaron Ogle", + "email": "aaron.ogle@rocket.chat" + }, + { + "name": "Bradley Hilton", + "email": "bradley.hilton@rocket.chat" + }, + { + "name": "Diego Sampaio", + "email": "diego.sampaio@rocket.chat" + }, + { + "name": "Gabriel Engel", + "email": "gabriel.engel@rocket.chat" + }, + { + "name": "Marcelo Schmidt", + "email": "marcelo.schmidt@rocket.chat" + }, + { + "name": "Rodrigo Nascimento", + "email": "rodrigo.nascimento@rocket.chat" + }, + { + "name": "Sing Li", + "email": "sing.li@rocket.chat" + } + ], + "mocha": { + "tests": [ + "packages/**/*.tests.js" + ], + "files": [ + "packages/**/*.js", + "!packages/**/*.tests.js" + ] + }, + "keywords": [ + "rocketchat", + "rocket", + "chat" + ], + "scripts": { + "start": "meteor npm i && meteor", + "lint": "eslint .", + "lint-fix": "eslint . --fix", + "stylelint": "stylelint packages/**/*.{less,css}", + "test": "node .scripts/start.js", + "deploy": "npm run build && pm2 startOrRestart pm2.json", + "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests/end-to-end", + "chimp-test": "chimp tests/chimp-config.js", + "postinstall": "cd packages/rocketchat-katex && npm i", + "testunit-watch": "mocha --watch --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "coverage": "nyc -r html mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "testunit": "mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "version": "node .scripts/version.js", + "set-version": "node .scripts/set-version.js", + "release": "npm run set-version --silent" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/RocketChat/Rocket.Chat.git" + }, + "bugs": { + "url": "https://github.com/RocketChat/Rocket.Chat/issues", + "email": "support@rocket.chat" + }, + "devDependencies": { + "babel-mocha-es6-compiler": "^0.1.0", + "babel-plugin-array-includes": "^2.0.3", + "chimp": "^0.49.0", + "conventional-changelog": "^1.1.3", + "eslint": "^3.19.0", + "postcss-cssnext": "^2.11.0", + "postcss-smart-import": "^0.7.2", + "stylelint": "^7.10.1", + "supertest": "^3.0.0" + }, + "dependencies": { + "@google-cloud/storage": "^1.1.1", + "aws-sdk": "^2.55.0", + "babel-runtime": "^6.23.0", + "bcrypt": "^1.0.2", + "codemirror": "^5.26.0", + "file-type": "^4.3.0", + "highlight.js": "^9.12.0", + "imap": "^0.8.19", + "jquery": "^3.2.1", + "mime-db": "^1.28.0", + "mime-type": "^3.0.5", + "moment": "^2.18.1", + "moment-timezone": "^0.5.13", + "photoswipe": "^4.1.2", + "prom-client": "^9.0.0", + "semver": "^5.3.0", + "toastr": "^2.1.2" + } } diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 1b2888536b9a..16117406cd63 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -708,6 +708,14 @@ "Installed_at": "Installed at", "Instance_Record": "Instance Record", "Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message", + "IMAP": "IMAP", + "IMAP_Host": "IMAP Host", + "IMAP_IgnoreTLS": "Ignore TLS", + "IMAP_Password": "IMAP Password", + "IMAP_Port": "IMAP Port", + "IMAP_Protocol": "IMAP Protocol", + "IMAP_Test_Button": "Test IMAP Settings", + "IMAP_Username": "IMAP Username", "Impersonate_user": "Impersonate User", "Impersonate_user_description": "When enabled, integration posts as the user that triggered integration", "Incoming_WebHook": "Incoming WebHook", diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 8ed92b4eced0..6c1a97e02cae 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -119,7 +119,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { email = { to: email.address, from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject }`, + subject: `[${ siteName }] ${ emailSubject } [${ message.rid } ${ message._id }]`, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer }; diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 1671d5185bee..d16d53305f3e 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -462,6 +462,50 @@ RocketChat.settings.addGroup('Email', function() { i18nLabel: 'Footer' }); }); + this.section('IMAP', function() { + this.add('IMAP_Protocol', 'imap', { + type: 'select', + values: [{ + key: 'imap', + i18nLabel: 'imap' + }, { + key: 'imaps', + i18nLabel: 'imaps' + }], + env: true, + i18nLabel: 'Protocol' + }); + this.add('IMAP_Host', '', { + type: 'string', + env: true, + i18nLabel: 'Host' + }); + this.add('IMAP_Port', '', { + type: 'string', + env: true, + i18nLabel: 'Port' + }); + this.add('IMAP_IgnoreTLS', false, { + type: 'boolean', + env: true, + i18nLabel: 'IgnoreTLS', + enableQuery: { + _id: 'IMAP_Protocol', + value: 'imap' + } + }); + this.add('IMAP_Username', '', { + type: 'string', + env: true, + i18nLabel: 'Username', + placeholder: 'email@domain' + }); + this.add('IMAP_Password', '', { + type: 'password', + env: true, + i18nLabel: 'Password' + }); + }); this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { type: 'select', From c5e9905c3b756cbdee5522282ef45221ad02e3fc Mon Sep 17 00:00:00 2001 From: trojan Date: Wed, 14 Jun 2017 04:14:12 +0530 Subject: [PATCH 02/56] Phase-I --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 ++ .../rocketchat-lib/server/lib/sendEmailOnMessage.js | 11 +++++++++-- packages/rocketchat-lib/server/startup/settings.js | 13 ++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 16117406cd63..fc88117df76a 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -606,6 +606,7 @@ "Follow_social_profiles": "Follow our social profiles, fork us on github and share your thoughts about the rocket.chat app on our trello board.", "Food_and_Drink": "Food & Drink", "Footer": "Footer", + "Footer_Direct_Reply": "Footer when Direct Reply enabled", "Fonts": "Fonts", "For_your_security_you_must_enter_your_current_password_to_continue": "For your security, you must enter your current password to continue", "Force_Disable_OpLog_For_Cache": "Force disable OpLog for Cache", @@ -709,6 +710,7 @@ "Instance_Record": "Instance Record", "Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message", "IMAP": "IMAP", + "IMAP_Enable": "Enable Direct Reply", "IMAP_Host": "IMAP Host", "IMAP_IgnoreTLS": "Ignore TLS", "IMAP_Password": "IMAP Password", diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 6c1a97e02cae..985a7ac2aa88 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -60,7 +60,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { } const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); - const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + let footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); messageHTML = messageHTML.replace(/\n/gm, '
'); RocketChat.models.Subscriptions.findWithSendEmailByRoomId(room._id).forEach((sub) => { @@ -114,12 +114,19 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { return; } + let Subject = `[${ siteName }] ${ emailSubject }`; + + if (RocketChat.settings.get('IMAP_Enable')) { + Subject += `[${ message.rid } ${ message._id }]`; + footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); + } + user.emails.some((email) => { if (email.verified) { email = { to: email.address, from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject } [${ message.rid } ${ message._id }]`, + subject: Subject, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer }; diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index d16d53305f3e..369ea6a0dfe7 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -455,14 +455,25 @@ RocketChat.settings.addGroup('Email', function() { multiline: true, i18nLabel: 'Header' }); - return this.add('Email_Footer', 'Powered by Rocket.Chat', { + this.add('Email_Footer', 'Powered by Rocket.Chat', { type: 'code', code: 'text/html', multiline: true, i18nLabel: 'Footer' }); + return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.Powered by Rocket.Chat', { + type: 'code', + code: 'text/html', + multiline: true, + i18nLabel: 'Footer_Direct_Reply' + }); }); this.section('IMAP', function() { + this.add('IMAP_Enable', false, { + type: 'boolean', + env: true, + i18nLabel: 'IMAP_Enable' + }); this.add('IMAP_Protocol', 'imap', { type: 'select', values: [{ From eaac7fbccb10fadb8ab063cac74d3787d4d05f7b Mon Sep 17 00:00:00 2001 From: trojan Date: Wed, 14 Jun 2017 09:57:36 +0530 Subject: [PATCH 03/56] Updated email footer --- packages/rocketchat-lib/server/startup/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 369ea6a0dfe7..a42066a70d46 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -461,7 +461,7 @@ RocketChat.settings.addGroup('Email', function() { multiline: true, i18nLabel: 'Footer' }); - return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.Powered by Rocket.Chat', { + return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.
Do not temper email SubjectPowered by Rocket.Chat', { type: 'code', code: 'text/html', multiline: true, From 61aa4223b5bb8c5e448a7f99a37ff4cbb45de050 Mon Sep 17 00:00:00 2001 From: trojan Date: Thu, 22 Jun 2017 19:16:59 +0530 Subject: [PATCH 04/56] IMAP implementation. Received emails & reply message --- package.json | 2 + packages/rocketchat-i18n/i18n/en.i18n.json | 2 + packages/rocketchat-lib/package.js | 3 + .../server/lib/interceptDirectReplyEmails.js | 93 +++++++++++++++++++ .../server/lib/processDirectEmail.js | 6 ++ .../server/lib/sendEmailOnMessage.js | 13 ++- .../server/methods/startIMAPIntercepter.js | 7 ++ .../rocketchat-lib/server/startup/settings.js | 20 +++- 8 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js create mode 100644 packages/rocketchat-lib/server/lib/processDirectEmail.js create mode 100644 packages/rocketchat-lib/server/methods/startIMAPIntercepter.js diff --git a/package.json b/package.json index 4c4de9dac01d..5956855a13a0 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "babel-runtime": "^6.23.0", "bcrypt": "^1.0.2", "codemirror": "^5.26.0", + "emailreplyparser": "0.0.5", "file-type": "^4.3.0", "highlight.js": "^9.12.0", "imap": "^0.8.19", @@ -101,6 +102,7 @@ "mime-type": "^3.0.5", "moment": "^2.18.1", "moment-timezone": "^0.5.13", + "node-email-reply-parser": "0.0.1", "photoswipe": "^4.1.2", "prom-client": "^9.0.0", "semver": "^5.3.0", diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index fc88117df76a..cac12e71d105 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -710,12 +710,14 @@ "Instance_Record": "Instance Record", "Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message", "IMAP": "IMAP", + "IMAP_Debug": "Debug", "IMAP_Enable": "Enable Direct Reply", "IMAP_Host": "IMAP Host", "IMAP_IgnoreTLS": "Ignore TLS", "IMAP_Password": "IMAP Password", "IMAP_Port": "IMAP Port", "IMAP_Protocol": "IMAP Protocol", + "IMAP_Start": "Start", "IMAP_Test_Button": "Test IMAP Settings", "IMAP_Username": "IMAP Username", "Impersonate_user": "Impersonate User", diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index b4e0168c2664..a98b3de13b39 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -95,7 +95,9 @@ Package.onUse(function(api) { api.addFiles('server/lib/configLogger.js', 'server'); api.addFiles('server/lib/PushNotification.js', 'server'); api.addFiles('server/lib/defaultBlockedDomainsList.js', 'server'); + api.addFiles('server/lib/interceptDirectReplyEmails.js', 'server'); api.addFiles('server/lib/notifyUsersOnMessage.js', 'server'); + api.addFiles('server/lib/processDirectEmail.js', 'server'); api.addFiles('server/lib/roomTypes.js', 'server'); api.addFiles('server/lib/sendEmailOnMessage.js', 'server'); api.addFiles('server/lib/sendNotificationsOnMessage.js', 'server'); @@ -161,6 +163,7 @@ Package.onUse(function(api) { api.addFiles('server/methods/setRealName.js', 'server'); api.addFiles('server/methods/setUsername.js', 'server'); api.addFiles('server/methods/setEmail.js', 'server'); + api.addFiles('server/methods/startIMAPIntercepter.js', 'server'); api.addFiles('server/methods/unarchiveRoom.js', 'server'); api.addFiles('server/methods/unblockUser.js', 'server'); api.addFiles('server/methods/updateMessage.js', 'server'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js new file mode 100644 index 000000000000..2431ba719c4a --- /dev/null +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -0,0 +1,93 @@ +const Imap = require('imap'); + +RocketChat.imapIntercepter = function() { + const imap = new Imap({ + user: RocketChat.settings.get('IMAP_Username'), + password: RocketChat.settings.get('IMAP_Password'), + host: RocketChat.settings.get('IMAP_Host'), + port: RocketChat.settings.get('IMAP_Port'), + debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, + tls: !RocketChat.settings.get('IMAP_IgnoreTLS') + }); + + function openInbox(cb) { + imap.openBox('INBOX', false, cb); + } + + function getEmails(imap) { + imap.search(['UNSEEN'], function(err, newEmails) { + if (err) { + console.log(err); + } + + if (newEmails.length > 0) { + const f = imap.fetch(newEmails, { + bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE REFERENCES)', '1'], + struct: true, + markSeen: true + }); + + f.on('message', function(msg) { + const email = {}; + + msg.on('body', function(stream, info) { + let headerBuffer = ''; + let bodyBuffer = ''; + + stream.on('data', function(chunk) { + if (info.which === '1') { + bodyBuffer += chunk.toString('utf8'); + } else { + headerBuffer += chunk.toString('utf8'); + } + }); + stream.once('end', function() { + if (info.which === '1') { + email.body = bodyBuffer; + } else { + email.headers = Imap.parseHeader(headerBuffer); + } + }); + }); + + msg.once('end', function() { + RocketChat.processDirectEmail(email); + }); + }); + f.once('error', function(err) { + console.log(`Fetch error: ${ err }`); + }); + } + }); + } + + imap.once('ready', function() { + openInbox(function(err) { + if (err) { + throw err; + } + getEmails(imap); + + imap.on('mail', function() { + getEmails(imap); + }); + }); + }); + + imap.once('error', function(err) { + console.log(err); + }); + + imap.once('end', function() { + console.log('Connection ended'); + imap.connect(); + }); + + imap.connect(); +}; + +Meteor.startup(function() { + if (RocketChat.settings.get('IMAP_Enable')) { + RocketChat.imapIntercepter(); + } +}); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js new file mode 100644 index 000000000000..1bc4158c10b0 --- /dev/null +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -0,0 +1,6 @@ +const reply = require('emailreplyparser').EmailReplyParser; + +RocketChat.processDirectEmail = function(email) { + email.reply = reply.parse_reply(email.body); + console.log(email); +}; diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 985a7ac2aa88..395c3c5270fe 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -62,6 +62,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); let footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); messageHTML = messageHTML.replace(/\n/gm, '
'); + let From = RocketChat.settings.get('From_Email'); RocketChat.models.Subscriptions.findWithSendEmailByRoomId(room._id).forEach((sub) => { if (sub.disableNotifications) { @@ -114,19 +115,21 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { return; } - let Subject = `[${ siteName }] ${ emailSubject }`; - if (RocketChat.settings.get('IMAP_Enable')) { - Subject += `[${ message.rid } ${ message._id }]`; + From += `+${ message._id }`; footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); } + const ts = new Date().getTime(); user.emails.some((email) => { if (email.verified) { email = { to: email.address, - from: RocketChat.settings.get('From_Email'), - subject: Subject, + from: From, + subject: `[${ siteName }] ${ emailSubject }`, + headers: { + 'Message-ID': `${ ts }+${ message.rid }+${ message._id }@${ email.address.split('@')[1] }` + }, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer }; diff --git a/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js b/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js new file mode 100644 index 000000000000..8700b3b55298 --- /dev/null +++ b/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js @@ -0,0 +1,7 @@ +Meteor.methods({ + startIMAPIntercepter() { + if (RocketChat.settings.get('IMAP_Enable')) { + RocketChat.imapIntercepter(); + } + } +}); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index a42066a70d46..a6b008d8bdee 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -474,6 +474,11 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'IMAP_Enable' }); + this.add('IMAP_Debug', false, { + type: 'boolean', + env: true, + i18nLabel: 'IMAP_Debug' + }); this.add('IMAP_Protocol', 'imap', { type: 'select', values: [{ @@ -492,7 +497,16 @@ RocketChat.settings.addGroup('Email', function() { i18nLabel: 'Host' }); this.add('IMAP_Port', '', { - type: 'string', + type: 'select', + values: [ + { + key: 143, + i18nLabel: '143' + }, { + key: 993, + i18nLabel: '993' + } + ], env: true, i18nLabel: 'Port' }); @@ -516,6 +530,10 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'Password' }); + return this.add('IMAP_Start', 'startIMAPIntercepter', { + type: 'action', + actionText: 'IMAP_Start' + }); }); this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { From d428eb0777799574f396823241969bdd79cbf19c Mon Sep 17 00:00:00 2001 From: trojan Date: Thu, 22 Jun 2017 19:18:55 +0530 Subject: [PATCH 05/56] improved email footer --- packages/rocketchat-lib/server/startup/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index a6b008d8bdee..759722ac0bf7 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -461,7 +461,7 @@ RocketChat.settings.addGroup('Email', function() { multiline: true, i18nLabel: 'Footer' }); - return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.
Do not temper email SubjectPowered by Rocket.Chat', { + return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.
Do not temper email Subject
Powered by Rocket.Chat', { type: 'code', code: 'text/html', multiline: true, From c818311981b134ecf16435d37e283c2be8cdc8b4 Mon Sep 17 00:00:00 2001 From: trojan Date: Thu, 22 Jun 2017 20:11:27 +0530 Subject: [PATCH 06/56] extract email info --- .../server/lib/interceptDirectReplyEmails.js | 1 + .../server/lib/processDirectEmail.js | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 2431ba719c4a..ce594a84b6d5 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -80,6 +80,7 @@ RocketChat.imapIntercepter = function() { imap.once('end', function() { console.log('Connection ended'); + console.log('Retrying IMAP connection...'); imap.connect(); }); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 1bc4158c10b0..711caafde63f 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,6 +1,33 @@ const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { - email.reply = reply.parse_reply(email.body); + email.body = reply.parse_reply(email.body); console.log(email); + + email.headers.to = email.headers.to[0]; + + email.headers.from = email.headers.from[0]; + + if (email.headers.from.indexOf('<') >= 0 && email.headers.from.indexOf('>') >= 0) { + email.headers.from = email.headers.from.split('<')[1]; + email.headers.from = email.headers.from.split('>')[0]; + } + + email.headers.references = email.headers.references[0].split('@')[0]; + email.headers.date = email.headers.date[0]; + + if (email.headers.references.charAt(0) === '<') { + email.headers.references = email.headers.references.substr(1); + } + console.log(email); + + const validEmail = /^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/; + + if (validEmail.test(email.headers.references)) { + console.log('Valid Email'); + email.headers.rid = email.headers.references.split('+')[1]; + email.headers.mid = email.headers.references.split('+')[2]; + } else { + console.log('Invalid Email....'); + } }; From df8b8da1793c75b5c59205fdbef56b2bd43979bc Mon Sep 17 00:00:00 2001 From: trojan Date: Fri, 23 Jun 2017 08:27:00 +0530 Subject: [PATCH 07/56] Email sending refactored.Reply-To along with Message-ID for backup --- .../server/lib/processDirectEmail.js | 24 +++++++++------ .../server/lib/sendEmailOnMessage.js | 30 ++++++++++++------- .../rocketchat-lib/server/startup/settings.js | 2 +- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 711caafde63f..fa92d4d568fe 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -5,29 +5,35 @@ RocketChat.processDirectEmail = function(email) { console.log(email); email.headers.to = email.headers.to[0]; + // if email format is "Name " + if (email.headers.to.indexOf('<') >= 0 && email.headers.to.indexOf('>') >= 0) { + email.headers.to = email.headers.to.split('<')[1].split('>')[0]; + } email.headers.from = email.headers.from[0]; - + // if email format is "Name " if (email.headers.from.indexOf('<') >= 0 && email.headers.from.indexOf('>') >= 0) { - email.headers.from = email.headers.from.split('<')[1]; - email.headers.from = email.headers.from.split('>')[0]; + email.headers.from = email.headers.from.split('<')[1].split('>')[0]; } - email.headers.references = email.headers.references[0].split('@')[0]; email.headers.date = email.headers.date[0]; + email.headers.references = email.headers.references[0].split('@')[0]; + // references are of format "" if (email.headers.references.charAt(0) === '<') { email.headers.references = email.headers.references.substr(1); } - console.log(email); - - const validEmail = /^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/; - if (validEmail.test(email.headers.references)) { + if (email.headers.to.indexOf('+') >= 0) { // if reply+messageID@domain format + console.log('Valid Email'); + email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; + console.log(email); + } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { // if references info is valid ie format "ts+roomID+messageID@domain" console.log('Valid Email'); email.headers.rid = email.headers.references.split('+')[1]; email.headers.mid = email.headers.references.split('+')[2]; + console.log(email); } else { - console.log('Invalid Email....'); + console.log('Invalid Email....If not. Please report it.'); } }; diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 395c3c5270fe..ea0aeb9e4a87 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -62,7 +62,6 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); let footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); messageHTML = messageHTML.replace(/\n/gm, '
'); - let From = RocketChat.settings.get('From_Email'); RocketChat.models.Subscriptions.findWithSendEmailByRoomId(room._id).forEach((sub) => { if (sub.disableNotifications) { @@ -116,22 +115,31 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { } if (RocketChat.settings.get('IMAP_Enable')) { - From += `+${ message._id }`; footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); } const ts = new Date().getTime(); user.emails.some((email) => { if (email.verified) { - email = { - to: email.address, - from: From, - subject: `[${ siteName }] ${ emailSubject }`, - headers: { - 'Message-ID': `${ ts }+${ message.rid }+${ message._id }@${ email.address.split('@')[1] }` - }, - html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer - }; + if (RocketChat.settings.get('IMAP_Enable')) { + email = { + to: email.address, + from: RocketChat.settings.get('From_Email'), + subject: `[${ siteName }] ${ emailSubject }`, + headers: { + 'Reply-To' : `${ RocketChat.settings.get('IMAP_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('IMAP_Username').split('@')[1] }`, + 'Message-ID': `${ ts }+${ message.rid }+${ message._id }@${ email.address.split('@')[1] }` + }, + html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer + }; + } else { + email = { + to: email.address, + from: RocketChat.settings.get('From_Email'), + subject: `[${ siteName }] ${ emailSubject }`, + html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer + }; + } Meteor.defer(() => { Email.send(email); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 759722ac0bf7..d9726e53d350 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -461,7 +461,7 @@ RocketChat.settings.addGroup('Email', function() { multiline: true, i18nLabel: 'Footer' }); - return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.
Do not temper email Subject
Powered by Rocket.Chat', { + return this.add('Email_Footer_Direct_Reply', 'You can directly reply to this email.
Do not temper reply email
Powered by Rocket.Chat', { type: 'code', code: 'text/html', multiline: true, From 8883de3608f7742ed1234b7d8dcc8e589edb5444 Mon Sep 17 00:00:00 2001 From: trojan Date: Fri, 23 Jun 2017 08:32:20 +0530 Subject: [PATCH 08/56] remove unwanted deps --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 5956855a13a0..32ac5830615f 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,6 @@ "mime-type": "^3.0.5", "moment": "^2.18.1", "moment-timezone": "^0.5.13", - "node-email-reply-parser": "0.0.1", "photoswipe": "^4.1.2", "prom-client": "^9.0.0", "semver": "^5.3.0", From da8e0a46a0a75de3e6d74eb2ea69993ffb3ae007 Mon Sep 17 00:00:00 2001 From: trojan Date: Fri, 23 Jun 2017 19:52:11 +0530 Subject: [PATCH 09/56] Constraint IMAP info & show error --- .../rocketchat-lib/server/lib/interceptDirectReplyEmails.js | 2 +- .../rocketchat-lib/server/methods/startIMAPIntercepter.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index ce594a84b6d5..b70846699013 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -88,7 +88,7 @@ RocketChat.imapIntercepter = function() { }; Meteor.startup(function() { - if (RocketChat.settings.get('IMAP_Enable')) { + if (RocketChat.settings.get('IMAP_Enable') && RocketChat.settings.get('IMAP_Host') && RocketChat.settings.get('IMAP_Port') && RocketChat.settings.get('IMAP_Username') && RocketChat.settings.get('IMAP_Password')) { RocketChat.imapIntercepter(); } }); diff --git a/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js b/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js index 8700b3b55298..ce4aec4dc67d 100644 --- a/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js @@ -1,7 +1,9 @@ Meteor.methods({ startIMAPIntercepter() { - if (RocketChat.settings.get('IMAP_Enable')) { + if (RocketChat.settings.get('IMAP_Enable') && RocketChat.settings.get('IMAP_Host') && RocketChat.settings.get('IMAP_Port') && RocketChat.settings.get('IMAP_Username') && RocketChat.settings.get('IMAP_Password')) { RocketChat.imapIntercepter(); + } else { + throw new Meteor.Error('Please fill all information.'); } } }); From 585623b691758a830f64d94fb0d432d156dc1dfa Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 25 Jun 2017 22:24:03 +0530 Subject: [PATCH 10/56] fix eslint --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index fa92d4d568fe..96b1f8ddc296 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -19,16 +19,16 @@ RocketChat.processDirectEmail = function(email) { email.headers.date = email.headers.date[0]; email.headers.references = email.headers.references[0].split('@')[0]; - // references are of format "" + if (email.headers.references.charAt(0) === '<') { email.headers.references = email.headers.references.substr(1); } - if (email.headers.to.indexOf('+') >= 0) { // if reply+messageID@domain format + if (email.headers.to.indexOf('+') >= 0) { console.log('Valid Email'); email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; console.log(email); - } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { // if references info is valid ie format "ts+roomID+messageID@domain" + } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { console.log('Valid Email'); email.headers.rid = email.headers.references.split('+')[1]; email.headers.mid = email.headers.references.split('+')[2]; From 75ebf82ab545028b42cff24a4f6a3b991fbefd3c Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 25 Jun 2017 22:50:03 +0530 Subject: [PATCH 11/56] resolve conflict in package.json --- package.json | 209 +++++++++++++++++++++++++-------------------------- 1 file changed, 101 insertions(+), 108 deletions(-) diff --git a/package.json b/package.json index 32ac5830615f..f8eb4e60f0ef 100644 --- a/package.json +++ b/package.json @@ -1,110 +1,103 @@ { - "name": "Rocket.Chat", - "description": "The Ultimate Open Source WebChat Platform", - "version": "0.57.0-develop", - "author": { - "name": "Rocket.Chat", - "url": "https://rocket.chat/" - }, - "contributors": [ - { - "name": "Aaron Ogle", - "email": "aaron.ogle@rocket.chat" - }, - { - "name": "Bradley Hilton", - "email": "bradley.hilton@rocket.chat" - }, - { - "name": "Diego Sampaio", - "email": "diego.sampaio@rocket.chat" - }, - { - "name": "Gabriel Engel", - "email": "gabriel.engel@rocket.chat" - }, - { - "name": "Marcelo Schmidt", - "email": "marcelo.schmidt@rocket.chat" - }, - { - "name": "Rodrigo Nascimento", - "email": "rodrigo.nascimento@rocket.chat" - }, - { - "name": "Sing Li", - "email": "sing.li@rocket.chat" - } - ], - "mocha": { - "tests": [ - "packages/**/*.tests.js" - ], - "files": [ - "packages/**/*.js", - "!packages/**/*.tests.js" - ] - }, - "keywords": [ - "rocketchat", - "rocket", - "chat" - ], - "scripts": { - "start": "meteor npm i && meteor", - "lint": "eslint .", - "lint-fix": "eslint . --fix", - "stylelint": "stylelint packages/**/*.{less,css}", - "test": "node .scripts/start.js", - "deploy": "npm run build && pm2 startOrRestart pm2.json", - "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests/end-to-end", - "chimp-test": "chimp tests/chimp-config.js", - "postinstall": "cd packages/rocketchat-katex && npm i", - "testunit-watch": "mocha --watch --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "coverage": "nyc -r html mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "testunit": "mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", - "version": "node .scripts/version.js", - "set-version": "node .scripts/set-version.js", - "release": "npm run set-version --silent" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/RocketChat/Rocket.Chat.git" - }, - "bugs": { - "url": "https://github.com/RocketChat/Rocket.Chat/issues", - "email": "support@rocket.chat" - }, - "devDependencies": { - "babel-mocha-es6-compiler": "^0.1.0", - "babel-plugin-array-includes": "^2.0.3", - "chimp": "^0.49.0", - "conventional-changelog": "^1.1.3", - "eslint": "^3.19.0", - "postcss-cssnext": "^2.11.0", - "postcss-smart-import": "^0.7.2", - "stylelint": "^7.10.1", - "supertest": "^3.0.0" - }, - "dependencies": { - "@google-cloud/storage": "^1.1.1", - "aws-sdk": "^2.55.0", - "babel-runtime": "^6.23.0", - "bcrypt": "^1.0.2", - "codemirror": "^5.26.0", - "emailreplyparser": "0.0.5", - "file-type": "^4.3.0", - "highlight.js": "^9.12.0", - "imap": "^0.8.19", - "jquery": "^3.2.1", - "mime-db": "^1.28.0", - "mime-type": "^3.0.5", - "moment": "^2.18.1", - "moment-timezone": "^0.5.13", - "photoswipe": "^4.1.2", - "prom-client": "^9.0.0", - "semver": "^5.3.0", - "toastr": "^2.1.2" - } + "name": "Rocket.Chat", + "description": "The Ultimate Open Source WebChat Platform", + "version": "0.57.0-develop", + "author": { + "name": "Rocket.Chat", + "url": "https://rocket.chat/" + }, + "contributors": [{ + "name": "Aaron Ogle", + "email": "aaron.ogle@rocket.chat" + }, { + "name": "Bradley Hilton", + "email": "bradley.hilton@rocket.chat" + }, { + "name": "Diego Sampaio", + "email": "diego.sampaio@rocket.chat" + }, { + "name": "Gabriel Engel", + "email": "gabriel.engel@rocket.chat" + }, { + "name": "Marcelo Schmidt", + "email": "marcelo.schmidt@rocket.chat" + }, { + "name": "Rodrigo Nascimento", + "email": "rodrigo.nascimento@rocket.chat" + }, { + "name": "Sing Li", + "email": "sing.li@rocket.chat" + }], + "mocha": { + "tests": [ + "packages/**/*.tests.js" + ], + "files": [ + "packages/**/*.js", + "!packages/**/*.tests.js" + ] + }, + "keywords": [ + "rocketchat", + "rocket", + "chat" + ], + "scripts": { + "start": "meteor npm i && meteor", + "lint": "eslint .", + "lint-fix": "eslint . --fix", + "stylelint": "stylelint packages/**/*.{less,css}", + "test": "node .scripts/start.js", + "deploy": "npm run build && pm2 startOrRestart pm2.json", + "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests/end-to-end", + "chimp-test": "chimp tests/chimp-config.js", + "postinstall": "cd packages/rocketchat-katex && npm i", + "testunit-watch": "mocha --watch --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "coverage": "nyc -r html mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "testunit": "mocha --opts ./mocha.opts \"`node -e \"console.log(require('./package.json').mocha.tests.join(' '))\"`\"", + "version": "node .scripts/version.js", + "set-version": "node .scripts/set-version.js", + "release": "npm run set-version --silent" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/RocketChat/Rocket.Chat.git" + }, + "bugs": { + "url": "https://github.com/RocketChat/Rocket.Chat/issues", + "email": "support@rocket.chat" + }, + "devDependencies": { + "babel-mocha-es6-compiler": "^0.1.0", + "babel-plugin-array-includes": "^2.0.3", + "chimp": "^0.49.0", + "conventional-changelog": "^1.1.3", + "eslint": "^3.19.0", + "postcss-cssnext": "^2.11.0", + "postcss-smart-import": "^0.7.2", + "stylelint": "^7.10.1", + "supertest": "^3.0.0" + }, + "dependencies": { + "@google-cloud/storage": "^1.1.1", + "aws-sdk": "^2.55.0", + "babel-runtime": "^6.23.0", + "bcrypt": "^1.0.2", + "codemirror": "^5.26.0", + "emailreplyparser": "0.0.5", + "file-type": "^4.3.0", + "highlight.js": "^9.12.0", + "imap": "^0.8.19", + "jquery": "^3.2.1", + "mime-db": "^1.28.0", + "mime-type": "^3.0.5", + "moment": "^2.18.1", + "moment-timezone": "^0.5.13", + "photoswipe": "^4.1.2", + "prom-client": "^9.0.0", + "semver": "^5.3.0", + "toastr": "^2.1.2" + } } + From 5b7c0f64f130b27386ade764c90d919a7ed1e237 Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 25 Jun 2017 22:55:06 +0530 Subject: [PATCH 12/56] fix eslint --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 96b1f8ddc296..b3f36e288eae 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -5,13 +5,13 @@ RocketChat.processDirectEmail = function(email) { console.log(email); email.headers.to = email.headers.to[0]; - // if email format is "Name " + if (email.headers.to.indexOf('<') >= 0 && email.headers.to.indexOf('>') >= 0) { email.headers.to = email.headers.to.split('<')[1].split('>')[0]; } email.headers.from = email.headers.from[0]; - // if email format is "Name " + if (email.headers.from.indexOf('<') >= 0 && email.headers.from.indexOf('>') >= 0) { email.headers.from = email.headers.from.split('<')[1].split('>')[0]; } From 06ba63984c8c84e9674e479fd39f27d21ae62efc Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 25 Jun 2017 22:59:36 +0530 Subject: [PATCH 13/56] resolve conflict in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8eb4e60f0ef..378fa72252cb 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "bcrypt": "^1.0.2", "codemirror": "^5.26.0", "emailreplyparser": "0.0.5", - "file-type": "^4.3.0", + "file-type": "^5.2.0", "highlight.js": "^9.12.0", "imap": "^0.8.19", "jquery": "^3.2.1", From 3ea675c96c7f5023f896c0e9f912434bfcdf160d Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 25 Jun 2017 23:05:31 +0530 Subject: [PATCH 14/56] resolve conflict --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 378fa72252cb..5e5b4a31857e 100644 --- a/package.json +++ b/package.json @@ -100,4 +100,3 @@ "toastr": "^2.1.2" } } - From cc32ba41edce956607ffbaceb2dda03f8780297e Mon Sep 17 00:00:00 2001 From: trojan Date: Tue, 27 Jun 2017 00:19:28 +0530 Subject: [PATCH 15/56] supporting comments --- .../server/lib/interceptDirectReplyEmails.js | 10 ++++++++++ .../rocketchat-lib/server/lib/processDirectEmail.js | 10 +++++++++- .../rocketchat-lib/server/lib/sendEmailOnMessage.js | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index b70846699013..8f088598cc0a 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -14,14 +14,18 @@ RocketChat.imapIntercepter = function() { imap.openBox('INBOX', false, cb); } + // Fetch all UNSEEN messages and pass them for further processing function getEmails(imap) { imap.search(['UNSEEN'], function(err, newEmails) { if (err) { console.log(err); + throw err; } + // newEmails => array containing serials of unseen messages if (newEmails.length > 0) { const f = imap.fetch(newEmails, { + // fetch headers & first body part. bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE REFERENCES)', '1'], struct: true, markSeen: true @@ -41,6 +45,7 @@ RocketChat.imapIntercepter = function() { headerBuffer += chunk.toString('utf8'); } }); + stream.once('end', function() { if (info.which === '1') { email.body = bodyBuffer; @@ -50,6 +55,7 @@ RocketChat.imapIntercepter = function() { }); }); + // On fetched each message, pass it further msg.once('end', function() { RocketChat.processDirectEmail(email); }); @@ -61,13 +67,16 @@ RocketChat.imapIntercepter = function() { }); } + // On successfully connected. imap.once('ready', function() { openInbox(function(err) { if (err) { throw err; } + // fetch new emails & wait [IDLE] getEmails(imap); + // If new message arrived, fetch them imap.on('mail', function() { getEmails(imap); }); @@ -76,6 +85,7 @@ RocketChat.imapIntercepter = function() { imap.once('error', function(err) { console.log(err); + throw err; }); imap.once('end', function() { diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index b3f36e288eae..18b742c7328d 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,34 +1,42 @@ const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { + // Extract/parse reply from email body email.body = reply.parse_reply(email.body); console.log(email); email.headers.to = email.headers.to[0]; + // if 'To' email format is "Name " if (email.headers.to.indexOf('<') >= 0 && email.headers.to.indexOf('>') >= 0) { email.headers.to = email.headers.to.split('<')[1].split('>')[0]; } email.headers.from = email.headers.from[0]; + // if 'From' email format is "Name " if (email.headers.from.indexOf('<') >= 0 && email.headers.from.indexOf('>') >= 0) { email.headers.from = email.headers.from.split('<')[1].split('>')[0]; } email.headers.date = email.headers.date[0]; - email.headers.references = email.headers.references[0].split('@')[0]; + email.headers.references = email.headers.references[0]; + // references format is "" + email.headers.references = email.headers.references.split('@')[0]; if (email.headers.references.charAt(0) === '<') { email.headers.references = email.headers.references.substr(1); } + // 'To' email format "username+messageId@domain" if (email.headers.to.indexOf('+') >= 0) { + // Valid 'To' format console.log('Valid Email'); email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; console.log(email); } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { + // Valid references(Message-ID) format console.log('Valid Email'); email.headers.rid = email.headers.references.split('+')[1]; email.headers.mid = email.headers.references.split('+')[2]; diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index ea0aeb9e4a87..4531ca2c8218 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -114,6 +114,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { return; } + // Footer in case direct reply is enabled. if (RocketChat.settings.get('IMAP_Enable')) { footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); } @@ -121,13 +122,16 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { user.emails.some((email) => { if (email.verified) { + // If direct reply enabled, email content with headers if (RocketChat.settings.get('IMAP_Enable')) { email = { to: email.address, from: RocketChat.settings.get('From_Email'), subject: `[${ siteName }] ${ emailSubject }`, headers: { + // Reply-To header with format "username+messageId@domain" 'Reply-To' : `${ RocketChat.settings.get('IMAP_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('IMAP_Username').split('@')[1] }`, + // Message-ID header with format "timestamp+roomId+messageId@domain" 'Message-ID': `${ ts }+${ message.rid }+${ message._id }@${ email.address.split('@')[1] }` }, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer From b4e80b7f059284a355c06743cd480c397e5fa83d Mon Sep 17 00:00:00 2001 From: trojan Date: Sun, 2 Jul 2017 12:40:31 +0530 Subject: [PATCH 16/56] imap info Bug fix --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 8 ++++++-- packages/rocketchat-lib/server/startup/settings.js | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 18b742c7328d..5e72912e88a1 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,6 +1,10 @@ const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { + function sendMessage(email) { + console.log(email); + } + // Extract/parse reply from email body email.body = reply.parse_reply(email.body); console.log(email); @@ -34,13 +38,13 @@ RocketChat.processDirectEmail = function(email) { // Valid 'To' format console.log('Valid Email'); email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; - console.log(email); + sendMessage(email); } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { // Valid references(Message-ID) format console.log('Valid Email'); email.headers.rid = email.headers.references.split('+')[1]; email.headers.mid = email.headers.references.split('+')[2]; - console.log(email); + sendMessage(email); } else { console.log('Invalid Email....If not. Please report it.'); } diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index d9726e53d350..ded745c9d6ea 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -496,7 +496,7 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'Host' }); - this.add('IMAP_Port', '', { + this.add('IMAP_Port', 143, { type: 'select', values: [ { From 1ab89bc48fa0e8cb5a0951a728321ac478294049 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sun, 2 Jul 2017 19:33:28 +0530 Subject: [PATCH 17/56] imap => direct_reply, settings --- packages/rocketchat-i18n/i18n/en.i18n.json | 21 ++- packages/rocketchat-lib/package.js | 10 +- .../server/lib/interceptDirectReplyEmails.js | 10 +- .../server/lib/processDirectEmail.js | 36 +++- .../server/methods/startEmailIntercepter.js | 12 ++ .../server/methods/startIMAPIntercepter.js | 9 - .../rocketchat-lib/server/startup/settings.js | 154 ++++++++---------- 7 files changed, 143 insertions(+), 109 deletions(-) create mode 100644 packages/rocketchat-lib/server/methods/startEmailIntercepter.js delete mode 100644 packages/rocketchat-lib/server/methods/startIMAPIntercepter.js diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index cac12e71d105..a202066bb20f 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -419,6 +419,16 @@ "Desktop_Notifications_Enabled": "Desktop Notifications are Enabled", "Direct_message_someone": "Direct message someone", "Direct_Messages": "Direct Messages", + "Direct_Reply": "Direct Reply", + "Direct_Reply_Debug": "Debug Direct Reply", + "Direct_Reply_Enable": "Enable Direct Reply", + "Direct_Reply_Protocol": "Direct Reply Protocol", + "Direct_Reply_Host": "Direct Reply Host", + "Direct_Reply_Port": "Direct_Reply_Port", + "Direct_Reply_IgnoreTLS": "IgnoreTLS", + "Direct_Reply_Username": "Username", + "Direct_Reply_Password": "Password", + "Direct_Reply_Start": "Start Direct Reply", "Disable_Notifications": "Disable Notifications", "Disable_two-factor_authentication": "Disable two-factor authentication", "Display_offline_form": "Display offline form", @@ -709,17 +719,6 @@ "Installed_at": "Installed at", "Instance_Record": "Instance Record", "Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message", - "IMAP": "IMAP", - "IMAP_Debug": "Debug", - "IMAP_Enable": "Enable Direct Reply", - "IMAP_Host": "IMAP Host", - "IMAP_IgnoreTLS": "Ignore TLS", - "IMAP_Password": "IMAP Password", - "IMAP_Port": "IMAP Port", - "IMAP_Protocol": "IMAP Protocol", - "IMAP_Start": "Start", - "IMAP_Test_Button": "Test IMAP Settings", - "IMAP_Username": "IMAP Username", "Impersonate_user": "Impersonate User", "Impersonate_user_description": "When enabled, integration posts as the user that triggered integration", "Incoming_WebHook": "Incoming WebHook", diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index 0ee4f833ef5d..b6f26736e53f 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -39,8 +39,12 @@ Package.onUse(function(api) { api.use('rocketchat:version'); api.use('rocketchat:logger'); api.use('rocketchat:custom-oauth'); - api.use('rocketchat:authorization', {unordered: true}); - api.use('rocketchat:push-notifications', {unordered: true}); + api.use('rocketchat:authorization', { + unordered: true + }); + api.use('rocketchat:push-notifications', { + unordered: true + }); api.use('templating', 'client'); api.use('kadira:flow-router'); @@ -164,7 +168,7 @@ Package.onUse(function(api) { api.addFiles('server/methods/setRealName.js', 'server'); api.addFiles('server/methods/setUsername.js', 'server'); api.addFiles('server/methods/setEmail.js', 'server'); - api.addFiles('server/methods/startIMAPIntercepter.js', 'server'); + api.addFiles('server/methods/startEmailIntercepter.js', 'server'); api.addFiles('server/methods/unarchiveRoom.js', 'server'); api.addFiles('server/methods/unblockUser.js', 'server'); api.addFiles('server/methods/updateMessage.js', 'server'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 8f088598cc0a..61d9738ad5da 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -7,7 +7,9 @@ RocketChat.imapIntercepter = function() { host: RocketChat.settings.get('IMAP_Host'), port: RocketChat.settings.get('IMAP_Port'), debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, - tls: !RocketChat.settings.get('IMAP_IgnoreTLS') + tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), + connTimeout: 30000, + keepalive: true }); function openInbox(cb) { @@ -98,7 +100,9 @@ RocketChat.imapIntercepter = function() { }; Meteor.startup(function() { - if (RocketChat.settings.get('IMAP_Enable') && RocketChat.settings.get('IMAP_Host') && RocketChat.settings.get('IMAP_Port') && RocketChat.settings.get('IMAP_Username') && RocketChat.settings.get('IMAP_Password')) { - RocketChat.imapIntercepter(); + if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { + if (RocketChat.settings.get('Direct_Reply_Protocol') === "IMAP") { + RocketChat.imapIntercepter(); + } } }); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 5e72912e88a1..fe6e91e47ea7 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,13 +1,47 @@ +import moment from 'moment'; const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { function sendMessage(email) { console.log(email); + let message = { + ts: email.headers.date, + msg: email.body + }; + + if (message.ts) { + const tsDiff = Math.abs(moment(message.ts).diff()); + if (tsDiff > 60000) { + throw new Meteor.Error('error-message-ts-out-of-sync', 'Message timestamp is out of sync', { + method: 'sendMessage', + message_ts: message.ts, + server_ts: new Date().getTime() + }); + } else if (tsDiff > 10000) { + message.ts = new Date(); + } + } else { + message.ts = new Date(); + } + if (message.msg && message.msg.length > RocketChat.settings.get('Message_MaxAllowedSize')) { + throw new Meteor.Error('error-message-size-exceeded', 'Message size exceeds Message_MaxAllowedSize', { + method: 'sendMessage' + }); + } + + const user = RocketChat.models.Users.findOneByEmailAddress(email.headers.from, { + fields: { + username: 1, + name: 1 + } + }); + if (!user) { + return false; + } } // Extract/parse reply from email body email.body = reply.parse_reply(email.body); - console.log(email); email.headers.to = email.headers.to[0]; diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js new file mode 100644 index 000000000000..5f52a7ee154a --- /dev/null +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -0,0 +1,12 @@ +Meteor.methods({ + startEmailIntercepter() { + if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { + if (RocketChat.settings.get('Direct_Reply_Protocol') === "IMAP") { + RocketChat.imapIntercepter(); + return true; + } + } else { + throw new Meteor.Error('Please fill all the information.'); + } + } +}); diff --git a/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js b/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js deleted file mode 100644 index ce4aec4dc67d..000000000000 --- a/packages/rocketchat-lib/server/methods/startIMAPIntercepter.js +++ /dev/null @@ -1,9 +0,0 @@ -Meteor.methods({ - startIMAPIntercepter() { - if (RocketChat.settings.get('IMAP_Enable') && RocketChat.settings.get('IMAP_Host') && RocketChat.settings.get('IMAP_Port') && RocketChat.settings.get('IMAP_Username') && RocketChat.settings.get('IMAP_Password')) { - RocketChat.imapIntercepter(); - } else { - throw new Meteor.Error('Please fill all information.'); - } - } -}); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index ded745c9d6ea..28c075cbcd15 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -116,18 +116,16 @@ RocketChat.settings.addGroup('Accounts', function() { this.add('Accounts_RegistrationForm', 'Public', { type: 'select', 'public': true, - values: [ - { - key: 'Public', - i18nLabel: 'Accounts_RegistrationForm_Public' - }, { - key: 'Disabled', - i18nLabel: 'Accounts_RegistrationForm_Disabled' - }, { - key: 'Secret URL', - i18nLabel: 'Accounts_RegistrationForm_Secret_URL' - } - ] + values: [{ + key: 'Public', + i18nLabel: 'Accounts_RegistrationForm_Public' + }, { + key: 'Disabled', + i18nLabel: 'Accounts_RegistrationForm_Disabled' + }, { + key: 'Secret URL', + i18nLabel: 'Accounts_RegistrationForm_Secret_URL' + }] }); this.add('Accounts_RegistrationForm_SecretURL', Random.id(), { type: 'string' @@ -468,85 +466,83 @@ RocketChat.settings.addGroup('Email', function() { i18nLabel: 'Footer_Direct_Reply' }); }); - this.section('IMAP', function() { - this.add('IMAP_Enable', false, { + this.section('Direct_Reply', function() { + this.add('Direct_Reply_Enable', false, { type: 'boolean', env: true, - i18nLabel: 'IMAP_Enable' + i18nLabel: 'Direct_Reply_Enable' }); - this.add('IMAP_Debug', false, { + this.add('Direct_Reply_Debug', false, { type: 'boolean', env: true, - i18nLabel: 'IMAP_Debug' + i18nLabel: 'Direct_Reply_Debug' }); - this.add('IMAP_Protocol', 'imap', { + this.add('Direct_Reply_Protocol', 'IMAP', { type: 'select', values: [{ - key: 'imap', - i18nLabel: 'imap' + key: 'IMAP', + i18nLabel: 'IMAP' }, { - key: 'imaps', - i18nLabel: 'imaps' + key: 'POP', + i18nLabel: 'POP' }], env: true, i18nLabel: 'Protocol' }); - this.add('IMAP_Host', '', { + this.add('Direct_Reply_Host', '', { type: 'string', env: true, i18nLabel: 'Host' }); - this.add('IMAP_Port', 143, { + this.add('Direct_Reply_Port', 143, { type: 'select', - values: [ - { - key: 143, - i18nLabel: '143' - }, { - key: 993, - i18nLabel: '993' - } - ], + values: [{ + key: 143, + i18nLabel: '143' + }, { + key: 993, + i18nLabel: '993' + }, { + key: 110, + i18nLabel: '110' + }, { + key: 995, + i18nLabel: '995' + }], env: true, i18nLabel: 'Port' }); - this.add('IMAP_IgnoreTLS', false, { + this.add('Direct_Reply_IgnoreTLS', false, { type: 'boolean', env: true, - i18nLabel: 'IgnoreTLS', - enableQuery: { - _id: 'IMAP_Protocol', - value: 'imap' - } + i18nLabel: 'IgnoreTLS' }); - this.add('IMAP_Username', '', { + this.add('Direct_Reply_Username', '', { type: 'string', env: true, i18nLabel: 'Username', placeholder: 'email@domain' }); - this.add('IMAP_Password', '', { + this.add('Direct_Reply_Password', '', { type: 'password', env: true, i18nLabel: 'Password' }); - return this.add('IMAP_Start', 'startIMAPIntercepter', { + return this.add('Direct_Reply_Start', 'startEmailIntercepter', { type: 'action', - actionText: 'IMAP_Start' + actionText: 'Direct_Reply_Start' }); }); this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { type: 'select', - values: [ - { - key: 'smtp', - i18nLabel: 'smtp' - }, { - key: 'smtps', - i18nLabel: 'smtps' - } - ], + values: [{ + key: 'smtp', + i18nLabel: 'smtp' + }, { + key: 'smtps', + i18nLabel: 'smtps' + }], env: true, i18nLabel: 'Protocol' }); @@ -946,28 +942,24 @@ RocketChat.settings.addGroup('Push', function() { }); this.add('Push_gateway', 'https://gateway.rocket.chat', { type: 'string', - enableQuery: [ - { - _id: 'Push_enable', - value: true - }, { - _id: 'Push_enable_gateway', - value: true - } - ] + enableQuery: [{ + _id: 'Push_enable', + value: true + }, { + _id: 'Push_enable_gateway', + value: true + }] }); this.add('Push_production', true, { type: 'boolean', 'public': true, - enableQuery: [ - { - _id: 'Push_enable', - value: true - }, { - _id: 'Push_enable_gateway', - value: false - } - ] + enableQuery: [{ + _id: 'Push_enable', + value: true + }, { + _id: 'Push_enable_gateway', + value: false + }] }); this.add('Push_test_push', 'push_test', { type: 'action', @@ -1091,18 +1083,16 @@ RocketChat.settings.addGroup('Layout', function() { RocketChat.settings.addGroup('Logs', function() { this.add('Log_Level', '0', { type: 'select', - values: [ - { - key: '0', - i18nLabel: '0_Errors_Only' - }, { - key: '1', - i18nLabel: '1_Errors_and_Information' - }, { - key: '2', - i18nLabel: '2_Erros_Information_and_Debug' - } - ], + values: [{ + key: '0', + i18nLabel: '0_Errors_Only' + }, { + key: '1', + i18nLabel: '1_Errors_and_Information' + }, { + key: '2', + i18nLabel: '2_Erros_Information_and_Debug' + }], 'public': true }); this.add('Log_Package', false, { From b60b1f16ae6bd597a11a444e1123e70570ec583d Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sun, 2 Jul 2017 19:37:15 +0530 Subject: [PATCH 18/56] meteor fiber error --- .../rocketchat-lib/server/lib/processDirectEmail.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index fe6e91e47ea7..e7b1757e5825 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -28,16 +28,6 @@ RocketChat.processDirectEmail = function(email) { method: 'sendMessage' }); } - - const user = RocketChat.models.Users.findOneByEmailAddress(email.headers.from, { - fields: { - username: 1, - name: 1 - } - }); - if (!user) { - return false; - } } // Extract/parse reply from email body From 3219105c118ddd98f41f42c7f93c68c5464155bf Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sun, 2 Jul 2017 19:40:45 +0530 Subject: [PATCH 19/56] codecy fix --- .../rocketchat-lib/server/lib/interceptDirectReplyEmails.js | 2 +- packages/rocketchat-lib/server/lib/processDirectEmail.js | 2 ++ packages/rocketchat-lib/server/methods/startEmailIntercepter.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 61d9738ad5da..d0080fcbef46 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -101,7 +101,7 @@ RocketChat.imapIntercepter = function() { Meteor.startup(function() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { - if (RocketChat.settings.get('Direct_Reply_Protocol') === "IMAP") { + if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { RocketChat.imapIntercepter(); } } diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index e7b1757e5825..6b76691c0d3c 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -28,6 +28,8 @@ RocketChat.processDirectEmail = function(email) { method: 'sendMessage' }); } + + console.log(message); } // Extract/parse reply from email body diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index 5f52a7ee154a..0089d00ecb3d 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -1,7 +1,7 @@ Meteor.methods({ startEmailIntercepter() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { - if (RocketChat.settings.get('Direct_Reply_Protocol') === "IMAP") { + if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { RocketChat.imapIntercepter(); return true; } From 41aaae544d965c38ae0c818ac9fcd1fa8f6698d3 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Wed, 5 Jul 2017 21:26:02 +0530 Subject: [PATCH 20/56] send Message --- .../server/lib/interceptDirectReplyEmails.js | 24 ++--- .../server/lib/processDirectEmail.js | 88 +++++++++++++++---- .../rocketchat-lib/server/models/Messages.js | 4 + 3 files changed, 87 insertions(+), 29 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index d0080fcbef46..ae3ace8c5c59 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -18,7 +18,7 @@ RocketChat.imapIntercepter = function() { // Fetch all UNSEEN messages and pass them for further processing function getEmails(imap) { - imap.search(['UNSEEN'], function(err, newEmails) { + imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { if (err) { console.log(err); throw err; @@ -33,7 +33,7 @@ RocketChat.imapIntercepter = function() { markSeen: true }); - f.on('message', function(msg) { + f.on('message', Meteor.bindEnvironment(function(msg) { const email = {}; msg.on('body', function(stream, info) { @@ -58,20 +58,20 @@ RocketChat.imapIntercepter = function() { }); // On fetched each message, pass it further - msg.once('end', function() { + msg.once('end', Meteor.bindEnvironment(function() { RocketChat.processDirectEmail(email); - }); - }); + })); + })); f.once('error', function(err) { console.log(`Fetch error: ${ err }`); }); } - }); + })); } // On successfully connected. - imap.once('ready', function() { - openInbox(function(err) { + imap.once('ready', Meteor.bindEnvironment(function() { + openInbox(Meteor.bindEnvironment(function(err) { if (err) { throw err; } @@ -79,11 +79,11 @@ RocketChat.imapIntercepter = function() { getEmails(imap); // If new message arrived, fetch them - imap.on('mail', function() { + imap.on('mail', Meteor.bindEnvironment(function() { getEmails(imap); - }); - }); - }); + })); + })); + })); imap.once('error', function(err) { console.log(err); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 6b76691c0d3c..ffb2a3c3f26f 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -5,31 +5,85 @@ RocketChat.processDirectEmail = function(email) { function sendMessage(email) { console.log(email); let message = { - ts: email.headers.date, + ts: new Date(email.headers.date), msg: email.body }; - if (message.ts) { - const tsDiff = Math.abs(moment(message.ts).diff()); - if (tsDiff > 60000) { - throw new Meteor.Error('error-message-ts-out-of-sync', 'Message timestamp is out of sync', { - method: 'sendMessage', - message_ts: message.ts, - server_ts: new Date().getTime() - }); - } else if (tsDiff > 10000) { - message.ts = new Date(); - } - } else { + if (!message.ts) { message.ts = new Date(); } + if (message.msg && message.msg.length > RocketChat.settings.get('Message_MaxAllowedSize')) { - throw new Meteor.Error('error-message-size-exceeded', 'Message size exceeds Message_MaxAllowedSize', { - method: 'sendMessage' - }); + return false; + } + + const user = RocketChat.models.Users.findOneByEmailAddress(email.headers.from, { + fields: { + username: 1, + name: 1 + } + }); + if (!user) { + // user not found + return false; + } + + const prevMessage = RocketChat.models.Messages.findOneById(email.headers.mid, { + rid: 1, + u: 1 + }); + if (!prevMessage) { + // message doesn't exist anymore + return false; + } + message.rid = prevMessage.rid; + + const room = Meteor.call('canAccessRoom', message.rid, user._id); + if (!room) { + return false; + } + + // check mention + if (message.msg.indexOf('@' + prevMessage.u.username) === -1) { + message.msg = '@' + prevMessage.u.username + ' ' + message.msg; } - console.log(message); + const roomInfo = RocketChat.models.Rooms.findOneByIdOrName(message.rid, { + t: 1, + name: 1, + ro: 1 + }); + + // reply message link + let prevMessageLink = `[ ](${ Meteor.absoluteUrl().replace(/\/$/, '') }`; + if (roomInfo.t == "c") { + prevMessageLink += `/channel/${ roomInfo.name }?msg=${ email.headers.mid }) `; + } else if (roomInfo.t == "d") { + prevMessageLink += `/direct/${ user.username }?msg=${ email.headers.mid }) `; + } else if (roomInfo.t == "p") { + prevMessageLink += `/group/${ roomInfo.name }?msg=${ email.headers.mid }) `; + } + + message.msg = prevMessageLink + message.msg; + + const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(message.rid, user._id); + if (subscription && subscription.blocked || subscription.blocker) { + // room is blocked + return false; + } + + if ((room.muted || []).includes(user.username)) { + // room is muted + return false; + } + + if (message.alias == null && RocketChat.settings.get('Message_SetNameToAliasEnabled')) { + message.alias = user.name; + } + + RocketChat.metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736 + + return RocketChat.sendMessage(user, message, room); } // Extract/parse reply from email body diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index dabf18936633..59c512852542 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -19,6 +19,10 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { } // FIND + findOneById(_id, options) { + return this.findOne({'_id': _id}, options); + } + findByMention(username, options) { const query = {'mentions.username': username}; From 923103e9d63e9acbfb9334684ee1501262fb3aba Mon Sep 17 00:00:00 2001 From: pkgodara Date: Wed, 5 Jul 2017 21:57:08 +0530 Subject: [PATCH 21/56] fix eslint --- .../server/lib/processDirectEmail.js | 17 +++++++---------- .../rocketchat-lib/server/models/Messages.js | 6 +++++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index ffb2a3c3f26f..d76912fd22a8 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,9 +1,7 @@ -import moment from 'moment'; const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { function sendMessage(email) { - console.log(email); let message = { ts: new Date(email.headers.date), msg: email.body @@ -44,23 +42,22 @@ RocketChat.processDirectEmail = function(email) { } // check mention - if (message.msg.indexOf('@' + prevMessage.u.username) === -1) { - message.msg = '@' + prevMessage.u.username + ' ' + message.msg; + if (message.msg.indexOf(`@${ prevMessage.u.username }`) === -1) { + message.msg = `@${ prevMessage.u.username } ${ message.msg }`; } - const roomInfo = RocketChat.models.Rooms.findOneByIdOrName(message.rid, { + const roomInfo = RocketChat.models.Rooms.findOneById(message.rid, { t: 1, - name: 1, - ro: 1 + name: 1 }); // reply message link let prevMessageLink = `[ ](${ Meteor.absoluteUrl().replace(/\/$/, '') }`; - if (roomInfo.t == "c") { + if (roomInfo.t === 'c') { prevMessageLink += `/channel/${ roomInfo.name }?msg=${ email.headers.mid }) `; - } else if (roomInfo.t == "d") { + } else if (roomInfo.t === 'd') { prevMessageLink += `/direct/${ user.username }?msg=${ email.headers.mid }) `; - } else if (roomInfo.t == "p") { + } else if (roomInfo.t === 'p') { prevMessageLink += `/group/${ roomInfo.name }?msg=${ email.headers.mid }) `; } diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index 59c512852542..55397cae2fb3 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -20,7 +20,11 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { // FIND findOneById(_id, options) { - return this.findOne({'_id': _id}, options); + const query = { + _id: _id + }; + + return this.findOne(query, options); } findByMention(username, options) { From 4128ae650cfa85cfda0e1e182fc01ffd571d317c Mon Sep 17 00:00:00 2001 From: pkgodara Date: Wed, 5 Jul 2017 21:59:51 +0530 Subject: [PATCH 22/56] fix eslint --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index d76912fd22a8..2c90e173bf40 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -2,7 +2,7 @@ const reply = require('emailreplyparser').EmailReplyParser; RocketChat.processDirectEmail = function(email) { function sendMessage(email) { - let message = { + const message = { ts: new Date(email.headers.date), msg: email.body }; From 9e7d70fb8ef3066fc5486afb88aff1c9ec78c4b0 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Wed, 5 Jul 2017 22:42:14 +0530 Subject: [PATCH 23/56] fix eslint --- packages/rocketchat-lib/server/models/Messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index 55397cae2fb3..a49a18a76b6c 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -21,7 +21,7 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { // FIND findOneById(_id, options) { const query = { - _id: _id + _id }; return this.findOne(query, options); From e4bbcb736c8909096ea0350e8bc714e517c74178 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Wed, 5 Jul 2017 23:40:15 +0530 Subject: [PATCH 24/56] reduce new-lines --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 2c90e173bf40..7c4258b7548a 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -15,6 +15,9 @@ RocketChat.processDirectEmail = function(email) { return false; } + // reduce new lines in multiline message + message.msg = message.msg.split('\n\n').join('\n'); + const user = RocketChat.models.Users.findOneByEmailAddress(email.headers.from, { fields: { username: 1, @@ -80,6 +83,7 @@ RocketChat.processDirectEmail = function(email) { RocketChat.metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736 + console.log(message); return RocketChat.sendMessage(user, message, room); } From feb8287afe2253cf2f1ebc4632a191f6d12d05a2 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sat, 8 Jul 2017 17:47:17 +0530 Subject: [PATCH 25/56] Object oriented IMAP & Control IMAP --- packages/rocketchat-i18n/i18n/en.i18n.json | 294 +++++++++--------- packages/rocketchat-lib/package.js | 1 + .../server/lib/interceptDirectReplyEmails.js | 127 +++++--- .../server/lib/processDirectEmail.js | 14 +- .../server/lib/sendEmailOnMessage.js | 8 +- .../server/methods/startEmailIntercepter.js | 19 +- .../server/methods/stopEmailIntercepter.js | 17 + .../rocketchat-lib/server/startup/settings.js | 9 +- 8 files changed, 271 insertions(+), 218 deletions(-) create mode 100644 packages/rocketchat-lib/server/methods/stopEmailIntercepter.js diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 2bce1c60c680..e3a715bfaf40 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -422,6 +422,7 @@ "Direct_Messages": "Direct Messages", "Direct_Reply": "Direct Reply", "Direct_Reply_Debug": "Debug Direct Reply", + "Direct_Reply_Debug_Description": "[Beware] Enabling Debug mode would display your 'Plain Text Password' in Admin console.", "Direct_Reply_Enable": "Enable Direct Reply", "Direct_Reply_Protocol": "Direct Reply Protocol", "Direct_Reply_Host": "Direct Reply Host", @@ -429,7 +430,8 @@ "Direct_Reply_IgnoreTLS": "IgnoreTLS", "Direct_Reply_Username": "Username", "Direct_Reply_Password": "Password", - "Direct_Reply_Start": "Start Direct Reply", + "Direct_Reply_Start": "Start Intercepter", + "Direct_Reply_Stop": "Stop Intercepter", "Disable_Notifications": "Disable Notifications", "Disable_two-factor_authentication": "Disable two-factor authentication", "Display_offline_form": "Display offline form", @@ -1174,150 +1176,150 @@ "People": "People", "Permalink": "Permalink", "Permissions": "Permissions", - "access-mailer":"Access Mailer Screen", - "access-mailer_description":"Permission to send mass email to all users.", - "access-permissions":"Access Permissions Screen", - "access-permissions_description":"Modify permissions for various roles.", - "add-oauth-service":"Add Oauth Service", - "add-oauth-service_description":"Permission to add a new Oauth service", - "add-user":"Add User", - "add-user_description":"Permission to add new users to the server via users screen", - "add-user-to-any-c-room":"Add User to Any Public Channel", - "add-user-to-any-c-room_description":"Permission to add a user to any public channel", - "add-user-to-any-p-room":"Add User to Any Private Channel", - "add-user-to-any-p-room_description":"Permission to add a user to any private channel", - "add-user-to-joined-room":"Add User to Any Joined Channel", - "add-user-to-joined-room_description":"Permission to add a user to a currently joined channel", - "archive-room":"Archive Room", - "archive-room_description":"Permission to archive a channel", - "assign-admin-role":"Assign Admin Role", - "assign-admin-role_description":"Permission to assign the admin role to other users", - "auto-translate":"Auto Translate", - "auto-translate_description":"Permission to use the auto translate tool", - "ban-user":"Ban User", - "ban-user_description":"Permission to ban a user from a channel", - "bulk-create-c":"Bulk Create Channels", - "bulk-create-c_description":"Permission to create channels in bulk", - "bulk-register-user":"Bulk Create Channels", - "bulk-register-user_description":"Permission to create channels in bulk", - "clean-channel-history":"Clean Channel History", - "clean-channel-history_description":"Permission to Clear the history from channels", - "close-livechat-room":"Close Livechat Room", - "close-livechat-room_description":"Permission to close the current LiveChat channel", - "close-others-livechat-room":"Close Livechat Room", - "close-others-livechat-room_description":"Permission to close other LiveChat channels", - "create-c":"Create Public Channels", - "create-c_description":"Permission to create public channels", - "create-d":"Create Direct Messages", - "create-d_description":"Permission to start direct messages", - "create-p":"Create Private Channels", - "create-p_description":"Permission to create private channels", - "create-user":"Create User", - "create-user_description":"Permission to create users", - "delete-c":"Delete Public Channels", - "delete-c_description":"Permission to delete public channels", - "delete-d":"Delete Direct Messages", - "delete-d_description":"Permission to delete direct messages", - "delete-p":"Delete Private Channels", - "delete-p_description":"Permission to delete private channels", - "delete-message":"Delete Message", - "delete-message_description":"Permission to delete a message within a room", - "delete-user":"Delete User", - "delete-user_description":"Permission to delete users", - "edit-message":"Edit Message", - "edit-message_description":"Permission to edit a message within a room", - "edit-other-user-active-status":"Edit Other User Active Status", - "edit-other-user-active-status_description":"Permission to enable or disable other accounts", - "edit-other-user-info":"Edit Other User Information", - "edit-other-user-info_description":"Permission to change other user’s name, username or email address.", - "edit-other-user-password":"Edit Other User Password", - "edit-other-user-password_description":"Permission to modify other user’s passwords. Requires edit-other-user-info permission.", - "edit-privileged-setting":"Edit privileged Setting", - "edit-privileged-setting_description":"Permission to edit settings", - "edit-room":"Edit Room", - "edit-room_description":"Permission to edit a room’s name, topic, type (private or public status) and status (active or archived)", - "force-delete-message":"Force Delete Message", - "force-delete-message_description":"Permission to delete a message bypassing all restrictions", - "join-without-join-code":"Join Without Join Code", - "join-without-join-code_description":"Permission to bypass the join code in channels with join code enabled", - "mail-messages":"Mail Messages", - "mail-messages_description":"Permission to use the mail messages option", - "manage-assets":"Manage Assets", - "manage-assets_description":"Permission to manage the server assets", - "manage-emoji":"Manage Emoji", - "manage-emoji_description":"Permission to manage the server emojis", - "manage-integrations":"Manage Integrations", - "manage-integrations_description":"Permission to manage the server integrations", - "manage-oauth-apps":"Manage Oauth Apps", - "manage-oauth-apps_description":"Permission to manage the server Oauth apps", - "manage-own-integrations":"Manage Own Integrations", - "manage-own-integrations_description":"Permition to allow users to create and edit their own integration or webhooks", - "manage-sounds":"Manage Sounds", - "manage-sounds_description":"Permission to manage the server sounds", - "mention-all":"Mention All", - "mention-all_description":"Permission to use the @all mention", - "mute-user":"Mute User", - "mute-user_description":"Permission to mute other users in the same channel", - "pin-message":"Pin Message", - "pin-message_description":"Permission to pin a message in a channel", - "post-readonly":"Post ReadOnly", - "post-readonly_description":"Permission to post a message in a read-only channel", - "preview-c-room":"Preview Public Channel", - "preview-c-room_description":"Permission to view the contents of a public channel before joining", - "remove-user":"Remove User", - "remove-user_description":"Permission to remove a user from a room", - "run-import":"Run Import", - "run-import_description":"Permission to run the importers", - "run-migration":"Run Migration", - "run-migration_description":"Permission to run the migrations", - "save-others-livechat-room-info":"Save Others Livechat Room Info", - "save-others-livechat-room-info_description":"Permission to save information from other livechat channels", - "set-moderator":"Set Moderator", - "set-moderator_description":"Permission to set other users as moderator of a channel", - "set-owner":"Set Owner", - "set-owner_description":"Permission to set other users as owner of a channel", - "set-react-when-readonly":"Set React When ReadOnly", - "set-react-when-readonly_description":"Permission to set the ability to react to messages in a read only channel", - "set-readonly":"Set ReadOnly", - "set-readonly_description":"Permission to set a channel to read only channel", - "snippet-message":"Snippet Message", - "snippet-message_description":"Permission to create snippet message", - "unarchive-room":"Unarchive Room", - "unarchive-room_description":"Permission to unarchive channels", - "user-generate-access-token":"User Generate Access Token", - "user-generate-access-token_description":"Permission for users to generate access tokens", - "view-c-room":"View Public Channel", - "view-c-room_description":"Permission to view public channels", - "view-d-room":"View Direct Messages", - "view-d-room_description":"Permission to view direct messages", - "view-full-other-user-info":"View Full Other User Info", - "view-full-other-user-info_description":"Permission to view full profile of other users including account creation date, last login, etc.", - "view-history":"View History", - "view-history_description":"Permission to view the channel history", - "view-join-code":"View Join Code", - "view-join-code_description":"Permission to view the channel join code", - "view-joined-room":"View Joined Room", - "view-joined-room_description":"Permission to view the currently joined channels", - "view-l-room":"View Livechat Rooms", - "view-l-room_description":"Permission to view livechat channels", - "view-livechat-manager":"View Livechat Manager", - "view-livechat-manager_description":"Permission to view other livechat managers", - "view-livechat-rooms":"View Livechat Rooms", - "view-livechat-rooms_description":"Permission to view other livechat channels", - "view-logs":"View Logs", - "view-logs_description":"Permission to view the server logs ", - "view-p-room":"View Private Room", - "view-p-room_description":"Permission to view private channels", - "view-privileged-setting":"View Privileged Setting", - "view-privileged-setting_description":"Permission to view settings", - "view-other-user-channels":"View Other User Channels", - "view-other-user-channels_description":"Permission to view channels owned by other users", - "view-room-administration":"View Room Administration", - "view-room-administration_description":"Permission to view public, private and direct message statistics. Does not include the ability to view conversations or archives", - "view-statistics":"View Statistics", - "view-statistics_description":"Permission o view system statistics such as number of users logged in, number of rooms, operating system information", - "view-user-administration":"View User Administration", - "view-user-administration_description":"Permission to partial, read-only list view of other user accounts currently logged into the system. No user account information is accessible with this permission", + "access-mailer": "Access Mailer Screen", + "access-mailer_description": "Permission to send mass email to all users.", + "access-permissions": "Access Permissions Screen", + "access-permissions_description": "Modify permissions for various roles.", + "add-oauth-service": "Add Oauth Service", + "add-oauth-service_description": "Permission to add a new Oauth service", + "add-user": "Add User", + "add-user_description": "Permission to add new users to the server via users screen", + "add-user-to-any-c-room": "Add User to Any Public Channel", + "add-user-to-any-c-room_description": "Permission to add a user to any public channel", + "add-user-to-any-p-room": "Add User to Any Private Channel", + "add-user-to-any-p-room_description": "Permission to add a user to any private channel", + "add-user-to-joined-room": "Add User to Any Joined Channel", + "add-user-to-joined-room_description": "Permission to add a user to a currently joined channel", + "archive-room": "Archive Room", + "archive-room_description": "Permission to archive a channel", + "assign-admin-role": "Assign Admin Role", + "assign-admin-role_description": "Permission to assign the admin role to other users", + "auto-translate": "Auto Translate", + "auto-translate_description": "Permission to use the auto translate tool", + "ban-user": "Ban User", + "ban-user_description": "Permission to ban a user from a channel", + "bulk-create-c": "Bulk Create Channels", + "bulk-create-c_description": "Permission to create channels in bulk", + "bulk-register-user": "Bulk Create Channels", + "bulk-register-user_description": "Permission to create channels in bulk", + "clean-channel-history": "Clean Channel History", + "clean-channel-history_description": "Permission to Clear the history from channels", + "close-livechat-room": "Close Livechat Room", + "close-livechat-room_description": "Permission to close the current LiveChat channel", + "close-others-livechat-room": "Close Livechat Room", + "close-others-livechat-room_description": "Permission to close other LiveChat channels", + "create-c": "Create Public Channels", + "create-c_description": "Permission to create public channels", + "create-d": "Create Direct Messages", + "create-d_description": "Permission to start direct messages", + "create-p": "Create Private Channels", + "create-p_description": "Permission to create private channels", + "create-user": "Create User", + "create-user_description": "Permission to create users", + "delete-c": "Delete Public Channels", + "delete-c_description": "Permission to delete public channels", + "delete-d": "Delete Direct Messages", + "delete-d_description": "Permission to delete direct messages", + "delete-p": "Delete Private Channels", + "delete-p_description": "Permission to delete private channels", + "delete-message": "Delete Message", + "delete-message_description": "Permission to delete a message within a room", + "delete-user": "Delete User", + "delete-user_description": "Permission to delete users", + "edit-message": "Edit Message", + "edit-message_description": "Permission to edit a message within a room", + "edit-other-user-active-status": "Edit Other User Active Status", + "edit-other-user-active-status_description": "Permission to enable or disable other accounts", + "edit-other-user-info": "Edit Other User Information", + "edit-other-user-info_description": "Permission to change other user’s name, username or email address.", + "edit-other-user-password": "Edit Other User Password", + "edit-other-user-password_description": "Permission to modify other user’s passwords. Requires edit-other-user-info permission.", + "edit-privileged-setting": "Edit privileged Setting", + "edit-privileged-setting_description": "Permission to edit settings", + "edit-room": "Edit Room", + "edit-room_description": "Permission to edit a room’s name, topic, type (private or public status) and status (active or archived)", + "force-delete-message": "Force Delete Message", + "force-delete-message_description": "Permission to delete a message bypassing all restrictions", + "join-without-join-code": "Join Without Join Code", + "join-without-join-code_description": "Permission to bypass the join code in channels with join code enabled", + "mail-messages": "Mail Messages", + "mail-messages_description": "Permission to use the mail messages option", + "manage-assets": "Manage Assets", + "manage-assets_description": "Permission to manage the server assets", + "manage-emoji": "Manage Emoji", + "manage-emoji_description": "Permission to manage the server emojis", + "manage-integrations": "Manage Integrations", + "manage-integrations_description": "Permission to manage the server integrations", + "manage-oauth-apps": "Manage Oauth Apps", + "manage-oauth-apps_description": "Permission to manage the server Oauth apps", + "manage-own-integrations": "Manage Own Integrations", + "manage-own-integrations_description": "Permition to allow users to create and edit their own integration or webhooks", + "manage-sounds": "Manage Sounds", + "manage-sounds_description": "Permission to manage the server sounds", + "mention-all": "Mention All", + "mention-all_description": "Permission to use the @all mention", + "mute-user": "Mute User", + "mute-user_description": "Permission to mute other users in the same channel", + "pin-message": "Pin Message", + "pin-message_description": "Permission to pin a message in a channel", + "post-readonly": "Post ReadOnly", + "post-readonly_description": "Permission to post a message in a read-only channel", + "preview-c-room": "Preview Public Channel", + "preview-c-room_description": "Permission to view the contents of a public channel before joining", + "remove-user": "Remove User", + "remove-user_description": "Permission to remove a user from a room", + "run-import": "Run Import", + "run-import_description": "Permission to run the importers", + "run-migration": "Run Migration", + "run-migration_description": "Permission to run the migrations", + "save-others-livechat-room-info": "Save Others Livechat Room Info", + "save-others-livechat-room-info_description": "Permission to save information from other livechat channels", + "set-moderator": "Set Moderator", + "set-moderator_description": "Permission to set other users as moderator of a channel", + "set-owner": "Set Owner", + "set-owner_description": "Permission to set other users as owner of a channel", + "set-react-when-readonly": "Set React When ReadOnly", + "set-react-when-readonly_description": "Permission to set the ability to react to messages in a read only channel", + "set-readonly": "Set ReadOnly", + "set-readonly_description": "Permission to set a channel to read only channel", + "snippet-message": "Snippet Message", + "snippet-message_description": "Permission to create snippet message", + "unarchive-room": "Unarchive Room", + "unarchive-room_description": "Permission to unarchive channels", + "user-generate-access-token": "User Generate Access Token", + "user-generate-access-token_description": "Permission for users to generate access tokens", + "view-c-room": "View Public Channel", + "view-c-room_description": "Permission to view public channels", + "view-d-room": "View Direct Messages", + "view-d-room_description": "Permission to view direct messages", + "view-full-other-user-info": "View Full Other User Info", + "view-full-other-user-info_description": "Permission to view full profile of other users including account creation date, last login, etc.", + "view-history": "View History", + "view-history_description": "Permission to view the channel history", + "view-join-code": "View Join Code", + "view-join-code_description": "Permission to view the channel join code", + "view-joined-room": "View Joined Room", + "view-joined-room_description": "Permission to view the currently joined channels", + "view-l-room": "View Livechat Rooms", + "view-l-room_description": "Permission to view livechat channels", + "view-livechat-manager": "View Livechat Manager", + "view-livechat-manager_description": "Permission to view other livechat managers", + "view-livechat-rooms": "View Livechat Rooms", + "view-livechat-rooms_description": "Permission to view other livechat channels", + "view-logs": "View Logs", + "view-logs_description": "Permission to view the server logs ", + "view-p-room": "View Private Room", + "view-p-room_description": "Permission to view private channels", + "view-privileged-setting": "View Privileged Setting", + "view-privileged-setting_description": "Permission to view settings", + "view-other-user-channels": "View Other User Channels", + "view-other-user-channels_description": "Permission to view channels owned by other users", + "view-room-administration": "View Room Administration", + "view-room-administration_description": "Permission to view public, private and direct message statistics. Does not include the ability to view conversations or archives", + "view-statistics": "View Statistics", + "view-statistics_description": "Permission o view system statistics such as number of users logged in, number of rooms, operating system information", + "view-user-administration": "View User Administration", + "view-user-administration_description": "Permission to partial, read-only list view of other user accounts currently logged into the system. No user account information is accessible with this permission", "Pin_Message": "Pin Message", "Pinned_a_message": "Pinned a message:", "Pinned_Messages": "Pinned Messages", @@ -1888,4 +1890,4 @@ "your_message_optional": "your message (optional)", "Your_password_is_wrong": "Your password is wrong!", "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices" -} \ No newline at end of file +} diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index b6f26736e53f..0782e83e3111 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -169,6 +169,7 @@ Package.onUse(function(api) { api.addFiles('server/methods/setUsername.js', 'server'); api.addFiles('server/methods/setEmail.js', 'server'); api.addFiles('server/methods/startEmailIntercepter.js', 'server'); + api.addFiles('server/methods/stopEmailIntercepter.js', 'server'); api.addFiles('server/methods/unarchiveRoom.js', 'server'); api.addFiles('server/methods/unblockUser.js', 'server'); api.addFiles('server/methods/updateMessage.js', 'server'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index ae3ace8c5c59..db41c15ceefe 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -1,24 +1,68 @@ -const Imap = require('imap'); - -RocketChat.imapIntercepter = function() { - const imap = new Imap({ - user: RocketChat.settings.get('IMAP_Username'), - password: RocketChat.settings.get('IMAP_Password'), - host: RocketChat.settings.get('IMAP_Host'), - port: RocketChat.settings.get('IMAP_Port'), - debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, - tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); - - function openInbox(cb) { - imap.openBox('INBOX', false, cb); - } +const IMAP = require('imap'); + +RocketChat.IMAPIntercepter = function(config) { + this.imap = new IMAP(config); +}; + +RocketChat.IMAPIntercepter.prototype = { + openInbox: function(Imap, cb) { + Imap.openBox('INBOX', false, cb); + }, + + start: function() { + var self = this; + var Imap = this.imap; + + Imap.connect(); + // On successfully connected. + Imap.once('ready', Meteor.bindEnvironment(function() { + if (Imap.state !== 'disconnected') { + self.openInbox(Imap, Meteor.bindEnvironment(function(err) { + if (err) { + throw err; + } + // fetch new emails & wait [IDLE] + self.getEmails(Imap); + + // If new message arrived, fetch them + Imap.on('mail', Meteor.bindEnvironment(function() { + self.getEmails(Imap); + })); + })); + } else { + console.log('IMAP didnot connected.'); + Imap.end(); + } + })); + + Imap.once('error', function(err) { + console.log(err); + throw err; + }); + + Imap.once('end', function() { + console.log('Connection ended.'); + //Imap.connect(); + }); + }, + + isActive: function() { + var Imap = this.imap; + if (Imap.state === 'disconnected') { + return false; + } + + return true; + }, + + stop: function() { + var Imap = this.imap; + Imap.end(); + }, // Fetch all UNSEEN messages and pass them for further processing - function getEmails(imap) { - imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { + getEmails: function(Imap) { + Imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { if (err) { console.log(err); throw err; @@ -26,7 +70,7 @@ RocketChat.imapIntercepter = function() { // newEmails => array containing serials of unseen messages if (newEmails.length > 0) { - const f = imap.fetch(newEmails, { + const f = Imap.fetch(newEmails, { // fetch headers & first body part. bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE REFERENCES)', '1'], struct: true, @@ -52,7 +96,7 @@ RocketChat.imapIntercepter = function() { if (info.which === '1') { email.body = bodyBuffer; } else { - email.headers = Imap.parseHeader(headerBuffer); + email.headers = IMAP.parseHeader(headerBuffer); } }); }); @@ -68,41 +112,22 @@ RocketChat.imapIntercepter = function() { } })); } - - // On successfully connected. - imap.once('ready', Meteor.bindEnvironment(function() { - openInbox(Meteor.bindEnvironment(function(err) { - if (err) { - throw err; - } - // fetch new emails & wait [IDLE] - getEmails(imap); - - // If new message arrived, fetch them - imap.on('mail', Meteor.bindEnvironment(function() { - getEmails(imap); - })); - })); - })); - - imap.once('error', function(err) { - console.log(err); - throw err; - }); - - imap.once('end', function() { - console.log('Connection ended'); - console.log('Retrying IMAP connection...'); - imap.connect(); - }); - - imap.connect(); }; Meteor.startup(function() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { - RocketChat.imapIntercepter(); + RocketChat.IMAP = new RocketChat.IMAPIntercepter({ + user: RocketChat.settings.get('IMAP_Username'), + password: RocketChat.settings.get('IMAP_Password'), + host: RocketChat.settings.get('IMAP_Host'), + port: RocketChat.settings.get('IMAP_Port'), + debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, + tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + RocketChat.IMAP.start(); } } }); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 7c4258b7548a..609f4f3baa3f 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -59,7 +59,7 @@ RocketChat.processDirectEmail = function(email) { if (roomInfo.t === 'c') { prevMessageLink += `/channel/${ roomInfo.name }?msg=${ email.headers.mid }) `; } else if (roomInfo.t === 'd') { - prevMessageLink += `/direct/${ user.username }?msg=${ email.headers.mid }) `; + prevMessageLink += `/direct/${ prevMessage.u.username }?msg=${ email.headers.mid }) `; } else if (roomInfo.t === 'p') { prevMessageLink += `/group/${ roomInfo.name }?msg=${ email.headers.mid }) `; } @@ -108,24 +108,12 @@ RocketChat.processDirectEmail = function(email) { email.headers.references = email.headers.references[0]; - // references format is "" - email.headers.references = email.headers.references.split('@')[0]; - if (email.headers.references.charAt(0) === '<') { - email.headers.references = email.headers.references.substr(1); - } - // 'To' email format "username+messageId@domain" if (email.headers.to.indexOf('+') >= 0) { // Valid 'To' format console.log('Valid Email'); email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; sendMessage(email); - } else if (/^[0-9]+\+([0-9]|[a-z]|[A-Z])+\+([0-9]|[a-z]|[A-Z])+$/.test(email.headers.references)) { - // Valid references(Message-ID) format - console.log('Valid Email'); - email.headers.rid = email.headers.references.split('+')[1]; - email.headers.mid = email.headers.references.split('+')[2]; - sendMessage(email); } else { console.log('Invalid Email....If not. Please report it.'); } diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 4531ca2c8218..efe21bda2c5b 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -95,7 +95,9 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { linkByUser[sub.u._id] = getMessageLink(room, sub); }); } else { - defaultLink = getMessageLink(room, { name: room.name }); + defaultLink = getMessageLink(room, { + name: room.name + }); } if (userIdsToSendEmail.length > 0) { @@ -130,9 +132,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { subject: `[${ siteName }] ${ emailSubject }`, headers: { // Reply-To header with format "username+messageId@domain" - 'Reply-To' : `${ RocketChat.settings.get('IMAP_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('IMAP_Username').split('@')[1] }`, - // Message-ID header with format "timestamp+roomId+messageId@domain" - 'Message-ID': `${ ts }+${ message.rid }+${ message._id }@${ email.address.split('@')[1] }` + 'Reply-To': `${ RocketChat.settings.get('IMAP_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('IMAP_Username').split('@')[1] }` }, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer }; diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index 0089d00ecb3d..9e80076de48d 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -2,8 +2,23 @@ Meteor.methods({ startEmailIntercepter() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { - RocketChat.imapIntercepter(); - return true; + if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { + RocketChat.IMAP = new RocketChat.IMAPIntercepter({ + user: RocketChat.settings.get('IMAP_Username'), + password: RocketChat.settings.get('IMAP_Password'), + host: RocketChat.settings.get('IMAP_Host'), + port: RocketChat.settings.get('IMAP_Port'), + debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, + tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + RocketChat.IMAP.start(); + return true; + } else { + console.log('IMAP intercepter already running..........'); + throw new Meteor.Error('IMAP intercepter already running.'); + } } } else { throw new Meteor.Error('Please fill all the information.'); diff --git a/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js b/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js new file mode 100644 index 000000000000..3fa2b7831525 --- /dev/null +++ b/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js @@ -0,0 +1,17 @@ +Meteor.methods({ + stopEmailIntercepter() { + if (RocketChat.settings.get('Direct_Reply_Protocol')) { + if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { + if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { + RocketChat.IMAP.stop(); + return true; + } else { + console.log('IMAP intercepter Not running..........'); + throw new Meteor.Error('IMAP intercepter Not running.'); + } + } + } else { + throw new Meteor.Error('Please fill Protocol information.'); + } + } +}); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 42a430f3b79a..f5edfef990a9 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -475,7 +475,8 @@ RocketChat.settings.addGroup('Email', function() { this.add('Direct_Reply_Debug', false, { type: 'boolean', env: true, - i18nLabel: 'Direct_Reply_Debug' + i18nLabel: 'Direct_Reply_Debug', + i18nDescription: 'Direct_Reply_Debug_Description' }); this.add('Direct_Reply_Protocol', 'IMAP', { type: 'select', @@ -528,10 +529,14 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'Password' }); - return this.add('Direct_Reply_Start', 'startEmailIntercepter', { + this.add('Direct_Reply_Start', 'startEmailIntercepter', { type: 'action', actionText: 'Direct_Reply_Start' }); + return this.add('Direct_Reply_Stop', 'stopEmailIntercepter', { + type: 'action', + actionText: 'Direct_Reply_Stop' + }); }); this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { From 62600332844997cd12628bdf6cde21b8f674b4f0 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sat, 8 Jul 2017 21:52:00 +0530 Subject: [PATCH 26/56] remove extra logs --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 609f4f3baa3f..10fe0850aac5 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -83,7 +83,6 @@ RocketChat.processDirectEmail = function(email) { RocketChat.metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736 - console.log(message); return RocketChat.sendMessage(user, message, room); } @@ -111,7 +110,6 @@ RocketChat.processDirectEmail = function(email) { // 'To' email format "username+messageId@domain" if (email.headers.to.indexOf('+') >= 0) { // Valid 'To' format - console.log('Valid Email'); email.headers.mid = email.headers.to.split('@')[0].split('+')[1]; sendMessage(email); } else { From 0bbda5e0f32493c413ee5506620b41785ea45e2a Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sat, 8 Jul 2017 22:02:45 +0530 Subject: [PATCH 27/56] fix eslint --- .../server/lib/interceptDirectReplyEmails.js | 18 +++++++++--------- .../server/lib/sendEmailOnMessage.js | 1 - 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index db41c15ceefe..25013d9c9eb2 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -5,13 +5,13 @@ RocketChat.IMAPIntercepter = function(config) { }; RocketChat.IMAPIntercepter.prototype = { - openInbox: function(Imap, cb) { + openInbox(Imap, cb) { Imap.openBox('INBOX', false, cb); }, - start: function() { - var self = this; - var Imap = this.imap; + start() { + const self = this; + const Imap = this.imap; Imap.connect(); // On successfully connected. @@ -46,8 +46,8 @@ RocketChat.IMAPIntercepter.prototype = { }); }, - isActive: function() { - var Imap = this.imap; + isActive() { + const Imap = this.imap; if (Imap.state === 'disconnected') { return false; } @@ -55,13 +55,13 @@ RocketChat.IMAPIntercepter.prototype = { return true; }, - stop: function() { - var Imap = this.imap; + stop() { + const Imap = this.imap; Imap.end(); }, // Fetch all UNSEEN messages and pass them for further processing - getEmails: function(Imap) { + getEmails(Imap) { Imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { if (err) { console.log(err); diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index efe21bda2c5b..fd988016fb3c 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -120,7 +120,6 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { if (RocketChat.settings.get('IMAP_Enable')) { footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); } - const ts = new Date().getTime(); user.emails.some((email) => { if (email.verified) { From beff2469a664f4b594edb89f61e5561132e9f9f9 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Mon, 10 Jul 2017 21:54:41 +0530 Subject: [PATCH 28/56] Added email message info --- .../rocketchat-lib/server/lib/interceptDirectReplyEmails.js | 2 +- packages/rocketchat-lib/server/lib/processDirectEmail.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 25013d9c9eb2..f4a1927aa3b7 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -72,7 +72,7 @@ RocketChat.IMAPIntercepter.prototype = { if (newEmails.length > 0) { const f = Imap.fetch(newEmails, { // fetch headers & first body part. - bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE REFERENCES)', '1'], + bodies: ['HEADER.FIELDS (FROM TO DATE MESSAGE-ID)', '1'], struct: true, markSeen: true }); diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 10fe0850aac5..684ac10bcbd7 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -66,6 +66,9 @@ RocketChat.processDirectEmail = function(email) { message.msg = prevMessageLink + message.msg; + // info: message was sent by email + message.msg += '\n>Sent by Email'; + const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(message.rid, user._id); if (subscription && subscription.blocked || subscription.blocker) { // room is blocked @@ -105,8 +108,6 @@ RocketChat.processDirectEmail = function(email) { email.headers.date = email.headers.date[0]; - email.headers.references = email.headers.references[0]; - // 'To' email format "username+messageId@domain" if (email.headers.to.indexOf('+') >= 0) { // Valid 'To' format From e72ba62fb8a8e5e0817c1329309c14c6d05d4f7c Mon Sep 17 00:00:00 2001 From: pkgodara Date: Tue, 11 Jul 2017 10:18:01 +0530 Subject: [PATCH 29/56] i18n for toastr messages --- packages/rocketchat-i18n/i18n/en.i18n.json | 5 +++++ packages/rocketchat-lib/server/lib/processDirectEmail.js | 2 +- .../server/methods/startEmailIntercepter.js | 9 +++++---- .../server/methods/stopEmailIntercepter.js | 9 +++++---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index e3a715bfaf40..204bb816f9ce 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -431,7 +431,9 @@ "Direct_Reply_Username": "Username", "Direct_Reply_Password": "Password", "Direct_Reply_Start": "Start Intercepter", + "Direct_Reply_Started": "Intercepter Started", "Direct_Reply_Stop": "Stop Intercepter", + "Direct_Reply_Stopped": "Intercepter Stopped", "Disable_Notifications": "Disable Notifications", "Disable_two-factor_authentication": "Disable two-factor authentication", "Display_offline_form": "Display offline form", @@ -689,6 +691,8 @@ "Iframe_Integration_send_enable_Description": "Send events to parent window", "Iframe_Integration_send_target_origin": "Send target origin", "Iframe_Integration_send_target_origin_Description": "Origin with protocol prefix, which commands are sent to e.g. 'https://localhost', or * to allow sending to anywhere.", + "IMAP_intercepter_already_running": "IMAP intercepter already running", + "IMAP_intercepter_Not_running": "IMAP intercepter Not running", "Importer_Archived": "Archived", "Importer_CSV_Information": "The CSV importer requires a specific format, please read the documentation for how to structure your zip file:", "Importer_HipChatEnterprise_Information": "The file uploaded must be a decrypted tar.gz, please read the documentation for further information:", @@ -1176,6 +1180,7 @@ "People": "People", "Permalink": "Permalink", "Permissions": "Permissions", + "Please_fill_all_the_information": "Please fill all the information", "access-mailer": "Access Mailer Screen", "access-mailer_description": "Permission to send mass email to all users.", "access-permissions": "Access Permissions Screen", diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 684ac10bcbd7..1f3796665a1d 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -67,7 +67,7 @@ RocketChat.processDirectEmail = function(email) { message.msg = prevMessageLink + message.msg; // info: message was sent by email - message.msg += '\n>Sent by Email'; + message.msg += '\n>Message sent by Email'; const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(message.rid, user._id); if (subscription && subscription.blocked || subscription.blocker) { diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index 9e80076de48d..d04cd750ad1c 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -14,14 +14,15 @@ Meteor.methods({ keepalive: true }); RocketChat.IMAP.start(); - return true; + return { + message: 'Direct_Reply_Started' + }; } else { - console.log('IMAP intercepter already running..........'); - throw new Meteor.Error('IMAP intercepter already running.'); + throw new Meteor.Error('IMAP_intercepter_already_running'); } } } else { - throw new Meteor.Error('Please fill all the information.'); + throw new Meteor.Error('Please_fill_all_the_information'); } } }); diff --git a/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js b/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js index 3fa2b7831525..7ecc894823a7 100644 --- a/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js @@ -4,14 +4,15 @@ Meteor.methods({ if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { RocketChat.IMAP.stop(); - return true; + return { + message: 'Direct_Reply_Stopped' + }; } else { - console.log('IMAP intercepter Not running..........'); - throw new Meteor.Error('IMAP intercepter Not running.'); + throw new Meteor.Error('IMAP_intercepter_Not_running'); } } } else { - throw new Meteor.Error('Please fill Protocol information.'); + throw new Meteor.Error('Please_fill_all_the_information'); } } }); From d73629db54ea3136ac25a15963b9841a3fae96ed Mon Sep 17 00:00:00 2001 From: pkgodara Date: Tue, 11 Jul 2017 11:04:18 +0530 Subject: [PATCH 30/56] fix select values --- packages/rocketchat-lib/server/startup/settings.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index f5edfef990a9..1e99896fc986 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -495,19 +495,19 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'Host' }); - this.add('Direct_Reply_Port', 143, { + this.add('Direct_Reply_Port', '143', { type: 'select', values: [{ - key: 143, + key: '143', i18nLabel: '143' }, { - key: 993, + key: '993', i18nLabel: '993' }, { - key: 110, + key: '110', i18nLabel: '110' }, { - key: 995, + key: '995', i18nLabel: '995' }], env: true, From 00d48103b080d99e055b806d2cb9211b6d056e40 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 10:50:07 +0530 Subject: [PATCH 31/56] fix settings, unnecessary lint --- packages/rocketchat-lib/package.js | 8 +- .../server/lib/interceptDirectReplyEmails.js | 34 +++-- .../server/lib/sendEmailOnMessage.js | 10 +- .../server/methods/startEmailIntercepter.js | 12 +- .../rocketchat-lib/server/models/Messages.js | 8 -- .../rocketchat-lib/server/startup/settings.js | 136 ++++++++++-------- 6 files changed, 103 insertions(+), 105 deletions(-) diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index 0782e83e3111..6410afa210b3 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -39,12 +39,8 @@ Package.onUse(function(api) { api.use('rocketchat:version'); api.use('rocketchat:logger'); api.use('rocketchat:custom-oauth'); - api.use('rocketchat:authorization', { - unordered: true - }); - api.use('rocketchat:push-notifications', { - unordered: true - }); + api.use('rocketchat:authorization', {unordered: true}); + api.use('rocketchat:push-notifications', {unordered: true}); api.use('templating', 'client'); api.use('kadira:flow-router'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index f4a1927aa3b7..ecfa67823c89 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -2,14 +2,12 @@ const IMAP = require('imap'); RocketChat.IMAPIntercepter = function(config) { this.imap = new IMAP(config); -}; -RocketChat.IMAPIntercepter.prototype = { - openInbox(Imap, cb) { + this.openInbox = function(Imap, cb) { Imap.openBox('INBOX', false, cb); - }, + }; - start() { + this.start = function() { const self = this; const Imap = this.imap; @@ -44,24 +42,24 @@ RocketChat.IMAPIntercepter.prototype = { console.log('Connection ended.'); //Imap.connect(); }); - }, + }; - isActive() { + this.isActive = function() { const Imap = this.imap; if (Imap.state === 'disconnected') { return false; } return true; - }, + }; - stop() { + this.stop = function() { const Imap = this.imap; Imap.end(); - }, + }; // Fetch all UNSEEN messages and pass them for further processing - getEmails(Imap) { + this.getEmails = function(Imap) { Imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { if (err) { console.log(err); @@ -111,19 +109,19 @@ RocketChat.IMAPIntercepter.prototype = { }); } })); - } + }; }; Meteor.startup(function() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('IMAP_Username'), - password: RocketChat.settings.get('IMAP_Password'), - host: RocketChat.settings.get('IMAP_Host'), - port: RocketChat.settings.get('IMAP_Port'), - debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, - tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), connTimeout: 30000, keepalive: true }); diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index fd988016fb3c..2612ab46e99e 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -95,9 +95,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { linkByUser[sub.u._id] = getMessageLink(room, sub); }); } else { - defaultLink = getMessageLink(room, { - name: room.name - }); + defaultLink = getMessageLink(room, {name: room.name}); } if (userIdsToSendEmail.length > 0) { @@ -117,21 +115,21 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { } // Footer in case direct reply is enabled. - if (RocketChat.settings.get('IMAP_Enable')) { + if (RocketChat.settings.get('Direct_Reply_Enable')) { footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer_Direct_Reply') || ''); } user.emails.some((email) => { if (email.verified) { // If direct reply enabled, email content with headers - if (RocketChat.settings.get('IMAP_Enable')) { + if (RocketChat.settings.get('Direct_Reply_Enable')) { email = { to: email.address, from: RocketChat.settings.get('From_Email'), subject: `[${ siteName }] ${ emailSubject }`, headers: { // Reply-To header with format "username+messageId@domain" - 'Reply-To': `${ RocketChat.settings.get('IMAP_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('IMAP_Username').split('@')[1] }` + 'Reply-To': `${ RocketChat.settings.get('Direct_Reply_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('Direct_Reply_Username').split('@')[1] }` }, html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer }; diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index d04cd750ad1c..24aecc2678fb 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -4,12 +4,12 @@ Meteor.methods({ if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('IMAP_Username'), - password: RocketChat.settings.get('IMAP_Password'), - host: RocketChat.settings.get('IMAP_Host'), - port: RocketChat.settings.get('IMAP_Port'), - debug: RocketChat.settings.get('IMAP_Debug') ? console.log : false, - tls: !RocketChat.settings.get('IMAP_IgnoreTLS'), + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), connTimeout: 30000, keepalive: true }); diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index a49a18a76b6c..dabf18936633 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -19,14 +19,6 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { } // FIND - findOneById(_id, options) { - const query = { - _id - }; - - return this.findOne(query, options); - } - findByMention(username, options) { const query = {'mentions.username': username}; diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 1e99896fc986..8859d1812087 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -116,16 +116,18 @@ RocketChat.settings.addGroup('Accounts', function() { this.add('Accounts_RegistrationForm', 'Public', { type: 'select', 'public': true, - values: [{ - key: 'Public', - i18nLabel: 'Accounts_RegistrationForm_Public' - }, { - key: 'Disabled', - i18nLabel: 'Accounts_RegistrationForm_Disabled' - }, { - key: 'Secret URL', - i18nLabel: 'Accounts_RegistrationForm_Secret_URL' - }] + values: [ + { + key: 'Public', + i18nLabel: 'Accounts_RegistrationForm_Public' + }, { + key: 'Disabled', + i18nLabel: 'Accounts_RegistrationForm_Disabled' + }, { + key: 'Secret URL', + i18nLabel: 'Accounts_RegistrationForm_Secret_URL' + } + ] }); this.add('Accounts_RegistrationForm_SecretURL', Random.id(), { type: 'string' @@ -480,13 +482,15 @@ RocketChat.settings.addGroup('Email', function() { }); this.add('Direct_Reply_Protocol', 'IMAP', { type: 'select', - values: [{ - key: 'IMAP', - i18nLabel: 'IMAP' - }, { - key: 'POP', - i18nLabel: 'POP' - }], + values: [ + { + key: 'IMAP', + i18nLabel: 'IMAP' + }, { + key: 'POP', + i18nLabel: 'POP' + } + ], env: true, i18nLabel: 'Protocol' }); @@ -497,19 +501,21 @@ RocketChat.settings.addGroup('Email', function() { }); this.add('Direct_Reply_Port', '143', { type: 'select', - values: [{ - key: '143', - i18nLabel: '143' - }, { - key: '993', - i18nLabel: '993' - }, { - key: '110', - i18nLabel: '110' - }, { - key: '995', - i18nLabel: '995' - }], + values: [ + { + key: '143', + i18nLabel: '143' + }, { + key: '993', + i18nLabel: '993' + }, { + key: '110', + i18nLabel: '110' + }, { + key: '995', + i18nLabel: '995' + } + ], env: true, i18nLabel: 'Port' }); @@ -541,13 +547,15 @@ RocketChat.settings.addGroup('Email', function() { this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { type: 'select', - values: [{ - key: 'smtp', - i18nLabel: 'smtp' - }, { - key: 'smtps', - i18nLabel: 'smtps' - }], + values: [ + { + key: 'smtp', + i18nLabel: 'smtp' + }, { + key: 'smtps', + i18nLabel: 'smtps' + } + ], env: true, i18nLabel: 'Protocol' }); @@ -952,24 +960,28 @@ RocketChat.settings.addGroup('Push', function() { }); this.add('Push_gateway', 'https://gateway.rocket.chat', { type: 'string', - enableQuery: [{ - _id: 'Push_enable', - value: true - }, { - _id: 'Push_enable_gateway', - value: true - }] + enableQuery: [ + { + _id: 'Push_enable', + value: true + }, { + _id: 'Push_enable_gateway', + value: true + } + ] }); this.add('Push_production', true, { type: 'boolean', 'public': true, - enableQuery: [{ - _id: 'Push_enable', - value: true - }, { - _id: 'Push_enable_gateway', - value: false - }] + enableQuery: [ + { + _id: 'Push_enable', + value: true + }, { + _id: 'Push_enable_gateway', + value: false + } + ] }); this.add('Push_test_push', 'push_test', { type: 'action', @@ -1093,16 +1105,18 @@ RocketChat.settings.addGroup('Layout', function() { RocketChat.settings.addGroup('Logs', function() { this.add('Log_Level', '0', { type: 'select', - values: [{ - key: '0', - i18nLabel: '0_Errors_Only' - }, { - key: '1', - i18nLabel: '1_Errors_and_Information' - }, { - key: '2', - i18nLabel: '2_Erros_Information_and_Debug' - }], + values: [ + { + key: '0', + i18nLabel: '0_Errors_Only' + }, { + key: '1', + i18nLabel: '1_Errors_and_Information' + }, { + key: '2', + i18nLabel: '2_Erros_Information_and_Debug' + } + ], 'public': true }); this.add('Log_Package', false, { From 6d08dbc0c7c6192a97a84947a013b226eafc9880 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 10:55:41 +0530 Subject: [PATCH 32/56] fix unnecessary lint --- packages/rocketchat-lib/server/lib/sendEmailOnMessage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 2612ab46e99e..2dcfe1bb2877 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -95,7 +95,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { linkByUser[sub.u._id] = getMessageLink(room, sub); }); } else { - defaultLink = getMessageLink(room, {name: room.name}); + defaultLink = getMessageLink(room, { name: room.name }); } if (userIdsToSendEmail.length > 0) { From 953d1e249a3afd59528d056dcaf18c5464992c39 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 15:12:57 +0530 Subject: [PATCH 33/56] intercepter start on save settings --- packages/rocketchat-lib/package.js | 1 + .../server/lib/interceptDirectReplyEmails.js | 28 +------ .../server/methods/startEmailIntercepter.js | 5 ++ .../rocketchat-lib/server/startup/settings.js | 4 - .../startup/settingsOnLoadDirectReply.js | 79 +++++++++++++++++++ 5 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index 6410afa210b3..a02ddbbed745 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -172,6 +172,7 @@ Package.onUse(function(api) { // SERVER STARTUP api.addFiles('server/startup/settingsOnLoadCdnPrefix.js', 'server'); + api.addFiles('server/startup/settingsOnLoadDirectReply.js', 'server'); api.addFiles('server/startup/settingsOnLoadSMTP.js', 'server'); api.addFiles('server/startup/oAuthServicesUpdate.js', 'server'); api.addFiles('server/startup/settings.js', 'server'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index ecfa67823c89..f87dbc5b83b3 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -37,11 +37,6 @@ RocketChat.IMAPIntercepter = function(config) { console.log(err); throw err; }); - - Imap.once('end', function() { - console.log('Connection ended.'); - //Imap.connect(); - }); }; this.isActive = function() { @@ -53,9 +48,12 @@ RocketChat.IMAPIntercepter = function(config) { return true; }; - this.stop = function() { + this.stop = function(callback) { const Imap = this.imap; Imap.end(); + Imap.once('end', function() { + callback(); + }); }; // Fetch all UNSEEN messages and pass them for further processing @@ -111,21 +109,3 @@ RocketChat.IMAPIntercepter = function(config) { })); }; }; - -Meteor.startup(function() { - if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { - if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { - RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('Direct_Reply_Username'), - password: RocketChat.settings.get('Direct_Reply_Password'), - host: RocketChat.settings.get('Direct_Reply_Host'), - port: RocketChat.settings.get('Direct_Reply_Port'), - debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, - tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); - RocketChat.IMAP.start(); - } - } -}); diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index 24aecc2678fb..e46662af4c01 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -2,6 +2,11 @@ Meteor.methods({ startEmailIntercepter() { if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { + // stop already running instance + if(RocketChat.IMAP && RocketChat.IMAP.isActive()) { + RocketChat.IMAP.stop(); + } + // start new instance if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { RocketChat.IMAP = new RocketChat.IMAPIntercepter({ user: RocketChat.settings.get('Direct_Reply_Username'), diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 8859d1812087..f6f811dd22d2 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -535,10 +535,6 @@ RocketChat.settings.addGroup('Email', function() { env: true, i18nLabel: 'Password' }); - this.add('Direct_Reply_Start', 'startEmailIntercepter', { - type: 'action', - actionText: 'Direct_Reply_Start' - }); return this.add('Direct_Reply_Stop', 'stopEmailIntercepter', { type: 'action', actionText: 'Direct_Reply_Stop' diff --git a/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js new file mode 100644 index 000000000000..7242de032006 --- /dev/null +++ b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js @@ -0,0 +1,79 @@ +const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { + console.log('Starting Email Intercepter...'); + + if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { + if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { + // stop already running instance + if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { + console.log('Disconnecting already running instance...'); + RocketChat.IMAP.stop(Meteor.bindEnvironment(function() { + console.log('Starting new instance......'); + RocketChat.IMAP = new RocketChat.IMAPIntercepter({ + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + RocketChat.IMAP.start(); + return true; + })); + } else if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { + console.log('Starting new instance......'); + RocketChat.IMAP = new RocketChat.IMAPIntercepter({ + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + RocketChat.IMAP.start(); + return true; + } + } + } +}), 1000); + +RocketChat.settings.onload('Direct_Reply_Enable', function() { + return startEmailIntercepter(); +}); + +RocketChat.settings.onload('Direct_Reply_Debug', function() { + return startEmailIntercepter(); +}); + +RocketChat.settings.onload('Direct_Reply_Host', function(key, value) { + if (_.isString(value)) { + return startEmailIntercepter(); + } +}); + +RocketChat.settings.onload('Direct_Reply_Port', function() { + return startEmailIntercepter(); +}); + +RocketChat.settings.onload('Direct_Reply_Username', function(key, value) { + if (_.isString(value)) { + return startEmailIntercepter(); + } +}); + +RocketChat.settings.onload('Direct_Reply_Password', function(key, value) { + if (_.isString(value)) { + return startEmailIntercepter(); + } +}); + +RocketChat.settings.onload('Direct_Reply_Protocol', function() { + return startEmailIntercepter(); +}); + +RocketChat.settings.onload('Direct_Reply_IgnoreTLS', function() { + return startEmailIntercepter(); +}); From 252279eb4edab2801da8e9c1d89a660766fb6d68 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 15:22:26 +0530 Subject: [PATCH 34/56] fix start --- .../server/methods/startEmailIntercepter.js | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index e46662af4c01..fffa10c9f11e 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -3,11 +3,24 @@ Meteor.methods({ if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { // stop already running instance - if(RocketChat.IMAP && RocketChat.IMAP.isActive()) { - RocketChat.IMAP.stop(); - } - // start new instance - if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { + if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { + RocketChat.IMAP.stop(Meteor.bindEnvironment(function() { + RocketChat.IMAP = new RocketChat.IMAPIntercepter({ + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + RocketChat.IMAP.start(); + return { + message: 'Direct_Reply_Started' + }; + })); + } else if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { RocketChat.IMAP = new RocketChat.IMAPIntercepter({ user: RocketChat.settings.get('Direct_Reply_Username'), password: RocketChat.settings.get('Direct_Reply_Password'), From b400c39b559d0329ad8a9ea3767a7ce1fdcc94e6 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 21:28:54 +0530 Subject: [PATCH 35/56] fix class definition, config, onload --- .../server/lib/interceptDirectReplyEmails.js | 39 ++++++++---- .../server/methods/startEmailIntercepter.js | 22 +------ .../startup/settingsOnLoadDirectReply.js | 60 +------------------ 3 files changed, 31 insertions(+), 90 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index f87dbc5b83b3..80010d54b7ce 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -1,13 +1,24 @@ const IMAP = require('imap'); -RocketChat.IMAPIntercepter = function(config) { - this.imap = new IMAP(config); +class IMAPIntercepter { + constructor() { + this.imap = new IMAP({ + user: RocketChat.settings.get('Direct_Reply_Username'), + password: RocketChat.settings.get('Direct_Reply_Password'), + host: RocketChat.settings.get('Direct_Reply_Host'), + port: RocketChat.settings.get('Direct_Reply_Port'), + debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, + tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), + connTimeout: 30000, + keepalive: true + }); + } - this.openInbox = function(Imap, cb) { + openInbox(Imap, cb) { Imap.openBox('INBOX', false, cb); - }; + } - this.start = function() { + start() { const self = this; const Imap = this.imap; @@ -37,27 +48,27 @@ RocketChat.IMAPIntercepter = function(config) { console.log(err); throw err; }); - }; + } - this.isActive = function() { + isActive() { const Imap = this.imap; if (Imap.state === 'disconnected') { return false; } return true; - }; + } - this.stop = function(callback) { + stop(callback) { const Imap = this.imap; Imap.end(); Imap.once('end', function() { callback(); }); - }; + } // Fetch all UNSEEN messages and pass them for further processing - this.getEmails = function(Imap) { + getEmails(Imap) { Imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { if (err) { console.log(err); @@ -107,5 +118,7 @@ RocketChat.IMAPIntercepter = function(config) { }); } })); - }; -}; + } +} + +RocketChat.IMAPIntercepter = IMAPIntercepter; diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js index fffa10c9f11e..605d8da923b4 100644 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js @@ -5,32 +5,14 @@ Meteor.methods({ // stop already running instance if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { RocketChat.IMAP.stop(Meteor.bindEnvironment(function() { - RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('Direct_Reply_Username'), - password: RocketChat.settings.get('Direct_Reply_Password'), - host: RocketChat.settings.get('Direct_Reply_Host'), - port: RocketChat.settings.get('Direct_Reply_Port'), - debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, - tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); + RocketChat.IMAP = new RocketChat.IMAPIntercepter(); RocketChat.IMAP.start(); return { message: 'Direct_Reply_Started' }; })); } else if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { - RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('Direct_Reply_Username'), - password: RocketChat.settings.get('Direct_Reply_Password'), - host: RocketChat.settings.get('Direct_Reply_Host'), - port: RocketChat.settings.get('Direct_Reply_Port'), - debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, - tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); + RocketChat.IMAP = new RocketChat.IMAPIntercepter(); RocketChat.IMAP.start(); return { message: 'Direct_Reply_Started' diff --git a/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js index 7242de032006..f2adc6ed827d 100644 --- a/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js +++ b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js @@ -8,31 +8,13 @@ const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { console.log('Disconnecting already running instance...'); RocketChat.IMAP.stop(Meteor.bindEnvironment(function() { console.log('Starting new instance......'); - RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('Direct_Reply_Username'), - password: RocketChat.settings.get('Direct_Reply_Password'), - host: RocketChat.settings.get('Direct_Reply_Host'), - port: RocketChat.settings.get('Direct_Reply_Port'), - debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, - tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); + RocketChat.IMAP = new RocketChat.IMAPIntercepter(); RocketChat.IMAP.start(); return true; })); } else if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { console.log('Starting new instance......'); - RocketChat.IMAP = new RocketChat.IMAPIntercepter({ - user: RocketChat.settings.get('Direct_Reply_Username'), - password: RocketChat.settings.get('Direct_Reply_Password'), - host: RocketChat.settings.get('Direct_Reply_Host'), - port: RocketChat.settings.get('Direct_Reply_Port'), - debug: RocketChat.settings.get('Direct_Reply_Debug') ? console.log : false, - tls: !RocketChat.settings.get('Direct_Reply_IgnoreTLS'), - connTimeout: 30000, - keepalive: true - }); + RocketChat.IMAP = new RocketChat.IMAPIntercepter(); RocketChat.IMAP.start(); return true; } @@ -40,40 +22,4 @@ const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { } }), 1000); -RocketChat.settings.onload('Direct_Reply_Enable', function() { - return startEmailIntercepter(); -}); - -RocketChat.settings.onload('Direct_Reply_Debug', function() { - return startEmailIntercepter(); -}); - -RocketChat.settings.onload('Direct_Reply_Host', function(key, value) { - if (_.isString(value)) { - return startEmailIntercepter(); - } -}); - -RocketChat.settings.onload('Direct_Reply_Port', function() { - return startEmailIntercepter(); -}); - -RocketChat.settings.onload('Direct_Reply_Username', function(key, value) { - if (_.isString(value)) { - return startEmailIntercepter(); - } -}); - -RocketChat.settings.onload('Direct_Reply_Password', function(key, value) { - if (_.isString(value)) { - return startEmailIntercepter(); - } -}); - -RocketChat.settings.onload('Direct_Reply_Protocol', function() { - return startEmailIntercepter(); -}); - -RocketChat.settings.onload('Direct_Reply_IgnoreTLS', function() { - return startEmailIntercepter(); -}); +RocketChat.settings.onload(/^Direct_Reply_.+/, startEmailIntercepter); From 3048a028de541dc25eadf2976cfd0565f27e2364 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 23:18:21 +0530 Subject: [PATCH 36/56] fix email sending, import, callbacks --- packages/rocketchat-lib/package.js | 2 -- .../server/lib/interceptDirectReplyEmails.js | 6 ++-- .../server/lib/processDirectEmail.js | 2 +- .../server/lib/sendEmailOnMessage.js | 25 ++++++----------- .../server/methods/startEmailIntercepter.js | 28 ------------------- .../server/methods/stopEmailIntercepter.js | 18 ------------ .../rocketchat-lib/server/startup/settings.js | 6 +--- .../startup/settingsOnLoadDirectReply.js | 3 ++ 8 files changed, 17 insertions(+), 73 deletions(-) delete mode 100644 packages/rocketchat-lib/server/methods/startEmailIntercepter.js delete mode 100644 packages/rocketchat-lib/server/methods/stopEmailIntercepter.js diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index a02ddbbed745..462cf2f82751 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -164,8 +164,6 @@ Package.onUse(function(api) { api.addFiles('server/methods/setRealName.js', 'server'); api.addFiles('server/methods/setUsername.js', 'server'); api.addFiles('server/methods/setEmail.js', 'server'); - api.addFiles('server/methods/startEmailIntercepter.js', 'server'); - api.addFiles('server/methods/stopEmailIntercepter.js', 'server'); api.addFiles('server/methods/unarchiveRoom.js', 'server'); api.addFiles('server/methods/unblockUser.js', 'server'); api.addFiles('server/methods/updateMessage.js', 'server'); diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 80010d54b7ce..972428f06dfa 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -1,4 +1,4 @@ -const IMAP = require('imap'); +import IMAP from 'imap'; class IMAPIntercepter { constructor() { @@ -59,10 +59,10 @@ class IMAPIntercepter { return true; } - stop(callback) { + stop(callback = new Function) { const Imap = this.imap; Imap.end(); - Imap.once('end', function() { + Imap.once('end', () => { callback(); }); } diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index 1f3796665a1d..c5e153db9fb2 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -1,4 +1,4 @@ -const reply = require('emailreplyparser').EmailReplyParser; +import {EmailReplyParser as reply} from 'emailreplyparser'; RocketChat.processDirectEmail = function(email) { function sendMessage(email) { diff --git a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js index 2dcfe1bb2877..9fd4eb9f3cc7 100644 --- a/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendEmailOnMessage.js @@ -121,24 +121,17 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { user.emails.some((email) => { if (email.verified) { + email = { + to: email.address, + from: RocketChat.settings.get('From_Email'), + subject: `[${ siteName }] ${ emailSubject }`, + html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer + }; // If direct reply enabled, email content with headers if (RocketChat.settings.get('Direct_Reply_Enable')) { - email = { - to: email.address, - from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject }`, - headers: { - // Reply-To header with format "username+messageId@domain" - 'Reply-To': `${ RocketChat.settings.get('Direct_Reply_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('Direct_Reply_Username').split('@')[1] }` - }, - html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer - }; - } else { - email = { - to: email.address, - from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject }`, - html: header + messageHTML + divisorMessage + (linkByUser[user._id] || defaultLink) + footer + email.headers = { + // Reply-To header with format "username+messageId@domain" + 'Reply-To': `${ RocketChat.settings.get('Direct_Reply_Username').split('@')[0] }+${ message._id }@${ RocketChat.settings.get('Direct_Reply_Username').split('@')[1] }` }; } diff --git a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js b/packages/rocketchat-lib/server/methods/startEmailIntercepter.js deleted file mode 100644 index 605d8da923b4..000000000000 --- a/packages/rocketchat-lib/server/methods/startEmailIntercepter.js +++ /dev/null @@ -1,28 +0,0 @@ -Meteor.methods({ - startEmailIntercepter() { - if (RocketChat.settings.get('Direct_Reply_Enable') && RocketChat.settings.get('Direct_Reply_Protocol') && RocketChat.settings.get('Direct_Reply_Host') && RocketChat.settings.get('Direct_Reply_Port') && RocketChat.settings.get('Direct_Reply_Username') && RocketChat.settings.get('Direct_Reply_Password')) { - if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { - // stop already running instance - if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { - RocketChat.IMAP.stop(Meteor.bindEnvironment(function() { - RocketChat.IMAP = new RocketChat.IMAPIntercepter(); - RocketChat.IMAP.start(); - return { - message: 'Direct_Reply_Started' - }; - })); - } else if (!RocketChat.IMAP || !RocketChat.IMAP.isActive()) { - RocketChat.IMAP = new RocketChat.IMAPIntercepter(); - RocketChat.IMAP.start(); - return { - message: 'Direct_Reply_Started' - }; - } else { - throw new Meteor.Error('IMAP_intercepter_already_running'); - } - } - } else { - throw new Meteor.Error('Please_fill_all_the_information'); - } - } -}); diff --git a/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js b/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js deleted file mode 100644 index 7ecc894823a7..000000000000 --- a/packages/rocketchat-lib/server/methods/stopEmailIntercepter.js +++ /dev/null @@ -1,18 +0,0 @@ -Meteor.methods({ - stopEmailIntercepter() { - if (RocketChat.settings.get('Direct_Reply_Protocol')) { - if (RocketChat.settings.get('Direct_Reply_Protocol') === 'IMAP') { - if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { - RocketChat.IMAP.stop(); - return { - message: 'Direct_Reply_Stopped' - }; - } else { - throw new Meteor.Error('IMAP_intercepter_Not_running'); - } - } - } else { - throw new Meteor.Error('Please_fill_all_the_information'); - } - } -}); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index f6f811dd22d2..83a9fa8be00d 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -530,15 +530,11 @@ RocketChat.settings.addGroup('Email', function() { i18nLabel: 'Username', placeholder: 'email@domain' }); - this.add('Direct_Reply_Password', '', { + return this.add('Direct_Reply_Password', '', { type: 'password', env: true, i18nLabel: 'Password' }); - return this.add('Direct_Reply_Stop', 'stopEmailIntercepter', { - type: 'action', - actionText: 'Direct_Reply_Stop' - }); }); this.section('SMTP', function() { this.add('SMTP_Protocol', 'smtp', { diff --git a/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js index f2adc6ed827d..8903b96c4ccf 100644 --- a/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js +++ b/packages/rocketchat-lib/server/startup/settingsOnLoadDirectReply.js @@ -19,6 +19,9 @@ const startEmailIntercepter = _.debounce(Meteor.bindEnvironment(function() { return true; } } + } else if (RocketChat.IMAP && RocketChat.IMAP.isActive()) { + // stop IMAP instance + RocketChat.IMAP.stop(); } }), 1000); From 03a7d1c1bb47448771e7c50fafe0ff8a5d71d17e Mon Sep 17 00:00:00 2001 From: pkgodara Date: Thu, 13 Jul 2017 23:27:10 +0530 Subject: [PATCH 37/56] callbacks to arrow functions --- .../server/lib/interceptDirectReplyEmails.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 972428f06dfa..c5e2f21825de 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -24,9 +24,9 @@ class IMAPIntercepter { Imap.connect(); // On successfully connected. - Imap.once('ready', Meteor.bindEnvironment(function() { + Imap.once('ready', Meteor.bindEnvironment(() => { if (Imap.state !== 'disconnected') { - self.openInbox(Imap, Meteor.bindEnvironment(function(err) { + self.openInbox(Imap, Meteor.bindEnvironment((err) => { if (err) { throw err; } @@ -34,7 +34,7 @@ class IMAPIntercepter { self.getEmails(Imap); // If new message arrived, fetch them - Imap.on('mail', Meteor.bindEnvironment(function() { + Imap.on('mail', Meteor.bindEnvironment(() => { self.getEmails(Imap); })); })); @@ -69,7 +69,7 @@ class IMAPIntercepter { // Fetch all UNSEEN messages and pass them for further processing getEmails(Imap) { - Imap.search(['UNSEEN'], Meteor.bindEnvironment(function(err, newEmails) { + Imap.search(['UNSEEN'], Meteor.bindEnvironment((err, newEmails) => { if (err) { console.log(err); throw err; @@ -84,14 +84,14 @@ class IMAPIntercepter { markSeen: true }); - f.on('message', Meteor.bindEnvironment(function(msg) { + f.on('message', Meteor.bindEnvironment((msg) => { const email = {}; - msg.on('body', function(stream, info) { + msg.on('body', (stream, info) => { let headerBuffer = ''; let bodyBuffer = ''; - stream.on('data', function(chunk) { + stream.on('data', (chunk) => { if (info.which === '1') { bodyBuffer += chunk.toString('utf8'); } else { @@ -99,7 +99,7 @@ class IMAPIntercepter { } }); - stream.once('end', function() { + stream.once('end', () => { if (info.which === '1') { email.body = bodyBuffer; } else { @@ -109,11 +109,11 @@ class IMAPIntercepter { }); // On fetched each message, pass it further - msg.once('end', Meteor.bindEnvironment(function() { + msg.once('end', Meteor.bindEnvironment(() => { RocketChat.processDirectEmail(email); })); })); - f.once('error', function(err) { + f.once('error', (err) => { console.log(`Fetch error: ${ err }`); }); } From 9a7dfd3cee09fdd9b0490971b75bae1518bdec09 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Fri, 14 Jul 2017 00:19:21 +0530 Subject: [PATCH 38/56] using class variables --- .../server/lib/interceptDirectReplyEmails.js | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index c5e2f21825de..689a4be71083 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -14,45 +14,41 @@ class IMAPIntercepter { }); } - openInbox(Imap, cb) { - Imap.openBox('INBOX', false, cb); + openInbox(cb) { + this.imap.openBox('INBOX', false, cb); } start() { - const self = this; - const Imap = this.imap; - - Imap.connect(); + this.imap.connect(); // On successfully connected. - Imap.once('ready', Meteor.bindEnvironment(() => { - if (Imap.state !== 'disconnected') { - self.openInbox(Imap, Meteor.bindEnvironment((err) => { + this.imap.once('ready', Meteor.bindEnvironment(() => { + if (this.imap.state !== 'disconnected') { + this.openInbox(Meteor.bindEnvironment((err) => { if (err) { throw err; } // fetch new emails & wait [IDLE] - self.getEmails(Imap); + this.getEmails(); // If new message arrived, fetch them - Imap.on('mail', Meteor.bindEnvironment(() => { - self.getEmails(Imap); + this.imap.on('mail', Meteor.bindEnvironment(() => { + this.getEmails(); })); })); } else { console.log('IMAP didnot connected.'); - Imap.end(); + this.imap.end(); } })); - Imap.once('error', function(err) { + this.imap.once('error', function(err) { console.log(err); throw err; }); } isActive() { - const Imap = this.imap; - if (Imap.state === 'disconnected') { + if (this.imap.state === 'disconnected') { return false; } @@ -60,16 +56,15 @@ class IMAPIntercepter { } stop(callback = new Function) { - const Imap = this.imap; - Imap.end(); - Imap.once('end', () => { + this.imap.end(); + this.imap.once('end', () => { callback(); }); } // Fetch all UNSEEN messages and pass them for further processing - getEmails(Imap) { - Imap.search(['UNSEEN'], Meteor.bindEnvironment((err, newEmails) => { + getEmails() { + this.imap.search(['UNSEEN'], Meteor.bindEnvironment((err, newEmails) => { if (err) { console.log(err); throw err; @@ -77,7 +72,7 @@ class IMAPIntercepter { // newEmails => array containing serials of unseen messages if (newEmails.length > 0) { - const f = Imap.fetch(newEmails, { + const f = this.imap.fetch(newEmails, { // fetch headers & first body part. bodies: ['HEADER.FIELDS (FROM TO DATE MESSAGE-ID)', '1'], struct: true, From 72dc7244aae803b637de4e51b73131d64b3fd590 Mon Sep 17 00:00:00 2001 From: pkgodara Date: Fri, 14 Jul 2017 00:22:44 +0530 Subject: [PATCH 39/56] direct callback --- .../rocketchat-lib/server/lib/interceptDirectReplyEmails.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js index 689a4be71083..53e7aec0b84e 100644 --- a/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js +++ b/packages/rocketchat-lib/server/lib/interceptDirectReplyEmails.js @@ -57,9 +57,7 @@ class IMAPIntercepter { stop(callback = new Function) { this.imap.end(); - this.imap.once('end', () => { - callback(); - }); + this.imap.once('end', callback); } // Fetch all UNSEEN messages and pass them for further processing From fb58ea8fe04efbdb0089258cfbb1daaff451607a Mon Sep 17 00:00:00 2001 From: pkgodara Date: Fri, 14 Jul 2017 21:58:06 +0530 Subject: [PATCH 40/56] Icon to identify messages sent by emails --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-lib/server/lib/processDirectEmail.js | 9 ++++----- packages/rocketchat-ui-message/client/message.html | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 204bb816f9ce..b2c9bbfcced1 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1037,6 +1037,7 @@ "Message_ShowDeletedStatus": "Show Deleted Status", "Message_ShowEditedStatus": "Show Edited Status", "Message_ShowFormattingTips": "Show Formatting Tips", + "Message_sent_by_email": "Message sent by Email", "Message_starring": "Message starring", "Message_TimeFormat": "Time Format", "Message_TimeAndDateFormat": "Time and Date Format", diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index c5e153db9fb2..ac307ecb1a19 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -4,7 +4,9 @@ RocketChat.processDirectEmail = function(email) { function sendMessage(email) { const message = { ts: new Date(email.headers.date), - msg: email.body + msg: email.body, + emailReply: true, + groupable: false }; if (!message.ts) { @@ -63,12 +65,9 @@ RocketChat.processDirectEmail = function(email) { } else if (roomInfo.t === 'p') { prevMessageLink += `/group/${ roomInfo.name }?msg=${ email.headers.mid }) `; } - + // add reply message link message.msg = prevMessageLink + message.msg; - // info: message was sent by email - message.msg += '\n>Message sent by Email'; - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(message.rid, user._id); if (subscription && subscription.blocked || subscription.blocker) { // room is blocked diff --git a/packages/rocketchat-ui-message/client/message.html b/packages/rocketchat-ui-message/client/message.html index 3a02fa4d14b6..04b2a4d5e28b 100644 --- a/packages/rocketchat-ui-message/client/message.html +++ b/packages/rocketchat-ui-message/client/message.html @@ -35,6 +35,11 @@ {{/if}} + {{#if emailReply}} + + + + {{/if}} {{#if edited}} From 7bc663100e549d7a23d41165083a130a6bcbe9fc Mon Sep 17 00:00:00 2001 From: pkgodara Date: Fri, 14 Jul 2017 22:40:11 +0530 Subject: [PATCH 41/56] Icon to identify messages sent by emails --- packages/rocketchat-ui-message/client/message.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-ui-message/client/message.html b/packages/rocketchat-ui-message/client/message.html index 04b2a4d5e28b..d56eee40a13d 100644 --- a/packages/rocketchat-ui-message/client/message.html +++ b/packages/rocketchat-ui-message/client/message.html @@ -36,8 +36,8 @@ {{/if}} {{#if emailReply}} - - + {{/if}} {{#if edited}} From 1d7f2666367515af10a11e68f44f547721be51ad Mon Sep 17 00:00:00 2001 From: pkgodara Date: Sat, 15 Jul 2017 00:14:18 +0530 Subject: [PATCH 42/56] use common property name --- packages/rocketchat-lib/server/lib/processDirectEmail.js | 2 +- packages/rocketchat-ui-message/client/message.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/lib/processDirectEmail.js b/packages/rocketchat-lib/server/lib/processDirectEmail.js index ac307ecb1a19..6eab1b428473 100644 --- a/packages/rocketchat-lib/server/lib/processDirectEmail.js +++ b/packages/rocketchat-lib/server/lib/processDirectEmail.js @@ -5,7 +5,7 @@ RocketChat.processDirectEmail = function(email) { const message = { ts: new Date(email.headers.date), msg: email.body, - emailReply: true, + sentByEmail: true, groupable: false }; diff --git a/packages/rocketchat-ui-message/client/message.html b/packages/rocketchat-ui-message/client/message.html index d56eee40a13d..fe362a206118 100644 --- a/packages/rocketchat-ui-message/client/message.html +++ b/packages/rocketchat-ui-message/client/message.html @@ -35,8 +35,8 @@ {{/if}} - {{#if emailReply}} -