--- /dev/null
+{if $category->categoryName === 'general'}
+ <script data-relocate="true">
+ require(['Language', 'WoltLabSuite/Core/Acp/Ui/Option/EmailSmtpTest'], function (Language, AcpUiOptionEmailSmtpTest) {
+ Language.addObject({
+ 'wcf.acp.email.smtp.test': '{lang}wcf.acp.email.smtp.test{/lang}',
+ 'wcf.acp.email.smtp.test.description': '{lang}wcf.acp.email.smtp.test.description{/lang}',
+ 'wcf.acp.email.smtp.test.error.empty.host': '{lang}wcf.acp.email.smtp.test.error.empty.host{/lang}',
+ 'wcf.acp.email.smtp.test.error.empty.password': '{lang}wcf.acp.email.smtp.test.error.empty.password{/lang}',
+ 'wcf.acp.email.smtp.test.error.empty.user': '{lang}wcf.acp.email.smtp.test.error.empty.user{/lang}',
+ 'wcf.acp.email.smtp.test.run': '{lang}wcf.acp.email.smtp.test.run{/lang}',
+ 'wcf.acp.email.smtp.test.run.success': '{lang}wcf.acp.email.smtp.test.run.success{/lang}'
+ });
+
+ AcpUiOptionEmailSmtpTest.init();
+ });
+ </script>
+{/if}
</div>
</form>
+{include file='__optionEmailSmtpTest'}
{include file='__optionRewriteTest'}
{include file='footer'}
--- /dev/null
+define(['Ajax', 'Core', 'Language'], function(Ajax, Core, Language) {
+ "use strict";
+
+ var _buttonRunTest = null;
+ var _container = null;
+
+ return {
+ init: function () {
+ var smtpCheckbox = null;
+ elBySelAll('input[name="values[mail_send_method]"]', undefined, (function (radioCheckbox) {
+ radioCheckbox.addEventListener('change', this._onChange.bind(this));
+
+ if (radioCheckbox.value === 'smtp') smtpCheckbox = radioCheckbox;
+ }).bind(this));
+
+ Core.triggerEvent(smtpCheckbox, 'change');
+ },
+
+ _onChange: function (event) {
+ var checkbox = event.currentTarget;
+
+ if (checkbox.value === 'smtp' && checkbox.checked) {
+ if (_container === null) this._initUi(checkbox);
+
+ elShow(_container);
+ }
+ else if (_container !== null) {
+ elHide(_container);
+ }
+ },
+
+ _initUi: function (checkbox) {
+ var html = '<dt>' + Language.get('wcf.acp.email.smtp.test') + '</dt>';
+ html += '<dd>';
+ html += '<button>' + Language.get('wcf.acp.email.smtp.test.run') + '</button>';
+ html += '<small>' + Language.get('wcf.acp.email.smtp.test.description') + '</small>';
+ html += '</dd>';
+
+ _container = elCreate('dl');
+ _container.innerHTML = html;
+
+ _buttonRunTest = elBySel('button', _container);
+ _buttonRunTest.addEventListener(WCF_CLICK_EVENT, this._onClick.bind(this));
+
+ var insertAfter = checkbox.closest('dl');
+ insertAfter.parentNode.insertBefore(_container, insertAfter.nextSibling);
+ },
+
+ _onClick: function (event) {
+ event.preventDefault();
+
+ _buttonRunTest.disabled = true;
+ _buttonRunTest.innerHTML = '<span class="icon icon16 fa-spinner"></span> ' + Language.get('wcf.global.loading');
+
+ var innerError = _buttonRunTest.nextElementSibling;
+ if (innerError && innerError.classList.contains('innerError')) elRemove(innerError);
+
+ window.setTimeout((function () {
+ Ajax.api(this, {
+ parameters: {
+ host: elById('mail_smtp_host').value,
+ port: elById('mail_smtp_port').value,
+ startTls: elBySel('input[name="values[mail_smtp_starttls]"]:checked').value,
+ user: elById('mail_smtp_user').value,
+ password: elById('mail_smtp_password').value
+ }
+ });
+ }).bind(this), 100);
+ },
+
+ _ajaxSuccess: function (data) {
+ var result = data.returnValues.validationResult;
+ if (result === '') {
+ this._resetButton(true);
+ }
+ else {
+ this._resetButton(false, result);
+ }
+ },
+
+ _ajaxFailure: function (data) {
+ var result = '';
+ if (data && data.returnValues && data.returnValues.fieldName) {
+ result = Language.get('wcf.acp.email.smtp.test.error.empty.' + data.returnValues.fieldName);
+ }
+
+ this._resetButton(false, result);
+
+ return (result === '');
+ },
+
+ _resetButton: function (success, errorMessage) {
+ _buttonRunTest.disabled = false;
+
+ if (success) _buttonRunTest.innerHTML = '<span class="icon icon16 fa-check green"></span> ' + Language.get('wcf.acp.email.smtp.test.run.success');
+ else _buttonRunTest.innerHTML = Language.get('wcf.acp.email.smtp.test.run');
+
+ if (errorMessage) {
+ var innerError = elCreate('small');
+ innerError.className = 'innerError';
+ innerError.textContent = errorMessage;
+ _buttonRunTest.parentNode.insertBefore(innerError, _buttonRunTest.nextElementSibling);
+ }
+ },
+
+ _ajaxSetup: function () {
+ return {
+ data: {
+ actionName: 'emailSmtpTest',
+ className: 'wcf\\data\\option\\OptionAction'
+ },
+ silent: true
+ };
+ }
+ };
+});
* @return {AjaxRequest}
*/
api: function(callbackObject, data, success, failure) {
+ // Fetch AjaxRequest, as it cannot be provided because of a circular dependency
+ if (AjaxRequest === undefined) AjaxRequest = require('AjaxRequest');
+
if (typeof data !== 'object') data = {};
var request = _requests.get(callbackObject);
<?php
namespace wcf\data\option;
use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\email\transport\SmtpEmailTransport;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
/**
* Executes option-related actions.
* @author Alexander Ebert
* @copyright 2001-2017 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package WoltLabSuite\Core\Data$2 *
+ * @package WoltLabSuite\Core\Data\Option
+ *
* @method Option create()
* @method OptionEditor[] getObjects()
* @method OptionEditor getSingleObject()
/**
* @inheritDoc
*/
- protected $requireACP = ['create', 'delete', 'import', 'update', 'updateAll'];
+ protected $requireACP = ['create', 'delete', 'emailSmtpTest', 'import', 'update', 'updateAll'];
/**
* Validates permissions and parameters.
// create data
call_user_func([$this->className, 'updateAll'], $this->parameters['data']);
}
+
+ /**
+ * Validates the basic SMTP connection parameters.
+ *
+ * @throws UserInputException
+ */
+ public function validateEmailSmtpTest() {
+ WCF::getSession()->checkPermissions($this->permissionsUpdate);
+
+ $this->readString('host');
+ $this->readInteger('port');
+ $this->readString('startTls');
+
+ $this->readString('user', true);
+ $this->readString('password', true);
+ if (!empty($this->parameters['user']) && empty($this->parameters['password'])) {
+ throw new UserInputException('password');
+ }
+ else if (empty($this->parameters['user']) && !empty($this->parameters['password'])) {
+ throw new UserInputException('user');
+ }
+ }
+
+ /**
+ * Runs a simple test of the SMTP connection.
+ *
+ * @return string[]
+ */
+ public function emailSmtpTest() {
+ $smtp = new SmtpEmailTransport(
+ $this->parameters['host'],
+ $this->parameters['port'],
+ $this->parameters['user'],
+ $this->parameters['password'],
+ $this->parameters['startTls']
+ );
+
+ return ['validationResult' => $smtp->testConnection()];
+ }
}
use wcf\system\email\Mailbox;
use wcf\system\exception\SystemException;
use wcf\system\io\RemoteFile;
+use wcf\system\WCF;
use wcf\util\StringUtil;
/**
$this->disconnect();
}
+ /**
+ * Tests the connection by establishing a connection and optionally
+ * providing user credentials. Returns the error message or an empty
+ * string on success.
+ *
+ * @return string
+ */
+ public function testConnection() {
+ try {
+ $this->connect(10);
+ $this->auth();
+ }
+ catch (SystemException $e) {
+ if (strpos($e->getMessage(), 'Can not connect to') === 0) {
+ return WCF::getLanguage()->get('wcf.acp.email.smtp.test.error.hostUnknown');
+ }
+
+ return $e->getMessage();
+ }
+ catch (PermanentFailure $e) {
+ if (strpos($e->getMessage(), 'Remote SMTP server does not support EHLO') === 0) {
+ return WCF::getLanguage()->get('wcf.acp.email.smtp.test.error.notTlsSupport');
+ }
+ else if (strpos($e->getMessage(), 'Remote SMTP server does not advertise STARTTLS') === 0) {
+ return WCF::getLanguage()->get('wcf.acp.email.smtp.test.error.notTlsSupport');
+ }
+ else if (strpos($e->getMessage(), "Remote SMTP server reported permanent error code: 535 (") === 0) {
+ return WCF::getLanguage()->get('wcf.acp.email.smtp.test.error.badAuth');
+ }
+
+ return $e->getMessage();
+ }
+ catch (TransientFailure $e) {
+ if (strpos($e->getMessage(), 'Enabling TLS failed') === 0) {
+ return WCF::getLanguage()->get('wcf.acp.email.smtp.test.error.tlsFailed');
+ }
+
+ return $e->getMessage();
+ }
+
+ $this->disconnect();
+
+ return '';
+ }
+
/**
* Reads a server reply and validates it against the given expected status codes.
* Returns a tuple [ status code, reply text ].
* Connects to the server and enables STARTTLS if available. Bails
* out if STARTTLS is not available and connection is set to 'encrypt'.
*
+ * @param integer $overrideTimeout
* @throws PermanentFailure
*/
- protected function connect() {
- $this->connection = new RemoteFile($this->host, $this->port);
+ protected function connect($overrideTimeout = null) {
+ if ($overrideTimeout === null) $this->connection = new RemoteFile($this->host, $this->port);
+ else $this->connection = new RemoteFile($this->host, $this->port, $overrideTimeout);
+
$this->read([220]);
try {
<item name="wcf.acp.devtools.sync.syncAll"><![CDATA[Alles Abgleichen]]></item>
</category>
+ <category name="wcf.acp.email">
+ <item name="wcf.acp.email.smtp.test"><![CDATA[SMTP-Verbindungstest]]></item>
+ <item name="wcf.acp.email.smtp.test.description"><![CDATA[Testet die eingegebenen Verbindungsinformationen und Zugangsdaten, ob eine Anmeldung beim SMTP-Server möglich ist. Es wird keine E-Mail verschickt!<br><br><strong>Hinweis:</strong> Es handelt sich hierbei nur um einen sehr oberflächlichen Test. Ein erfolgreicher Versand von E-Mails kann auch beim Bestehen dieses Tests nicht abschließend garantiert werden.]]></item>
+ <item name="wcf.acp.email.smtp.test.run"><![CDATA[SMTP-Verbindung testen]]></item>
+ <item name="wcf.acp.email.smtp.test.run.success"><![CDATA[Verbindungstest erfolgreich]]></item>
+ <item name="wcf.acp.email.smtp.test.error.badAuth"><![CDATA[Benutzername und/oder Passwort wurde vom Server abgelehnt.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.host"><![CDATA[Kein SMTP-Server angegeben.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.password"><![CDATA[Das Passwort fehlt.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.user"><![CDATA[Der Benutzername fehlt.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.hostUnknown"><![CDATA[Der Server antwortet nicht.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.notTlsSupport"><![CDATA[Der Server unterstützt keine Verschlüsselung.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.tlsFailed"><![CDATA[Der Aufbau einer verschlüselten Verbindung war nicht möglich.]]></item>
+ </category>
+
<category name="wcf.acp.exceptionLog">
<item name="wcf.acp.exceptionLog"><![CDATA[Protokollierte Fehler]]></item>
<item name="wcf.acp.exceptionLog.exception.message"><![CDATA[Fehlermeldung]]></item>
<item name="wcf.acp.devtools.sync.syncAll"><![CDATA[Sync All]]></item>
</category>
+ <category name="wcf.acp.email">
+ <item name="wcf.acp.email.smtp.test"><![CDATA[SMTP Connection Test]]></item>
+ <item name="wcf.acp.email.smtp.test.description"><![CDATA[Validates the connection data and user credentials, for their basic validity. No email is sent during this process!<br><br><strong>Notice:</strong> This is only a very basic test. Passing it does not guarantee emails to be successfully delivered!]]></item>
+ <item name="wcf.acp.email.smtp.test.run"><![CDATA[Run SMTP Connection Test]]></item>
+ <item name="wcf.acp.email.smtp.test.run.success"><![CDATA[Test Passed]]></item>
+ <item name="wcf.acp.email.smtp.test.error.badAuth"><![CDATA[Username and/or password were rejected by the server.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.host"><![CDATA[Please enter a SMTP server.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.password"><![CDATA[Please enter a password.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.empty.user"><![CDATA[Please enter a username.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.hostUnknown"><![CDATA[The server is not responding.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.notTlsSupport"><![CDATA[The server does not support encryption.]]></item>
+ <item name="wcf.acp.email.smtp.test.error.tlsFailed"><![CDATA[Unable to establish a secure connection.]]></item>
+ </category>
+
<category name="wcf.acp.exceptionLog">
<item name="wcf.acp.exceptionLog"><![CDATA[Logged errors]]></item>
<item name="wcf.acp.exceptionLog.exception.message"><![CDATA[Error Message]]></item>