Move the "upload EML file to mailbox" Append feature into a DoFolderAppend()

This commit is contained in:
the-djmaze 2023-02-16 13:13:23 +01:00
parent fb2eb62f83
commit 5216535278
8 changed files with 102 additions and 145 deletions

View file

@ -9,8 +9,6 @@ import { SettingsUserStore } from 'Stores/User/Settings';
import { FolderUserStore } from 'Stores/User/Folder';
import { MessagelistUserStore } from 'Stores/User/Messagelist';
import { getNotification } from 'Common/Translator';
import { Settings } from 'Common/Globals';
import { serverRequest } from 'Common/Links';
import Remote from 'Remote/User/Fetch';
@ -286,28 +284,20 @@ moveMessagesToFolder = (sFromFolderFullName, oUids, sToFolderFullName, bCopy) =>
},
dropFilesInFolder = (sFolderFullName, files) => {
let count = 0,
fn = () => 0 == --count
&& FolderUserStore.currentFolderFullName() == sFolderFullName
&& MessagelistUserStore.reload(true, true);
let count = files.length;
for (const file of files) {
if ('message/rfc822' === file.type) {
++count;
let data = new FormData;
data.append('folder', sFolderFullName);
data.append('appendFile', file);
data.XToken = Settings.app('token');
fetch(serverRequest('Append'), {
method: 'POST',
mode: 'same-origin',
cache: 'no-cache',
redirect: 'error',
referrerPolicy: 'no-referrer',
credentials: 'same-origin',
body: data
})
.then(fn)
.catch(fn);
Remote.request('FolderAppend', (iError, data)=>{
iError && console.error(data.ErrorMessage);
0 == --count
&& FolderUserStore.currentFolderFullName() == sFolderFullName
&& MessagelistUserStore.reload(true, true);
}, data);
} else {
--count;
}
}
};

22
dev/bootstrap.js vendored
View file

@ -44,21 +44,31 @@ export default App => {
}, init);
if (postData) {
init.method = 'POST';
init.headers['Content-Type'] = 'application/json';
let asJSON = 1,
XToken = Settings.app('token'),
object = {};
if (postData instanceof FormData) {
const object = {};
postData.forEach((value, key) => {
if (!Reflect.has(object, key)){
if (value instanceof File) {
asJSON = 0;
} else if (!Reflect.has(object, key)) {
object[key] = value;
} else {
isArray(object[key]) || (object[key] = [object[key]]);
object[key].push(value);
}
});
postData = object;
if (asJSON) {
postData = object;
} else {
postData.set('XToken', XToken);
}
}
postData.XToken = Settings.app('token');
init.body = JSON.stringify(postData);
if (asJSON) {
init.headers['Content-Type'] = 'application/json';
postData = JSON.stringify(postData);
}
init.body = postData;
}
init.headers['X-SM-Token'] = Settings.app('token');
// init.headers = new Headers(init.headers);

View file

@ -2,8 +2,6 @@
namespace RainLoop;
use RainLoop\Enumerations\UploadError;
class Actions
{
use Actions\Admin;
@ -942,52 +940,6 @@ class Actions
return \MailSo\Base\Utils::SecureFileName(\MailSo\Base\Utils::Utf8Clear($sClearedFileName));
}
protected function getUploadErrorMessageByCode(int $iError, int &$iClientError): string
{
$sError = '';
$iClientError = UploadError::NORMAL;
switch ($iError) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
case UploadError::CONFIG_SIZE:
case UploadError::EMPTY_FILES_DATA:
$sError = 'File is too big';
$iClientError = UploadError::FILE_IS_TOO_BIG;
break;
case UPLOAD_ERR_PARTIAL:
$sError = 'File partially uploaded';
$iClientError = UploadError::FILE_PARTIALLY_UPLOADED;
break;
case UPLOAD_ERR_NO_FILE:
$sError = 'No file uploaded';
$iClientError = UploadError::FILE_NO_UPLOADED;
break;
case UPLOAD_ERR_NO_TMP_DIR:
case UPLOAD_ERR_CANT_WRITE:
case UPLOAD_ERR_EXTENSION:
$sError = 'Missing temp folder';
$iClientError = UploadError::MISSING_TEMP_FOLDER;
break;
case UploadError::ON_SAVING:
$sError = 'Error on saving file';
$iClientError = UploadError::FILE_ON_SAVING_ERROR;
break;
case UploadError::FILE_TYPE:
$sError = 'Invalid file type';
$iClientError = UploadError::FILE_TYPE;
break;
case UploadError::UNKNOWN:
default:
$sError = 'Unknown error';
$iClientError = UploadError::UNKNOWN;
break;
}
return $sError;
}
public function Upload(?array $aFile, int $iError): array
{
$oAccount = $this->getAccountFromToken();
@ -1018,8 +970,8 @@ class Actions
}
if (UPLOAD_ERR_OK !== $iError) {
$iClientError = Enumerations\UploadError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
$iClientError = 0;
$sError = Enumerations\UploadError::getUserMessage($iError, $iClientError);
if (!empty($sError)) {
$aResponse['ErrorCode'] = $iClientError;

View file

@ -157,8 +157,8 @@ trait Contacts
}
if (UPLOAD_ERR_OK !== $iError) {
$iClientError = \RainLoop\Enumerations\UploadError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
$iClientError = 0;
$sError = \RainLoop\Enumerations\UploadError::getUserMessage($iError, $iClientError);
if (!empty($sError)) {
return $this->FalseResponse($iClientError, $sError);
}

View file

@ -14,31 +14,35 @@ trait Folders
* Appends uploaded rfc822 message to mailbox
* @throws \MailSo\RuntimeException
*/
public function Append(): bool
public function DoFolderAppend(): array
{
$oAccount = $this->initMailClientConnection();
$sFolderFullName = $this->GetActionParam('folder', '');
if ($oAccount
&& !empty($sFolderFullName)
&& !empty($_FILES['appendFile'])
&& \is_uploaded_file($_FILES['appendFile']['tmp_name'])
&& \UPLOAD_ERR_OK == $_FILES['appendFile']['error']
&& $this->oConfig->Get('labs', 'allow_message_append', false)
) {
if (!$this->oConfig->Get('labs', 'allow_message_append', false)) {
return $this->FalseResponse(999, 'Permission denied');
}
if (empty($_FILES['appendFile'])) {
return $this->FalseResponse(999, 'No file');
}
if (\UPLOAD_ERR_OK != $_FILES['appendFile']['error']) {
return $this->FalseResponse($iErrorCode, \RainLoop\Enumerations\UploadError::getMessage($iErrorCode));
}
if ($oAccount && !empty($sFolderFullName) && \is_uploaded_file($_FILES['appendFile']['tmp_name'])) {
$sSavedName = 'append-post-' . \md5($sFolderFullName . $_FILES['appendFile']['name'] . $_FILES['appendFile']['tmp_name']);
if ($this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $_FILES['appendFile']['tmp_name'])) {
$iMessageStreamSize = $this->FilesProvider()->FileSize($oAccount, $sSavedName);
$rMessageStream = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
$this->MailClient()->MessageAppendStream($rMessageStream, $iMessageStreamSize, $sFolderFullName);
$this->FilesProvider()->Clear($oAccount, $sSavedName);
return $this->TrueResponse();
}
}
return $this->TrueResponse();
return $this->FalseResponse(999);
}
public function DoFolders() : array

View file

@ -209,8 +209,8 @@ trait Themes
}
if (UPLOAD_ERR_OK !== $iError) {
$iClientError = \RainLoop\Enumerations\UploadError::NORMAL;
$sError = $this->getUploadErrorMessageByCode($iError, $iClientError);
$iClientError = 0;
$sError = \RainLoop\Enumerations\UploadError::getUserMessage($iError, $iClientError);
if (!empty($sError)) {
return $this->FalseResponse($iClientError, $sError);
}

View file

@ -4,27 +4,62 @@ namespace RainLoop\Enumerations;
abstract class UploadError
{
// UPLOAD_ERR_OK; There is no error, the file uploaded with success.
const NORMAL = 0;
// UPLOAD_ERR_INI_SIZE; The uploaded file exceeds the upload_max_filesize directive in php.ini.
const FILE_IS_TOO_BIG = 1;
// UPLOAD_ERR_FORM_SIZE; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
// const FORM_SIZE = 2;
// UPLOAD_ERR_PARTIAL; The uploaded file was only partially uploaded.
const FILE_PARTIALLY_UPLOADED = 3;
// UPLOAD_ERR_NO_FILE; No file was uploaded.
const FILE_NO_UPLOADED = 4;
// UPLOAD_ERR_NO_TMP_DIR; Missing a temporary folder.
const MISSING_TEMP_FOLDER = 6;
// UPLOAD_ERR_CANT_WRITE; Failed to write file to disk.
const FILE_ON_SAVING_ERROR = 7;
// UPLOAD_ERR_EXTENSION; A PHP extension stopped the file upload
// const EXTENSION = 8;
const FILE_TYPE = 98;
const UNKNOWN = 99;
const CONFIG_SIZE = 1001;
const ON_SAVING = 1002;
const EMPTY_FILES_DATA = 1003;
private static $messages = [
\UPLOAD_ERR_INI_SIZE => 'Filesize exceeds the upload_max_filesize directive in php.ini',
\UPLOAD_ERR_FORM_SIZE => 'Filesize exceeds the MAX_FILE_SIZE directive that was specified in the html form',
\UPLOAD_ERR_PARTIAL => 'File was only partially uploaded',
\UPLOAD_ERR_NO_FILE => 'No file was uploaded',
\UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder',
\UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
\UPLOAD_ERR_EXTENSION => 'File upload stopped by extension',
98 => 'Invalid file type',
99 => 'Unknown error',
1001 => 'Filesize exceeds the config setting',
1002 => 'Error saving file',
1003 => 'File is empty'
];
public static function getMessage(int $code): string
{
return isset(static::$messages[$code]) ? static::$messages[$code] : 0;
}
protected function getUserMessage(int $iError, int &$iClientError): string
{
$iClientError = $iError;
switch ($iError) {
case \UPLOAD_ERR_OK:
case \UPLOAD_ERR_PARTIAL:
case \UPLOAD_ERR_NO_FILE:
case static::FILE_TYPE:
break;
case \UPLOAD_ERR_INI_SIZE:
case \UPLOAD_ERR_FORM_SIZE:
case static::CONFIG_SIZE:
case static::EMPTY_FILES_DATA:
return 'File is too big';
case \UPLOAD_ERR_NO_TMP_DIR:
case \UPLOAD_ERR_CANT_WRITE:
case \UPLOAD_ERR_EXTENSION:
case static::ON_SAVING:
$iClientError = static::FILE_ON_SAVING_ERROR;
break;
default:
$iClientError = static::UNKNOWN;
break;
}
return static::getMessage($iClientError);
}
}

View file

@ -77,7 +77,9 @@ class ServiceActions
$aResponse = null;
$oException = null;
$_POST = \json_decode(\file_get_contents('php://input'), true);
if (empty($_POST) || (!empty($_SERVER['CONTENT_TYPE']) && \str_contains($_SERVER['CONTENT_TYPE'], 'application/json'))) {
$_POST = \json_decode(\file_get_contents('php://input'), true);
}
$sAction = $_POST['Action'] ?? '';
if (empty($sAction) && $this->oHttp->IsGet() && !empty($this->aPaths[2])) {
@ -195,40 +197,6 @@ class ServiceActions
return $sResult;
}
public function ServiceAppend() : string
{
\ob_start();
$bResponse = false;
$oException = null;
try
{
if (\method_exists($this->oActions, 'Append') && \is_callable(array($this->oActions, 'Append'))) {
isset($_POST) && $this->oActions->SetActionParams($_POST, 'Append');
$bResponse = $this->oActions->Append();
}
}
catch (\Throwable $oException)
{
$bResponse = false;
}
\header('Content-Type: text/plain; charset=utf-8');
$sResult = true === $bResponse ? '1' : '0';
$sObResult = \ob_get_clean();
if (\strlen($sObResult)) {
$this->Logger()->Write($sObResult, \LOG_ERR, 'OB-DATA');
}
if ($oException) {
$this->Logger()->WriteException($oException, \LOG_ERR);
}
$this->Logger()->Write($sResult, \LOG_INFO, 'APPEND');
return $sResult;
}
private function privateUpload(string $sAction, int $iSizeLimit = 0) : string
{
$oConfig = $this->Config();
@ -239,10 +207,8 @@ class ServiceActions
{
$aFile = null;
$sInputName = 'uploader';
$iError = Enumerations\UploadError::UNKNOWN;
$iSizeLimit = (0 < $iSizeLimit ? $iSizeLimit : ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0))) * 1024 * 1024;
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
if (isset($_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size'])) {
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;