diff --git a/application/Espo/Core/Utils/TemplateFileManager.php b/application/Espo/Core/Utils/TemplateFileManager.php index a75f86a4ad..40f55ccca3 100644 --- a/application/Espo/Core/Utils/TemplateFileManager.php +++ b/application/Espo/Core/Utils/TemplateFileManager.php @@ -124,7 +124,13 @@ class TemplateFileManager ?string $entityType = null ): string { + $type = basename($type); + $language = basename($language); + $name = basename($name); + if ($entityType) { + $entityType = basename($entityType); + return "custom/Espo/Custom/Resources/templates/{$type}/{$language}/{$entityType}/{$name}.tpl"; } @@ -152,7 +158,13 @@ class TemplateFileManager ?string $entityType = null ): string { + $type = basename($type); + $language = basename($language); + $name = basename($name); + if ($entityType) { + $entityType = basename($entityType); + return "templates/{$type}/{$language}/{$entityType}/{$name}.tpl"; } diff --git a/application/Espo/EntryPoints/Attachment.php b/application/Espo/EntryPoints/Attachment.php index b085136224..0e1c6fafa5 100644 --- a/application/Espo/EntryPoints/Attachment.php +++ b/application/Espo/EntryPoints/Attachment.php @@ -95,7 +95,7 @@ class Attachment implements EntryPoint $response ->setHeader('Content-Length', (string) $size) ->setHeader('Cache-Control', 'private, max-age=864000, immutable') - ->setHeader('Content-Security-Policy', "default-src 'self'") + ->setHeader('Content-Security-Policy', "default-src 'self'; script-src 'none'; object-src 'none';") ->setBody($stream); } diff --git a/application/Espo/EntryPoints/Download.php b/application/Espo/EntryPoints/Download.php index 726a063086..672dc26d83 100644 --- a/application/Espo/EntryPoints/Download.php +++ b/application/Espo/EntryPoints/Download.php @@ -87,7 +87,7 @@ class Download implements EntryPoint if (in_array($type, $inlineMimeTypeList)) { $disposition = 'inline'; - $response->setHeader('Content-Security-Policy', "default-src 'self'"); + $response->setHeader('Content-Security-Policy', "default-src 'self'; script-src 'none'; object-src 'none';"); } $response->setHeader('Content-Description', 'File Transfer'); diff --git a/application/Espo/EntryPoints/Image.php b/application/Espo/EntryPoints/Image.php index 614a66bdd9..e86c66c63b 100644 --- a/application/Espo/EntryPoints/Image.php +++ b/application/Espo/EntryPoints/Image.php @@ -153,7 +153,7 @@ class Image implements EntryPoint $response ->setHeader('Content-Disposition', 'inline;filename="' . $fileName . '"') ->setHeader('Content-Length', (string) $fileSize) - ->setHeader('Content-Security-Policy', "default-src 'self'"); + ->setHeader('Content-Security-Policy', "default-src 'self'; script-src 'none'; object-src 'none';"); if (!$noCacheHeaders) { $response->setHeader('Cache-Control', 'private, max-age=864000, immutable'); diff --git a/application/Espo/Resources/i18n/cs_CZ/Admin.json b/application/Espo/Resources/i18n/cs_CZ/Admin.json index d716f75824..863b5a8126 100644 --- a/application/Espo/Resources/i18n/cs_CZ/Admin.json +++ b/application/Espo/Resources/i18n/cs_CZ/Admin.json @@ -252,9 +252,9 @@ "upgradeVersion": "EspoCRM bude upgradováno na verzi {version}. Toto může chvíli trvat.", "upgradeDone": "EspoCRM bylo upgradováno na verzi {version}.", "downloadUpgradePackage": "Stáhnout upgradovací balíčky na [tomto]({url}) odkaze.", - "upgradeInfo": "Přečtěte si [dokumentaci]({url}) o tom, jak upgradovat instanci AutoCRM.", + "upgradeInfo": "Přečtěte si [dokumentaci]({url}) o tom, jak upgradovat instanci EspoCRM.", "upgradeRecommendation": "Tento způsob upgradu se nedoporučuje. Je lepší upgradovat z CLI.", - "newVersionIsAvailable": "K dispozici je nová verze AutoCRM {latestVersion}. Při aktualizaci instance postupujte podle [pokynů](https://www.espocrm.com/documentation/administration/upgrading/).", + "newVersionIsAvailable": "K dispozici je nová verze EspoCRM {latestVersion}. Při aktualizaci instance postupujte podle [pokynů](https://www.espocrm.com/documentation/administration/upgrading/).", "formulaFunctions": "Funkce formula skriptů", "rebuildRequired": "Musíte spustit znovu rebuild z CLI.", "cronIsDisabled": "Cron je zakázán", @@ -293,7 +293,7 @@ "authLog": "Historie přihlášení.", "attachments": "Všechny přílohy souborů uložené v systému.", "templateManager": "Přizpůsobte si šablony zpráv.", - "systemRequirements": "Systémové požadavky na AutoCRM.", + "systemRequirements": "Systémové požadavky na EspoCRM.", "apiUsers": "Oddělte uživatele pro účely integrace.", "jobs": "Spustit akce na pozadí.", "pdfTemplates": "Šablony pro tisk do PDF.", @@ -377,4 +377,4 @@ "tabUrl": "URL záložky", "tabUrlAclScope": "ACL rozsah pro záložku URL" } -} \ No newline at end of file +} diff --git a/application/Espo/Resources/i18n/cs_CZ/Global.json b/application/Espo/Resources/i18n/cs_CZ/Global.json index 039ade6622..b34751db38 100644 --- a/application/Espo/Resources/i18n/cs_CZ/Global.json +++ b/application/Espo/Resources/i18n/cs_CZ/Global.json @@ -168,7 +168,7 @@ "Search": "Hledat", "Only My": "Pouze moje", "Open": "Otevřený", - "About": "O AutoCRM", + "About": "O EspoCRM", "Refresh": "Obnovit", "Remove": "Odebrat", "Options": "Možnosti", @@ -944,4 +944,4 @@ "edit": "Upravit", "delete": "Smazat" } -} \ No newline at end of file +} diff --git a/application/Espo/Resources/i18n/cs_CZ/Settings.json b/application/Espo/Resources/i18n/cs_CZ/Settings.json index 0aceaf8a40..8daf5ab359 100644 --- a/application/Espo/Resources/i18n/cs_CZ/Settings.json +++ b/application/Espo/Resources/i18n/cs_CZ/Settings.json @@ -186,18 +186,18 @@ "ldapBaseDn": "Výchozí základní DN používané pro vyhledávání uživatelů. Např. \"OU = uživatelé, OU = espocrm, DC = test, DC = lan\".", "ldapTryUsernameSplit": "Možnost rozdělit uživatelské jméno na doménu.", "ldapOptReferrals": "pokud by měla být sledována doporučení klientovi LDAP.", - "ldapCreateEspoUser": "Tato možnost umožňuje AutoCRM vytvořit uživatele z LDAP.", + "ldapCreateEspoUser": "Tato možnost umožňuje EspoCRM vytvořit uživatele z LDAP.", "ldapUserFirstNameAttribute": "Atribut LDAP, který se používá k určení křestního jména uživatele. Např. \"křestní jméno\".", "ldapUserLastNameAttribute": "Atribut LDAP, který se používá k určení příjmení uživatele. Např. \"sn\".", "ldapUserTitleAttribute": "LDAP atribut pro titul uživatele.", "ldapUserEmailAddressAttribute": "Atribut LDAP, který se používá k určení e-mailové adresy uživatele. Např. \"pošta\".", "ldapUserPhoneNumberAttribute": "LDAP atribut pro telefonní číslo uživatele.", - "ldapUserLoginFilter": "Filtr, který umožňuje omezit uživatele, kteří mohou používat AutoCRM. Např. \"memberOf = CN = espoGroup, OU = groups, OU = espocrm, DC = test, DC = lan\".", + "ldapUserLoginFilter": "Filtr, který umožňuje omezit uživatele, kteří mohou používat EspoCRM. Např. \"memberOf = CN = espoGroup, OU = groups, OU = espocrm, DC = test, DC = lan\".", "ldapAccountDomainName": "Doména, která se používá k autorizaci k serveru LDAP.", "ldapAccountDomainNameShort": "Krátká doména, která se používá k autorizaci k serveru LDAP.", "ldapUserTeams": "LDAP týmy pro uživatele.", "ldapUserDefaultTeam": "Výchozí tým pro vytvořeného uživatele. Další informace najdete v uživatelském profilu.", - "b2cMode": "Ve výchozím nastavení je AutoCRM přizpůsoben pro B2B. Můžete jej přepnout na B2C.", + "b2cMode": "Ve výchozím nastavení je EspoCRM přizpůsoben pro B2B. Můžete jej přepnout na B2C.", "aclStrictMode": "Povoleno: Přístup k rozsahům bude zakázán, pokud není uveden v rolích. \nZakázán: Přístup k rozsahům bude povolen, pokud není uveden v rolích.", "outboundEmailIsShared": "Povolit posílání emailů uživatelům pomocí SMTP.", "streamEmailNotificationsEntityList": "Emailová upozornění na aktualizace streamu sledovaných záznamů. Uživatelé budou dostávat e-mailová oznámení pouze pro určené typy entit.", @@ -310,4 +310,4 @@ "Email": "E-mail" } } -} \ No newline at end of file +} diff --git a/application/Espo/Tools/Email/Api/PostImportEml.php b/application/Espo/Tools/Email/Api/PostImportEml.php index 006bb779a4..2e11ac09e1 100644 --- a/application/Espo/Tools/Email/Api/PostImportEml.php +++ b/application/Espo/Tools/Email/Api/PostImportEml.php @@ -36,8 +36,11 @@ use Espo\Core\Api\Response; use Espo\Core\Api\ResponseComposer; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Exceptions\Forbidden; +use Espo\Core\Exceptions\NotFound; +use Espo\Entities\Attachment; use Espo\Entities\Email; use Espo\Entities\User; +use Espo\ORM\EntityManager; use Espo\Tools\Email\ImportEmlService; /** @@ -49,6 +52,7 @@ class PostImportEml implements Action private Acl $acl, private User $user, private ImportEmlService $service, + private EntityManager $entityManager, ) {} public function process(Request $request): Response @@ -61,11 +65,32 @@ class PostImportEml implements Action throw new BadRequest("No 'fileId'."); } - $email = $this->service->import($fileId, $this->user->getId()); + $attachment = $this->getAttachment($fileId); + + $email = $this->service->import($attachment, $this->user->getId()); return ResponseComposer::json(['id' => $email->getId()]); } + /** + * @throws NotFound + * @throws Forbidden + */ + private function getAttachment(string $fileId): Attachment + { + $attachment = $this->entityManager->getRDBRepositoryByClass(Attachment::class)->getById($fileId); + + if (!$attachment) { + throw new NotFound("Attachment not found."); + } + + if (!$this->acl->checkEntityRead($attachment)) { + throw new Forbidden("No access to attachment."); + } + + return $attachment; + } + /** * @throws Forbidden */ diff --git a/application/Espo/Tools/Email/ImportEmlService.php b/application/Espo/Tools/Email/ImportEmlService.php index 6b42359b2b..d5fd394440 100644 --- a/application/Espo/Tools/Email/ImportEmlService.php +++ b/application/Espo/Tools/Email/ImportEmlService.php @@ -31,7 +31,6 @@ namespace Espo\Tools\Email; use Espo\Core\Exceptions\Conflict; use Espo\Core\Exceptions\Error; -use Espo\Core\Exceptions\NotFound; use Espo\Core\FileStorage\Manager; use Espo\Core\Mail\Exceptions\ImapError; use Espo\Core\Mail\Importer; @@ -56,16 +55,13 @@ class ImportEmlService /** * Import an EML. * - * @param string $fileId An attachment ID. * @param ?string $userId A user ID to relate an email with. * @return Email An Email. - * @throws NotFound * @throws Error * @throws Conflict */ - public function import(string $fileId, ?string $userId = null): Email + public function import(Attachment $attachment, ?string $userId = null): Email { - $attachment = $this->getAttachment($fileId); $contents = $this->fileStorageManager->getContents($attachment); try { @@ -93,20 +89,6 @@ class ImportEmlService return $email; } - /** - * @throws NotFound - */ - private function getAttachment(string $fileId): Attachment - { - $attachment = $this->entityManager->getRDBRepositoryByClass(Attachment::class)->getById($fileId); - - if (!$attachment) { - throw new NotFound("Attachment not found."); - } - - return $attachment; - } - /** * @throws Conflict */ diff --git a/package-lock.json b/package-lock.json index bc4d8d8341..ece26e043b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "espocrm", - "version": "9.3.3", + "version": "9.3.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "espocrm", - "version": "9.3.3", + "version": "9.3.4", "hasInstallScript": true, "license": "AGPL-3.0-or-later", "dependencies": { diff --git a/package.json b/package.json index 1eabb451fe..b357775e6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "espocrm", - "version": "9.3.3", + "version": "9.3.4", "description": "Open-source CRM.", "repository": { "type": "git",