diff --git a/apps/settings/lib/Controller/MailSettingsController.php b/apps/settings/lib/Controller/MailSettingsController.php
index 95e60c72496..c44c0fc45a8 100644
--- a/apps/settings/lib/Controller/MailSettingsController.php
+++ b/apps/settings/lib/Controller/MailSettingsController.php
@@ -59,6 +59,7 @@ class MailSettingsController extends Controller {
?bool $mail_smtpauth,
string $mail_smtpport,
string $mail_sendmailmode,
+ ?bool $mail_noverify = null,
): DataResponse {
$mail_smtpauth = $mail_smtpauth == '1';
@@ -76,6 +77,15 @@ class MailSettingsController extends Controller {
$configs[$key] = empty($value) ? null : $value;
}
+ if ($mail_noverify !== null) {
+ $options = $this->config->getSystemValue('mail_smtpstreamoptions', []);
+ $options['ssl'] ??= [];
+ $options['ssl']['allow_self_signed'] = $mail_noverify;
+ $options['ssl']['verify_peer'] = !$mail_noverify;
+ $options['ssl']['verify_peer_name'] = !$mail_noverify;
+ $configs['mail_smtpstreamoptions'] = $options;
+ }
+
// Delete passwords from config in case no auth is specified
if (!$mail_smtpauth) {
$configs['mail_smtpname'] = null;
diff --git a/apps/settings/lib/Settings/Admin/Mail.php b/apps/settings/lib/Settings/Admin/Mail.php
index 92dc9a340e4..e76ca9b8214 100644
--- a/apps/settings/lib/Settings/Admin/Mail.php
+++ b/apps/settings/lib/Settings/Admin/Mail.php
@@ -17,7 +17,7 @@ use OCP\Settings\IDelegatedSettings;
use OCP\Util;
class Mail implements IDelegatedSettings {
-
+
public function __construct(
private IConfig $config,
private IL10N $l,
@@ -67,6 +67,7 @@ class Mail implements IDelegatedSettings {
$smtpMode = 'smtp';
}
+ $smtpOptions = $this->config->getSystemValue('mail_smtpstreamoptions', []);
$this->initialState->provideInitialState('settingsAdminMailConfig', [
'mail_domain' => $this->config->getSystemValue('mail_domain', ''),
'mail_from_address' => $this->config->getSystemValue('mail_from_address', ''),
@@ -78,6 +79,8 @@ class Mail implements IDelegatedSettings {
'mail_smtpname' => $this->config->getSystemValue('mail_smtpname', ''),
'mail_smtppassword' => $smtpPassword,
'mail_sendmailmode' => $this->config->getSystemValue('mail_sendmailmode', 'smtp'),
+
+ 'mail_noverify' => $smtpOptions['ssl']['allow_self_signed'] ?? false,
]);
Util::addScript('settings', 'vue-settings-admin-mail');
diff --git a/apps/settings/src/views/AdminSettingsMailServer.vue b/apps/settings/src/views/AdminSettingsMailServer.vue
index 713832b88f7..74b7e794c49 100644
--- a/apps/settings/src/views/AdminSettingsMailServer.vue
+++ b/apps/settings/src/views/AdminSettingsMailServer.vue
@@ -39,6 +39,8 @@ const initialConfig = loadState<{
mail_smtpname: string
mail_smtppassword: string
mail_sendmailmode: string
+
+ mail_noverify: boolean
}>('settings', 'settingsAdminMailConfig')
const mailConfig = ref({ ...initialConfig })
@@ -159,6 +161,10 @@ async function onSubmit() {
:input-label="t('settings', 'Sendmail mode')"
:options="settingsAdminMail.smtpSendmailModeOptions"
required />
+
+
+ {{ t('settings', 'Disable certificate verification (insecure)') }}
+
diff --git a/apps/settings/tests/Controller/MailSettingsControllerTest.php b/apps/settings/tests/Controller/MailSettingsControllerTest.php
index f162b4da017..6064e76058a 100644
--- a/apps/settings/tests/Controller/MailSettingsControllerTest.php
+++ b/apps/settings/tests/Controller/MailSettingsControllerTest.php
@@ -95,7 +95,7 @@ class MailSettingsControllerTest extends \Test\TestCase {
'smtp',
'ssl',
'mx.nextcloud.org',
- '1',
+ true,
'25',
'smtp'
);
@@ -108,7 +108,7 @@ class MailSettingsControllerTest extends \Test\TestCase {
'smtp',
'ssl',
'mx.nextcloud.org',
- '0',
+ false,
'25',
'smtp'
);
@@ -116,16 +116,30 @@ class MailSettingsControllerTest extends \Test\TestCase {
}
public function testStoreCredentials(): void {
+ $calls = [];
$this->config
- ->expects($this->once())
- ->method('setSystemValues')
- ->with([
- 'mail_smtpname' => 'UsernameToStore',
- 'mail_smtppassword' => 'PasswordToStore',
- ]);
+ ->expects($this->exactly(2))
+ ->method('setSystemValue')
+ ->willReturnCallback(function (string $key, ?string $value) use (&$calls): void {
+ $calls[] = [$key, $value];
+ });
$response = $this->mailController->storeCredentials('UsernameToStore', 'PasswordToStore');
$this->assertSame(Http::STATUS_OK, $response->getStatus());
+ self::assertEqualsCanonicalizing([
+ ['mail_smtpname', 'UsernameToStore'],
+ ['mail_smtppassword', 'PasswordToStore'],
+ ], $calls);
+ }
+
+ public function testStoreCredentialsWithoutPassword(): void {
+ $this->config
+ ->expects($this->exactly(1))
+ ->method('setSystemValue')
+ ->with('mail_smtpname', 'UsernameToStore');
+
+ $response = $this->mailController->storeCredentials('UsernameToStore', null);
+ $this->assertSame(Http::STATUS_OK, $response->getStatus());
}
public function testSendTestMail(): void {
diff --git a/apps/settings/tests/Settings/Admin/MailTest.php b/apps/settings/tests/Settings/Admin/MailTest.php
index 992c7d43dba..216a42c340b 100644
--- a/apps/settings/tests/Settings/Admin/MailTest.php
+++ b/apps/settings/tests/Settings/Admin/MailTest.php
@@ -8,9 +8,11 @@ namespace OCA\Settings\Tests\Settings\Admin;
use OCA\Settings\Settings\Admin\Mail;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
use OCP\IBinaryFinder;
use OCP\IConfig;
use OCP\IL10N;
+use OCP\IURLGenerator;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;
@@ -19,15 +21,22 @@ class MailTest extends TestCase {
private Mail $admin;
private IConfig&MockObject $config;
private IL10N&MockObject $l10n;
+ private IURLGenerator&MockObject $urlGenerator;
+ private IInitialState&MockObject $initialState;
protected function setUp(): void {
parent::setUp();
$this->config = $this->createMock(IConfig::class);
$this->l10n = $this->createMock(IL10N::class);
+ $this->l10n->method('t')->willReturnArgument(0);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->initialState = $this->createMock(IInitialState::class);
$this->admin = new Mail(
$this->config,
- $this->l10n
+ $this->l10n,
+ $this->initialState,
+ $this->urlGenerator,
);
}
@@ -41,10 +50,12 @@ class MailTest extends TestCase {
#[\PHPUnit\Framework\Attributes\DataProvider('dataGetForm')]
public function testGetForm(bool $sendmail) {
$finder = $this->createMock(IBinaryFinder::class);
- $finder->expects(self::once())
+ $finder->expects(self::atLeastOnce())
->method('findBinaryPath')
- ->with('sendmail')
- ->willReturn($sendmail ? '/usr/bin/sendmail': false);
+ ->willReturnMap([
+ ['qmail', false],
+ ['sendmail', $sendmail ? '/usr/bin/sendmail' : false],
+ ]);
$this->overwriteService(IBinaryFinder::class, $finder);
$this->config
@@ -63,11 +74,37 @@ class MailTest extends TestCase {
['mail_sendmailmode', 'smtp', 'smtp'],
]);
+ $initialState = [];
+ $this->initialState->method('provideInitialState')
+ ->willReturnCallback(function (string $key, array $data) use (&$initialState): void {
+ $initialState[$key] = $data;
+ });
+
$expected = new TemplateResponse(
'settings',
'settings/admin/additional-mail',
- [
- 'sendmail_is_available' => $sendmail,
+ renderAs: ''
+ );
+
+ $this->assertEquals($expected, $this->admin->getForm());
+ self::assertEquals([
+ 'settingsAdminMail' => [
+ 'configIsReadonly' => false,
+ 'docUrl' => '',
+ 'smtpModeOptions' => [
+ ['label' => 'SMTP', 'id' => 'smtp'],
+ ...($sendmail ? [['label' => 'Sendmail', 'id' => 'sendmail']] : [])
+ ],
+ 'smtpEncryptionOptions' => [
+ ['label' => 'None / STARTTLS', 'id' => ''],
+ ['label' => 'SSL/TLS', 'id' => 'ssl'],
+ ],
+ 'smtpSendmailModeOptions' => [
+ ['label' => 'smtp (-bs)', 'id' => 'smtp'],
+ ['label' => 'pipe (-t -i)', 'id' => 'pipe'],
+ ],
+ ],
+ 'settingsAdminMailConfig' => [
'mail_domain' => 'mx.nextcloud.com',
'mail_from_address' => 'no-reply@nextcloud.com',
'mail_smtpmode' => 'smtp',
@@ -78,11 +115,9 @@ class MailTest extends TestCase {
'mail_smtpname' => 'smtp.sender.com',
'mail_smtppassword' => '********',
'mail_sendmailmode' => 'smtp',
+ 'mail_noverify' => false,
],
- ''
- );
-
- $this->assertEquals($expected, $this->admin->getForm());
+ ], $initialState);
}
public function testGetSection(): void {