diff --git a/CHANGELOG.md b/CHANGELOG.md index ec7a8c4f..3a88c7d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -299,4 +299,9 @@ ## 3.0.14 - 2024-09-16 ### Fix -- Fix for users experiencing issues with Secure Mail rendering in Nextcloud running versions >= 28.x \ No newline at end of file +- Fix for users experiencing issues with Secure Mail rendering in Nextcloud running versions >= 28.x + +## 3.0.15 - 2024-10-19 +### Features +- Added setting for controlling Presence Synchronisation (Outlook add-in) +- Added setting to configure default upload path (MS Teams add-in) \ No newline at end of file diff --git a/appinfo/info.xml b/appinfo/info.xml index 230f1896..c012e234 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -4,7 +4,7 @@ Sendent Sendent allows you to securely exchange files and emails Sendent now securely exchanges files and emails, integrating with both Microsoft Outlook and Microsoft Teams. This enhanced capability allows users to seamlessly conduct their work, not only within their preferred email environment but also within the collaborative framework of Microsoft Teams. Whether sharing privacy-sensitive documents, content, or handling attachments that exceed standard email size constraints, Sendent ensures a streamlined and secure communication experience. All files are directed to your Nextcloud instance, empowering you to control and manage access permissions effectively. - 3.0.14 + 3.0.15 agpl Sendent B.V. Sendent diff --git a/appinfo/routes.php b/appinfo/routes.php index 2cdc6449..0391c9fa 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -19,6 +19,7 @@ ['name' => 'setting_key_api#index', 'url' => '/api/1.0/settingkey/index', 'verb' => 'GET'], ['name' => 'setting_key_api#showByKey', 'url' => '/api/1.0/settingkey/showByKey/{key}', 'verb' => 'GET'], ['name' => 'setting_key_api#showByTemplateId', 'url' => '/api/1.0/settingkey/showByTemplateId/{templateid}', 'verb' => 'GET'], + ['name' => 'setting_key_api#showByTemplateKey', 'url' => '/api/1.0/settingkey/showByTemplateKey/{templatekey}', 'verb' => 'GET'], ['name' => 'setting_key_api#showTheming', 'url' => '/api/1.0/settingkey/theming', 'verb' => 'GET'], ['name' => 'setting_key_api#create', 'url' => '/api/1.0/settingkey', 'verb' => 'POST'], ['name' => 'setting_key_api#update', 'url' => '/api/1.0/settingkey/{id}', 'verb' => 'PUT'], @@ -46,6 +47,7 @@ ], ['name' => 'setting_template_api#index', 'url' => '/api/1.0/settingtemplate/index', 'verb' => 'GET'], ['name' => 'setting_template_api#show', 'url' => '/api/1.0/settingtemplate/{id}', 'verb' => 'GET'], + ['name' => 'setting_template_api#showByTemplateKey', 'url' => '/api/1.0/settingtemplate/bytemplatekey/{templateKey}', 'verb' => 'GET'], ['name' => 'setting_template_api#create', 'url' => '/api/1.0/settingtemplate', 'verb' => 'POST'], ['name' => 'setting_template_api#update', 'url' => '/api/1.0/settingtemplate/{id}', 'verb' => 'PUT'], ['name' => 'setting_template_api#destroy', 'url' => '/api/1.0/settingtemplate/{id}', 'verb' => 'DELETE'], diff --git a/lib/Controller/SettingKeyApiController.php b/lib/Controller/SettingKeyApiController.php index 4f9f565c..e554e7f6 100644 --- a/lib/Controller/SettingKeyApiController.php +++ b/lib/Controller/SettingKeyApiController.php @@ -55,7 +55,6 @@ public function showByKey(string $key) { public function showTheming() { return $this->service->findByTemplateId(1); } - /** * @NoAdminRequired * @NoCSRFRequired @@ -64,7 +63,6 @@ public function showTheming() { public function showByTemplateId(int $templateid) { return $this->service->findByTemplateId($templateid); } - /** * @NoAdminRequired * @NoCSRFRequired diff --git a/lib/Controller/SettingTemplateApiController.php b/lib/Controller/SettingTemplateApiController.php index e9f0d80c..a52d1b5d 100644 --- a/lib/Controller/SettingTemplateApiController.php +++ b/lib/Controller/SettingTemplateApiController.php @@ -52,7 +52,22 @@ public function show(int $id): DataResponse { return new DataResponse([], Http::STATUS_NOT_FOUND); } } - + /** + * @NoAdminRequired + * + * @NoCSRFRequired + * + * @param string $templateKey + * + * @return DataResponse + */ + public function showByTemplateKey(string $templateKey): DataResponse { + try { + return new DataResponse($this->mapper->getByTemplateKey($templateKey)); + } catch (Exception $e) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + } /** * @NoAdminRequired * diff --git a/lib/Db/SettingKeyMapper.php b/lib/Db/SettingKeyMapper.php index f96e8909..5ba373ed 100644 --- a/lib/Db/SettingKeyMapper.php +++ b/lib/Db/SettingKeyMapper.php @@ -89,7 +89,6 @@ public function findByTemplateId(int $id): array { return $this->findEntities($qb); } - /** * @return \OCP\AppFramework\Db\Entity[] * diff --git a/lib/Db/SettingTemplate.php b/lib/Db/SettingTemplate.php index 1cd3557b..7bb420a6 100644 --- a/lib/Db/SettingTemplate.php +++ b/lib/Db/SettingTemplate.php @@ -8,7 +8,7 @@ class SettingTemplate extends Entity implements JsonSerializable { protected $templatename; - + protected $templatekey; public function __construct() { // add types in constructor } @@ -16,7 +16,8 @@ public function __construct() { public function jsonSerialize() { return [ 'id' => $this->id, - 'templatename' => $this->templatename + 'templatename' => $this->templatename, + 'templatekey' => $this->templatekey ]; } } diff --git a/lib/Db/SettingTemplateMapper.php b/lib/Db/SettingTemplateMapper.php index 2b8e6e27..1061f827 100644 --- a/lib/Db/SettingTemplateMapper.php +++ b/lib/Db/SettingTemplateMapper.php @@ -30,7 +30,23 @@ public function find(int $id): \OCP\AppFramework\Db\Entity { return $this->findEntity($qb); } + /** + * @throws \OCP\AppFramework\Db\DoesNotExistException if not found + * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result + * + * @return \OCP\AppFramework\Db\Entity + */ + public function getByTemplateKey(string $templatekey): \OCP\AppFramework\Db\Entity { + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from('sndnt_stngtmplt') + ->where( + $qb->expr()->eq('templatekey', $qb->createNamedParameter($templatekey, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } /** * @return \OCP\AppFramework\Db\Entity[] * @@ -47,13 +63,13 @@ public function findAll($limit = null, $offset = null): array { return $this->findEntities($qb); } - public function settingKeyCount($name) { + public function settingTemplateCount($templatekey) { $qb = $this->db->getQueryBuilder(); $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') ->from('sndnt_stngtmplt') ->where( - $qb->expr()->eq('templatename', $qb->createNamedParameter($name, IQueryBuilder::PARAM_STR)) + $qb->expr()->eq('templatekey', $qb->createNamedParameter($templatekey, IQueryBuilder::PARAM_STR)) ); $cursor = $qb->execute(); diff --git a/lib/Migration/Version000020Date20241019100000.php b/lib/Migration/Version000020Date20241019100000.php new file mode 100644 index 00000000..ec717bf3 --- /dev/null +++ b/lib/Migration/Version000020Date20241019100000.php @@ -0,0 +1,85 @@ + + * + * @author Your name + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Sendent\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version000020Date20241019100000 extends SimpleMigrationStep { + + /** @var IDBConnection */ + private $db; + + public function __construct(IDBConnection $db) { + $this->db = $db; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('sndnt_stngtmplt')) { + // Adds a column to store templatekey + $table = $schema->getTable('sndnt_stngtmplt'); + $table->addColumn('templatekey', \OCP\DB\Types::STRING, [ + 'notnull' => false, + 'default' => '-1' + ]); + + //$table->addUniqueIndex(['templatekey'], 'sendent_templatekey_index'); + } + + + return $schema; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + + } +} diff --git a/lib/Service/InitialLoadManager.php b/lib/Service/InitialLoadManager.php index fb69a909..90b38bec 100644 --- a/lib/Service/InitialLoadManager.php +++ b/lib/Service/InitialLoadManager.php @@ -6,14 +6,18 @@ use OCA\Sendent\AppInfo\Application; use OCA\Sendent\Db\SettingKey; use OCA\Sendent\Db\SettingKeyMapper; +use OCA\Sendent\Db\SettingTemplateMapper; use OCA\Sendent\Db\SettingGroupValueMapper; use OCA\Sendent\Db\SettingGroupValue; +use OCA\Sendent\Db\SettingTemplate; +use Psr\Log\LoggerInterface; use OCP\App\IAppManager; use OCP\IConfig; use OCP\PreConditionNotMetException; class InitialLoadManager { private $SettingKeyMapper; + private $SettingTemplateMapper; private $SettingGroupValueMapper; private $SendentFileStorageManager; private $config; @@ -21,15 +25,22 @@ class InitialLoadManager { /** @var IAppManager */ private $appManager; + /** @var LoggerInterface */ + private $logger; + public function __construct( SettingKeyMapper $SettingKeyMapper, + SettingTemplateMapper $SettingTemplateMapper, SettingGroupValueMapper $SettingGroupValueMapper, SendentFileStorageManager $SendentFileStorageManager, + LoggerInterface $logger, IConfig $config, IAppManager $appManager) { - $this->SettingKeyMapper = $SettingKeyMapper; - $this->SettingGroupValueMapper = $SettingGroupValueMapper; + $this->SettingKeyMapper = $SettingKeyMapper; + $this->SettingTemplateMapper = $SettingTemplateMapper; + $this->SettingGroupValueMapper = $SettingGroupValueMapper; $this->SendentFileStorageManager = $SendentFileStorageManager; + $this->logger = $logger; $this->config = $config; $this->appManager = $appManager; @@ -39,26 +50,57 @@ public function __construct( /** * Return true if this is the first time a user is acessing their instance with deck enabled * - * @param $userId * @return bool */ public function checkUpdateNeeded115(): bool { $firstRun = $this->config->getAppValue('sendent', 'firstRunAppVersion'); - if ($firstRun !== '3.0.1') { - try { + if ($firstRun !== '3.0.15') { + try { + $this->logger->info('Initial load manager determined it needs to run. '); + $this->runInitialLoadTasks115(); - $this->config->setAppValue('sendent', 'firstRunAppVersion', '3.0.1'); + $this->config->setAppValue('sendent', 'firstRunAppVersion', '3.0.15'); } catch (PreConditionNotMetException $e) { + $this->logger->error('Error while running initial load manager. ' . $e); + return false; } return true; } + else{ + $this->logger->debug('Initial load manager determined it doesnt need to run. '); + + } return false; } private function runInitialLoadTasks115(): void { try { + if($this->SettingTemplateMapper->settingTemplateCount("0") < 1) + { + $this->logger->info('settingtemplate 0 not present, creating it. '); + $this->createTemplate("0", "msoutlook"); + } + if($this->SettingTemplateMapper->settingTemplateCount("1") < 1) + { + $this->logger->info('settingtemplate 1 not present, creating it. '); + $this->createTemplate("1", "msoutlook_advanced-theming"); + } + if($this->SettingTemplateMapper->settingTemplateCount("2") < 1) + { + $this->logger->info('settingtemplate 2 not present, creating it. '); + $this->createTemplate("2", "msteams"); + } + if ($this->SettingKeyMapper->settingKeyCount("401") < 1) { + $this->logger->info('statussync settingkey (401) not present, creating it. '); + $this->addStatusSync(); + } + if ($this->SettingKeyMapper->settingKeyCount("501") < 1) { + $this->logger->info('teams_pathuploadfiles settingkey (501) not present, creating it. '); + $this->addPathUploadFilesTeams(); + $this->fixTeams_pathuploadfiles(); + } if ($this->SettingKeyMapper->settingKeyCount("20") < 1) { $this->initialLoading(); } @@ -194,7 +236,26 @@ private function fixSnippets(): void { } catch (Exception $exception) { } } - + public function addStatusSync() : void { + $this->createKey("401", "statussync", "0", "select-one"); + $this->createGroupValue("0", "401", "False"); + } + public function addPathUploadFilesTeams() : void { + $this->createKey("501", "teams_pathuploadfiles", "2", "text"); + $this->createGroupValue("0", "501", "/MSTeams/Upload-Share/"); + } + private function fixTeams_pathuploadfiles(): void { + try { + $teams_pathuploadfiles = $this->showBySettingKeyId(501); + + if (!is_null($teams_pathuploadfiles)) { + if ($teams_pathuploadfiles->getValue() === '') { + $this->update($teams_pathuploadfiles->getId(), $teams_pathuploadfiles->getSettingkeyid(), $teams_pathuploadfiles->getGroupid(), "/MSTeams/Upload-Share/"); + } + } + } catch (Exception $exception) { + } + } public function addPopupExternalMail(): void { $this->createKey("31", "attachmentdomainexceptionsexternalpopup", "0", "select-one"); $this->createGroupValue("0", "31", "False"); @@ -520,24 +581,33 @@ public function addSecureMailUIMode(): void { $this->createKey("600", "securemailuimode", "0", "select-one"); $this->createGroupValue("0", "600", "toolbar"); } - public function createKey(string $key, string $name, string $templateid, string $valuetype) { + public function createKey(string $key, string $name, string $templatekey, string $valuetype) { try { $SettingKey = new settingkey(); $SettingKey->setKey($key); $SettingKey->setName($name); - $SettingKey->setTemplateid($templateid); + $SettingKey->setTemplateid($templatekey); $SettingKey->setValuetype($valuetype); return $this->SettingKeyMapper->insert($SettingKey); } catch (Exception $e) { return null; } } - - public function updateKey(string $key, string $name, string $templateid, string $valuetype) { + public function createTemplate(string $templatekey, string $name) { + try { + $SettingTemplate = new SettingTemplate(); + $SettingTemplate->setTemplatekey($templatekey); + $SettingTemplate->setTemplatename($name); + return $this->SettingTemplateMapper->insert($SettingTemplate); + } catch (Exception $e) { + return null; + } + } + public function updateKey(string $key, string $name, string $templatekey, string $valuetype) { try { $SettingKey = $this->SettingKeyMapper->findByKey($key); $SettingKey->setName($name); - $SettingKey->setTemplateid($templateid); + $SettingKey->setTemplateid($templatekey); $result = $this->SettingKeyMapper->update($SettingKey); return $this->showBySettingKeyId($key); } catch (Exception $e) { diff --git a/lib/Service/SettingKeyService.php b/lib/Service/SettingKeyService.php index bbe5e3dd..f80f398a 100644 --- a/lib/Service/SettingKeyService.php +++ b/lib/Service/SettingKeyService.php @@ -40,7 +40,9 @@ public function findByKey(string $key) { public function findByTemplateId(int $id) { return $this->mapper->findByTemplateId($id); } - + public function findByTemplateKey(int $key) { + return $this->mapper->findByTemplateKey($key); + } public function find(int $id) { try { return $this->mapper->find($id); diff --git a/src/imports/SettingFormHandler.ts b/src/imports/SettingFormHandler.ts index 51e6157c..7dd27e3e 100644 --- a/src/imports/SettingFormHandler.ts +++ b/src/imports/SettingFormHandler.ts @@ -42,6 +42,7 @@ export default class SettingFormHandler { const valueType = inputElement.prop('type'); if (!key || !name || !templateId || !valueType || typeof value !== 'string' || !groupId) { + console.warn('key, name, templateid, valuetype, not string or no groupid constrained triggerd. cannot continue with settings renderling.'); return; } diff --git a/templates/sections/general.php b/templates/sections/general.php index e3e4d698..58e838b6 100644 --- a/templates/sections/general.php +++ b/templates/sections/general.php @@ -204,4 +204,28 @@ + + + + + t('Presence Synchronization')); ?> + + + + + + t('Enabled')); ?> + t('Disabled')); ?> + + + + t('Use default group settings'));?> + + + + + + + + diff --git a/templates/sections/teams.php b/templates/sections/teams.php index f69f11d5..216f98e7 100644 --- a/templates/sections/teams.php +++ b/templates/sections/teams.php @@ -1,6 +1,30 @@ - + t('General')); ?> - t('Upon the next release of the Sendent for MS Teams integration, which will be coming soon, this page will contain settings.')); ?> + + + + + + t('Path for default upload')); ?> + + + + + + + + + t('Use default group settings')); ?> + + + + + + + + + \ No newline at end of file
t('Upon the next release of the Sendent for MS Teams integration, which will be coming soon, this page will contain settings.')); ?>