Merge branch 'stable'

This commit is contained in:
Yurii
2026-03-24 15:39:31 +02:00
11 changed files with 55 additions and 36 deletions

View File

@@ -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";
}

View File

@@ -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);
}

View File

@@ -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');

View File

@@ -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');

View File

@@ -252,9 +252,9 @@
"upgradeVersion": "EspoCRM bude upgradováno na verzi <strong>{version}</strong>. Toto může chvíli trvat.",
"upgradeDone": "EspoCRM bylo upgradováno na verzi <strong>{version}</strong>.",
"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"
}
}
}

View File

@@ -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"
}
}
}

View File

@@ -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"
}
}
}
}

View File

@@ -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
*/

View File

@@ -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
*/

4
package-lock.json generated
View File

@@ -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": {

View File

@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "9.3.3",
"version": "9.3.4",
"description": "Open-source CRM.",
"repository": {
"type": "git",