diff --git a/.eslintrc.js b/.eslintrc.js
index f51c13b..ad2e02f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,7 +1,7 @@
module.exports = {
- // extends: [
- // '@nextcloud',
- // ],
+ extends: [
+ '@nextcloud',
+ ],
// some unused toolgit files
ignorePatterns: [
'src/toolkit/util/file-download.js',
@@ -38,13 +38,25 @@ module.exports = {
},
overrides: [
{
+ // Vue files with TypeScript need the TypeScript parser
files: ['*.vue'],
+ parser: 'vue-eslint-parser',
+ parserOptions: {
+ parser: '@typescript-eslint/parser',
+ sourceType: 'module',
+ ecmaVersion: 2022,
+ },
rules: {
semi: ['error', 'never'],
+ // False positive with TypeScript generics like defineEmits<{...}>()
+ 'func-call-spacing': 'off',
+ '@typescript-eslint/func-call-spacing': 'off',
+ // Webpack ?raw query not recognized by eslint resolver
+ 'import/no-unresolved': ['error', { ignore: ['\\?raw$'] }],
},
},
{
- files: ['*.ts', '*.cts', '*.mts', '*.tsx', '*.vue'],
+ files: ['*.ts', '*.cts', '*.mts', '*.tsx'],
rules: {
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
},
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php
index ec1570c..1fff2ed 100644
--- a/lib/Controller/SettingsController.php
+++ b/lib/Controller/SettingsController.php
@@ -60,6 +60,10 @@ class SettingsController extends Controller
Config::FORCE_SSO => [ 'rw' => true, 'default' => Config::FORCE_SSO_DEFAULT, ],
Config::SHOW_TOP_LINE => [ 'rw' => true, 'default' => Config::SHOW_TOP_LINE_DEFAULT, ],
Config::ENABLE_SSL_VERIFY => [ 'rw' => true, 'default' => Config::ENABLE_SSL_VERIFY_DEFAULT, ],
+ Config::ENABLE_TLS_CLIENT_CERTIFICATES => [ 'rw' => true, 'default' => Config::ENABLE_TLS_CLIENT_CERTIFICATES_DEFAULT, ],
+ Config::CLIENT_TLS_KEY_FILE => [ 'rw' => true, 'default' => Config::CLIENT_TLS_KEY_FILE_DEFAULT, ],
+ Config::CLIENT_TLS_CERTIFICATE_FILE => [ 'rw' => true, 'default' => Config::CLIENT_TLS_CERTIFICATE_FILE_DEFAULT, ],
+ Config::CLIENT_TLS_KEY_PASSWORD => [ 'rw' => true, 'default' => Config::CLIENT_TLS_KEY_PASSWORD_DEFAULT, ],
Config::PERSONAL_ENCRYPTION => [ 'rw' => true, 'default' => Config::PERSONAL_ENCRYPTION_DEFAULT, ],
Config::CARDDAV_PROVISIONG_TAG => [ 'rw' => true, 'default' => Config::CARDDAV_PROVISIONG_TAG_DEFAULT, ],
];
@@ -151,6 +155,9 @@ public function setAdmin(string $setting, mixed $value, bool $force = false):Dat
case Config::EMAIL_ADDRESS_CHOICE:
case Config::FIXED_SINGLE_EMAIL_ADDRESS:
case Config::CARDDAV_PROVISIONG_TAG:
+ case Config::CLIENT_TLS_KEY_FILE:
+ case Config::CLIENT_TLS_CERTIFICATE_FILE:
+ case Config::CLIENT_TLS_KEY_PASSWORD:
$newValue = $value;
break;
case Config::FIXED_SINGLE_EMAIL_PASSWORD:
@@ -162,6 +169,7 @@ public function setAdmin(string $setting, mixed $value, bool $force = false):Dat
case Config::SHOW_TOP_LINE:
case Config::ENABLE_SSL_VERIFY:
case Config::PERSONAL_ENCRYPTION:
+ case Config::ENABLE_TLS_CLIENT_CERTIFICATES:
$newValue = filter_var($value, FILTER_VALIDATE_BOOLEAN, ['flags' => FILTER_NULL_ON_FAILURE]);
if ($newValue === null) {
return self::grumble($this->l->t(
@@ -240,6 +248,9 @@ public function getAdmin(?string $setting = null):DataResponse
case Config::EMAIL_ADDRESS_CHOICE:
case Config::FIXED_SINGLE_EMAIL_ADDRESS:
case Config::CARDDAV_PROVISIONG_TAG:
+ case Config::CLIENT_TLS_KEY_FILE:
+ case Config::CLIENT_TLS_CERTIFICATE_FILE:
+ case Config::CLIENT_TLS_KEY_PASSWORD:
break;
case Config::FIXED_SINGLE_EMAIL_PASSWORD:
$humanValue = '●●●●●●●●';
@@ -249,6 +260,7 @@ public function getAdmin(?string $setting = null):DataResponse
case Config::SHOW_TOP_LINE:
case Config::ENABLE_SSL_VERIFY:
case Config::PERSONAL_ENCRYPTION:
+ case Config::ENABLE_TLS_CLIENT_CERTIFICATES:
if ($humanValue !== null) {
$humanValue = $humanValue ? $this->l->t('true') : $this->l->t('false');
}
diff --git a/lib/Service/AuthRoundCube.php b/lib/Service/AuthRoundCube.php
index be6555b..f65ac7d 100644
--- a/lib/Service/AuthRoundCube.php
+++ b/lib/Service/AuthRoundCube.php
@@ -55,9 +55,13 @@ class AuthRoundCube
/** @var string */
private $appName;
+ private $clientTLSKeyFile;
+ private $clientTLSCertificateFile;
+ private $clientTLSKeyPassword;
/** @var bool */
private $enableSSLVerify;
+ private $enableClientTLSCertificates;
private $proto;
private $host;
@@ -80,6 +84,10 @@ public function __construct(
protected ILogger $logger,
) {
$this->enableSSLVerify = $this->config->getAppValue(Config::ENABLE_SSL_VERIFY);
+ $this->enableClientTLSCertificates = $this->config->getAppValue(Config::ENABLE_TLS_CLIENT_CERTIFICATES);
+ $this->clientTLSKeyFile = $this->config->getAppValue(Config::CLIENT_TLS_KEY_FILE);
+ $this->clientTLSCertificateFile = $this->config->getAppValue(Config::CLIENT_TLS_CERTIFICATE_FILE);
+ $this->clientTLSKeyPassword = $this->config->getAppValue(Config::CLIENT_TLS_KEY_PASSWORD);
$location = $this->config->getAppValue(Config::EXTERNAL_LOCATION);
if ($location[0] == '/') {
@@ -458,6 +466,12 @@ private function sendRequest(string $rcQuery = '', string $method = 'POST', ?arr
$curlOpts[CURLOPT_SSL_VERIFYPEER] = false;
$curlOpts[CURLOPT_SSL_VERIFYHOST] = 0;
}
+ if ($this->enableClientTLSCertificates) {
+ $curlOpts[CURLOPT_SSLKEY] = $this->clientTLSKeyFile;
+ $curlOpts[CURLOPT_SSLCERT] = $this->clientTLSCertificateFile;
+ $curlOpts[CURLOPT_SSLKEYPASSWD] = $this->clientTLSKeyPassword;
+ }
+
curl_setopt_array($curl, $curlOpts);
$rawResponse = curl_exec($curl);
diff --git a/lib/Service/Config.php b/lib/Service/Config.php
index 115dea5..5be4410 100644
--- a/lib/Service/Config.php
+++ b/lib/Service/Config.php
@@ -66,6 +66,14 @@ class Config
public const SHOW_TOP_LINE_DEFAULT = false;
public const ENABLE_SSL_VERIFY = 'enableSSLVerify';
public const ENABLE_SSL_VERIFY_DEFAULT = true;
+ public const ENABLE_TLS_CLIENT_CERTIFICATES = 'enableTLSClientCertificates';
+ public const ENABLE_TLS_CLIENT_CERTIFICATES_DEFAULT = false;
+ public const CLIENT_TLS_KEY_FILE = 'clientTLSKeyFile';
+ public const CLIENT_TLS_KEY_FILE_DEFAULT = '';
+ public const CLIENT_TLS_CERTIFICATE_FILE = 'clientTLSCertificateFile';
+ public const CLIENT_TLS_CERTIFICATE_FILE_DEFAULT = '';
+ public const CLIENT_TLS_KEY_PASSWORD = 'clientTLSKeyPassword';
+ public const CLIENT_TLS_KEY_PASSWORD_DEFAULT = '';
public const PERSONAL_ENCRYPTION = 'personalEncryption';
public const PERSONAL_ENCRYPTION_DEFAULT = false;
public const CARDDAV_PROVISIONG_TAG = 'cardDavProvisioningTag';
@@ -78,6 +86,10 @@ class Config
self::FORCE_SSO => self::FORCE_SSO_DEFAULT,
self::SHOW_TOP_LINE => self::SHOW_TOP_LINE_DEFAULT,
self::ENABLE_SSL_VERIFY => self::ENABLE_SSL_VERIFY_DEFAULT,
+ self::ENABLE_TLS_CLIENT_CERTIFICATES => self::ENABLE_TLS_CLIENT_CERTIFICATES_DEFAULT,
+ self::CLIENT_TLS_KEY_FILE => self::CLIENT_TLS_KEY_FILE_DEFAULT,
+ self::CLIENT_TLS_CERTIFICATE_FILE => self::CLIENT_TLS_CERTIFICATE_FILE_DEFAULT,
+ self::CLIENT_TLS_KEY_PASSWORD => self::CLIENT_TLS_KEY_PASSWORD_DEFAULT,
self::PERSONAL_ENCRYPTION => self::PERSONAL_ENCRYPTION_DEFAULT,
self::CARDDAV_PROVISIONG_TAG => self::CARDDAV_PROVISIONG_TAG_DEFAULT,
];
diff --git a/src/AdminSettings.vue b/src/AdminSettings.vue
index c8e36e0..62fe560 100644
--- a/src/AdminSettings.vue
+++ b/src/AdminSettings.vue
@@ -170,6 +170,41 @@
>
{{ t(appName, 'Enable SSL verification.') }}
+
+
+
+
+