diff --git a/data/web/inc/ajax/qitem_details.php b/data/web/inc/ajax/qitem_details.php index 3c82ee6a..06feb1e7 100644 --- a/data/web/inc/ajax/qitem_details.php +++ b/data/web/inc/ajax/qitem_details.php @@ -91,6 +91,19 @@ if (!empty($_GET['id']) && ctype_alnum($_GET['id'])) { ); } } + if (isset($_GET['eml'])) { + $dl_filename = str_replace('/', '_', $data['subject']); + header('Pragma: public'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Cache-Control: private', false); + header('Content-Type: message/rfc822'); + header('Content-Disposition: attachment; filename="'. $dl_filename . '.eml";'); + header('Content-Transfer-Encoding: binary'); + header('Content-Length: ' . strlen($mailc['msg'])); + echo $mailc['msg']; + exit; + } if (isset($_GET['att'])) { if ($_SESSION['acl']['quarantine_attachments'] == 0) { exit(json_encode('Forbidden')); diff --git a/data/web/json_api.php b/data/web/json_api.php index ea4304af..d59cfe56 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -69,6 +69,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u // check for valid json if ($action != 'get' && $requestDecoded === null) { + http_response_code(400); echo json_encode(array( 'type' => 'error', 'msg' => 'Request body doesn\'t contain valid json!' @@ -126,6 +127,15 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u $attr = (array)json_decode($_POST['attr'], true); unset($attr['csrf_token']); } + // only allow POST requests to POST API endpoints + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + http_response_code(405); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'only POST method is allowed' + )); + exit(); + } switch ($category) { case "time_limited_alias": process_add_return(mailbox('add', 'time_limited_alias', $attr)); @@ -196,12 +206,29 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "tls-policy-map": process_add_return(tls_policy_maps('add', $attr)); break; + // return no route found if no case is matched + default: + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); } break; case "get": function process_get_return($data) { echo (!isset($data) || empty($data)) ? '{}' : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } + // only allow GET requests to GET API endpoints + if ($_SERVER['REQUEST_METHOD'] != 'GET') { + http_response_code(405); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'only GET method is allowed' + )); + exit(); + } switch ($category) { case "rspamd": switch ($object) { @@ -561,6 +588,14 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u } echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}'; break; + // return no route found if no case is matched + default: + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); } break; case "mailbox": @@ -1026,9 +1061,14 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u break; } break; + // return no route found if no case is matched default: - echo '{}'; - break; + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); } break; case "delete": @@ -1055,6 +1095,15 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u else { $items = (array)json_decode($_POST['items'], true); } + // only allow POST requests to POST API endpoints + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + http_response_code(405); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'only POST method is allowed' + )); + exit(); + } switch ($category) { case "alias": process_delete_return(mailbox('delete', 'alias', array('id' => $items))); @@ -1135,6 +1184,14 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "rlhash": echo ratelimit('delete', null, implode($items)); break; + // return no route found if no case is matched + default: + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); } break; case "edit": @@ -1163,6 +1220,15 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u unset($attr['csrf_token']); $items = isset($_POST['items']) ? (array)json_decode($_POST['items'], true) : null; } + // only allow POST requests to POST API endpoints + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + http_response_code(405); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'only POST method is allowed' + )); + exit(); + } switch ($category) { case "bcc": process_edit_return(bcc('edit', array_merge(array('id' => $items), $attr))); @@ -1271,8 +1337,29 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u process_edit_return(edit_user_account($attr)); } break; + // return no route found if no case is matched + default: + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); } break; + // return no route found if no case is matched + default: + http_response_code(404); + echo json_encode(array( + 'type' => 'error', + 'msg' => 'route not found' + )); + exit(); + } + } + if ($_SESSION['mailcow_cc_api'] === true) { + if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) { + unset($_SESSION['return']); } } } diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index 4e2ee972..71b86e0a 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -777,6 +777,7 @@ $lang['quarantine']['quarantine'] = "Quarantäne"; $lang['quarantine']['qinfo'] = 'Das Quarantänesystem speichert abgelehnte Nachrichten in der Datenbank. Dem Sender wird nicht signalisiert, dass seine E-Mail zugestellt wurde.
"' . $lang['quarantine']['learn_spam_delete'] . '" lernt Nachrichten nach bayesscher Statistik als Spam und erstellt Fuzzy Hashes ausgehend von der jeweiligen Nachricht, um ähnliche Inhalte zukünftig zu unterbinden.
Der Prozess des Lernens kann abhängig vom System zeitintensiv sein.'; +$lang['quarantine']['download_eml'] = "Herunterladen (.eml)"; $lang['quarantine']['release'] = "Freigeben"; $lang['quarantine']['empty'] = 'Keine Einträge'; $lang['quarantine']['toggle_all'] = 'Alle auswählen'; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index ad288ca7..1e6e7fd4 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -794,6 +794,7 @@ $lang['quarantine']['learn_spam_delete'] = "Learn as spam and delete"; $lang['quarantine']['qinfo'] = 'The quarantine system will save rejected mail to the database, while the sender will not be given the impression of a delivered mail.
"' . $lang['quarantine']['learn_spam_delete'] . '" will learn a message as spam via Bayesian theorem and also calculate fuzzy hashes to deny similar messages in the future.
Please be aware that learning multiple messages can be - depending on your system - time consuming.'; +$lang['quarantine']['download_eml'] = "Download (.eml)"; $lang['quarantine']['release'] = "Release"; $lang['quarantine']['empty'] = 'No results'; $lang['quarantine']['toggle_all'] = 'Toggle all'; diff --git a/data/web/modals/quarantine.php b/data/web/modals/quarantine.php index 0d091163..98871fa3 100644 --- a/data/web/modals/quarantine.php +++ b/data/web/modals/quarantine.php @@ -46,6 +46,8 @@ if (!isset($_SESSION['mailcow_cc_role'])) {
  • +
  • +