diff --git a/ElectronClient/app/package-lock.json b/ElectronClient/app/package-lock.json index 8e3953e38..de58b40d4 100644 --- a/ElectronClient/app/package-lock.json +++ b/ElectronClient/app/package-lock.json @@ -6625,6 +6625,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, + "syswide-cas": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/syswide-cas/-/syswide-cas-5.1.0.tgz", + "integrity": "sha512-IXrmaTC5MGyEA/9H43L7lpiUpCst3XqhS3/VZShi6opZo4wOj1t6nRwYqIjYdYooFJRK4uN/TXT/5P4O/snq1A==" + }, "tar": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.4.tgz", diff --git a/ElectronClient/app/package.json b/ElectronClient/app/package.json index 96154fd6a..7245ff57c 100644 --- a/ElectronClient/app/package.json +++ b/ElectronClient/app/package.json @@ -122,6 +122,7 @@ "sqlite3": "^3.1.13", "string-padding": "^1.0.2", "string-to-stream": "^1.1.1", + "syswide-cas": "^5.1.0", "tar": "^4.4.4", "tcp-port-used": "^0.1.2", "url-parse": "^1.4.1", diff --git a/ReactNativeClient/lib/BaseApplication.js b/ReactNativeClient/lib/BaseApplication.js index 9f0f8f26f..6e19156bd 100644 --- a/ReactNativeClient/lib/BaseApplication.js +++ b/ReactNativeClient/lib/BaseApplication.js @@ -24,6 +24,7 @@ const os = require('os'); const fs = require('fs-extra'); const JoplinError = require('lib/JoplinError'); const EventEmitter = require('events'); +const syswidecas = require('syswide-cas'); const SyncTargetRegistry = require('lib/SyncTargetRegistry.js'); const SyncTargetFilesystem = require('lib/SyncTargetFilesystem.js'); const SyncTargetOneDrive = require('lib/SyncTargetOneDrive.js'); @@ -314,6 +315,15 @@ class BaseApplication { process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = Setting.value('net.ignoreTlsErrors') ? '0' : '1'; } + if ((action.type == 'SETTING_UPDATE_ONE' && action.key == 'net.customCertificates') || (action.type == 'SETTING_UPDATE_ALL')) { + const caPaths = Setting.value('net.customCertificates').split(','); + for (let i = 0; i < caPaths.length; i++) { + const f = caPaths[i].trim(); + if (!f) continue; + syswidecas.addCAs(f); + } + } + if ((action.type == 'SETTING_UPDATE_ONE' && (action.key.indexOf('encryption.') === 0)) || (action.type == 'SETTING_UPDATE_ALL')) { if (this.hasGui()) { await EncryptionService.instance().loadMasterKeysFromSettings(); diff --git a/ReactNativeClient/lib/models/Setting.js b/ReactNativeClient/lib/models/Setting.js index 32ca96049..f83041578 100644 --- a/ReactNativeClient/lib/models/Setting.js +++ b/ReactNativeClient/lib/models/Setting.js @@ -150,6 +150,7 @@ class Setting extends BaseModel { 'sync.6.context': { value: '', type: Setting.TYPE_STRING, public: false }, 'sync.7.context': { value: '', type: Setting.TYPE_STRING, public: false }, + 'net.customCertificates': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return [SyncTargetRegistry.nameToId('nextcloud'), SyncTargetRegistry.nameToId('webdav')].indexOf(settings['sync.target']) >= 0 }, public: true, appTypes: ['desktop', 'cli'], label: () => _('Custom TLS certificates'), description: () => _('Comma-separated list of paths to directories to load the certificates from, or path to individual cert files. For example: /my/cert_dir, /other/custom.pem') }, 'net.ignoreTlsErrors': { value: false, type: Setting.TYPE_BOOL, show: (settings) => { return [SyncTargetRegistry.nameToId('nextcloud'), SyncTargetRegistry.nameToId('webdav')].indexOf(settings['sync.target']) >= 0 }, public: true, appTypes: ['desktop', 'cli'], label: () => _('Ignore TLS certificate errors') }, };