diff --git a/application/Espo/Controllers/Email.php b/application/Espo/Controllers/Email.php index 9ab1982746..babf803c8f 100644 --- a/application/Espo/Controllers/Email.php +++ b/application/Espo/Controllers/Email.php @@ -41,7 +41,7 @@ class Email extends \Espo\Core\Controllers\Record throw new BadRequest(); } - if (empty($data['password'])) { + if (is_null($data['password'])) { if ($data['type'] == 'preferences') { if (!$this->getUser()->isAdmin() && $data['id'] != $this->getUser()->id) { throw new Forbidden(); diff --git a/application/Espo/Controllers/EmailAccount.php b/application/Espo/Controllers/EmailAccount.php index 484057cc01..d3a77e8b61 100644 --- a/application/Espo/Controllers/EmailAccount.php +++ b/application/Espo/Controllers/EmailAccount.php @@ -44,5 +44,27 @@ class EmailAccount extends \Espo\Core\Controllers\Record throw new Forbidden(); } } + + public function actionTestConnection($params, $data, $request) + { + if (!$request->isPost()) { + throw new BadRequest(); + } + + if (is_null($data['password'])) { + $emailAccount = $this->getEntityManager()->getEntity('EmailAccount', $data['id']); + if (!$emailAccount) { + throw new Error(); + } + + if ($emailAccount->get('assignedUserId') != $this->getUser()->id && !$this->getUser()->isAdmin()) { + throw new Forbidden(); + } + + $data['password'] = $this->getContainer()->get('crypt')->decrypt($emailAccount->get('password')); + } + + return $this->getRecordService()->testConnection($data); + } } diff --git a/application/Espo/Modules/Crm/Controllers/InboundEmail.php b/application/Espo/Modules/Crm/Controllers/InboundEmail.php index fd286f8e9b..ed0aaa188f 100644 --- a/application/Espo/Modules/Crm/Controllers/InboundEmail.php +++ b/application/Espo/Modules/Crm/Controllers/InboundEmail.php @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ namespace Espo\Modules\Crm\Controllers; @@ -30,9 +30,9 @@ class InboundEmail extends \Espo\Core\Controllers\Record throw new Forbidden(); } } - + public function actionGetFolders($params, $data, $request) - { + { return $this->getRecordService()->getFolders(array( 'host' => $request->get('host'), 'port' => $request->get('port'), @@ -41,7 +41,23 @@ class InboundEmail extends \Espo\Core\Controllers\Record 'password' => $request->get('password'), 'id' => $request->get('id') )); + } + public function actionTestConnection($params, $data, $request) + { + if (!$request->isPost()) { + throw new BadRequest(); + } + + if (is_null($data['password'])) { + $inboundEmail = $this->getEntityManager()->getEntity('InboundEmail', $data['id']); + if (!$inboundEmail) { + throw new Error(); + } + $data['password'] = $this->getContainer()->get('crypt')->decrypt($inboundEmail->get('password')); + } + + return $this->getRecordService()->testConnection($data); } } diff --git a/application/Espo/Modules/Crm/Resources/layouts/InboundEmail/detail.json b/application/Espo/Modules/Crm/Resources/layouts/InboundEmail/detail.json index 4cd16d46d9..87e885f128 100644 --- a/application/Espo/Modules/Crm/Resources/layouts/InboundEmail/detail.json +++ b/application/Espo/Modules/Crm/Resources/layouts/InboundEmail/detail.json @@ -26,7 +26,8 @@ ], [ {"name":"monitoredFolders"},{"name":"password"} - ] + ], + [{"name": "testConnection", "customLabel": null, "view": "Crm:InboundEmail.Fields.TestConnection"}] ] }, { diff --git a/application/Espo/Modules/Crm/Services/InboundEmail.php b/application/Espo/Modules/Crm/Services/InboundEmail.php index 0d0f94e0c1..8fb85f6f52 100644 --- a/application/Espo/Modules/Crm/Services/InboundEmail.php +++ b/application/Espo/Modules/Crm/Services/InboundEmail.php @@ -121,6 +121,27 @@ class InboundEmail extends \Espo\Services\Record return $foldersArr; } + public function testConnection(array $params) + { + $imapParams = array( + 'host' => $params['host'], + 'port' => $params['port'], + 'user' => $params['username'], + 'password' => $params['password'] + ); + + if (!empty($params['ssl'])) { + $imapParams['ssl'] = 'SSL'; + } + + $storage = new \Espo\Core\Mail\Mail\Storage\Imap($imapParams); + + if ($storage->getFolders()) { + return true; + } + throw new Error(); + } + public function fetchFromMailServer(Entity $inboundEmail) { if ($inboundEmail->get('status') != 'Active') { diff --git a/application/Espo/Resources/i18n/en_US/EmailAccount.json b/application/Espo/Resources/i18n/en_US/EmailAccount.json index 10845a516e..06dd46b4e3 100644 --- a/application/Espo/Resources/i18n/en_US/EmailAccount.json +++ b/application/Espo/Resources/i18n/en_US/EmailAccount.json @@ -21,9 +21,11 @@ "labels": { "Create EmailAccount": "Create Email Account", "IMAP": "IMAP", - "Main": "Main" + "Main": "Main", + "Test Connection": "Test Connection" }, "messages": { - "couldNotConnectToImap": "Could not connect to IMAP server" + "couldNotConnectToImap": "Could not connect to IMAP server", + "connectionIsOk": "Connection is Ok" } } diff --git a/application/Espo/Resources/layouts/EmailAccount/detail.json b/application/Espo/Resources/layouts/EmailAccount/detail.json index e83b3b23d8..86879947c7 100644 --- a/application/Espo/Resources/layouts/EmailAccount/detail.json +++ b/application/Espo/Resources/layouts/EmailAccount/detail.json @@ -22,7 +22,8 @@ ], [ {"name":"monitoredFolders"},{"name":"password"} - ] + ], + [{"name": "testConnection", "customLabel": null, "view": "EmailAccount.Fields.TestConnection"}] ] } ] diff --git a/application/Espo/Services/EmailAccount.php b/application/Espo/Services/EmailAccount.php index 2670c14867..3a52bf4080 100644 --- a/application/Espo/Services/EmailAccount.php +++ b/application/Espo/Services/EmailAccount.php @@ -92,6 +92,27 @@ class EmailAccount extends Record return $foldersArr; } + public function testConnection(array $params) + { + $imapParams = array( + 'host' => $params['host'], + 'port' => $params['port'], + 'user' => $params['username'], + 'password' => $params['password'] + ); + + if (!empty($params['ssl'])) { + $imapParams['ssl'] = 'SSL'; + } + + $storage = new \Espo\Core\Mail\Mail\Storage\Imap($imapParams); + + if ($storage->getFolders()) { + return true; + } + throw new Error(); + } + public function createEntity($data) { if (!$this->getUser()->isAdmin()) { diff --git a/frontend/client/modules/crm/src/views/inbound-email/fields/test-connection.js b/frontend/client/modules/crm/src/views/inbound-email/fields/test-connection.js new file mode 100644 index 0000000000..ecb9a4273e --- /dev/null +++ b/frontend/client/modules/crm/src/views/inbound-email/fields/test-connection.js @@ -0,0 +1,31 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + ************************************************************************/ + +Espo.define('Crm:Views.InboundEmail.Fields.TestConnection', 'Views.EmailAccount.Fields.TestConnection', function (Dep) { + + return Dep.extend({ + + url: 'InboundEmail/action/testConnection', + + }); + +}); + diff --git a/frontend/client/src/views/email-account/fields/test-connection.js b/frontend/client/src/views/email-account/fields/test-connection.js new file mode 100644 index 0000000000..1c255f13cb --- /dev/null +++ b/frontend/client/src/views/email-account/fields/test-connection.js @@ -0,0 +1,109 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + ************************************************************************/ + +Espo.define('Views.EmailAccount.Fields.TestConnection', 'Views.Fields.Base', function (Dep) { + + return Dep.extend({ + + readOnly: true, + + _template: '', + + url: 'EmailAccount/action/testConnection', + + events: { + 'click [data-action="testConnection"]': function () { + this.test(); + }, + }, + + fetch: function () { + return {}; + }, + + checkAvailability: function () { + if (this.model.get('host')) { + this.$el.find('button').removeClass('disabled'); + } else { + this.$el.find('button').addClass('disabled'); + } + }, + + afterRender: function () { + this.checkAvailability(); + + this.stopListening(this.model, 'change:host'); + this.listenTo(this.model, 'change:host', function () { + this.checkAvailability(); + }, this); + }, + + getData: function () { + var data = { + 'host': this.model.get('host'), + 'port': this.model.get('port'), + 'ssl': this.model.get('ssl'), + 'username': this.model.get('username'), + 'password': this.model.get('password') || null, + 'id': this.model.id + }; + return data; + }, + + + test: function () { + var data = this.getData(); + + var $btn = this.$el.find('button'); + + $btn.addClass('disabled'); + + Espo.Ui.notify(this.translate('pleaseWait', 'messages')); + + $.ajax({ + url: this.url, + type: 'POST', + data: JSON.stringify(data), + error: function (xhr, status) { + var statusReason = xhr.getResponseHeader('X-Status-Reason') || ''; + statusReason = statusReason.replace(/ $/, ''); + statusReason = statusReason.replace(/,$/, ''); + + var msg = this.translate('Error') + ' ' + xhr.status; + if (statusReason) { + msg += ': ' + statusReason; + } + Espo.Ui.error(msg); + console.error(msg); + xhr.errorIsHandled = true; + $btn.removeClass('disabled'); + }.bind(this) + }).done(function () { + $btn.removeClass('disabled'); + Espo.Ui.success(this.translate('connectionIsOk', 'messages', 'EmailAccount')); + }.bind(this)); + + }, + + }); + +}); + diff --git a/frontend/client/src/views/outbound-email/fields/test-send.js b/frontend/client/src/views/outbound-email/fields/test-send.js index 103918ed5f..c75882b9be 100644 --- a/frontend/client/src/views/outbound-email/fields/test-send.js +++ b/frontend/client/src/views/outbound-email/fields/test-send.js @@ -90,7 +90,7 @@ Espo.define('Views.OutboundEmail.Fields.TestSend', 'Views.Fields.Base', function type: 'POST', data: JSON.stringify(data), error: function (xhr, status) { - var statusReason = xhr.getResponseHeader('X-Status-Reason'); + var statusReason = xhr.getResponseHeader('X-Status-Reason') || ''; statusReason = statusReason.replace(/ $/, ''); statusReason = statusReason.replace(/,$/, '');