mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-29 11:01:34 +08:00
Move the "upload EML file to mailbox" Append feature into a DoFolderAppend()
This commit is contained in:
parent
fb2eb62f83
commit
5216535278
8 changed files with 102 additions and 145 deletions
|
@ -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
22
dev/bootstrap.js
vendored
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue