json_api.php 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538
  1. <?php
  2. /*
  3. see /api
  4. */
  5. header('Content-Type: application/json');
  6. require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
  7. error_reporting(0);
  8. function api_log($_data) {
  9. global $redis;
  10. $data_var = array();
  11. foreach ($_data as $data => &$value) {
  12. if ($data == 'csrf_token') {
  13. continue;
  14. }
  15. if ($value = json_decode($value, true)) {
  16. unset($value["csrf_token"]);
  17. foreach ($value as $key => &$val) {
  18. if(preg_match("/pass/i", $key)) {
  19. $val = '*';
  20. }
  21. }
  22. $value = json_encode($value);
  23. }
  24. $data_var[] = $data . "='" . $value . "'";
  25. }
  26. try {
  27. $log_line = array(
  28. 'time' => time(),
  29. 'uri' => $_SERVER['REQUEST_URI'],
  30. 'method' => $_SERVER['REQUEST_METHOD'],
  31. 'remote' => get_remote_ip(),
  32. 'data' => implode(', ', $data_var)
  33. );
  34. $redis->lPush('API_LOG', json_encode($log_line));
  35. }
  36. catch (RedisException $e) {
  37. $_SESSION['return'][] = array(
  38. 'type' => 'danger',
  39. 'msg' => 'Redis: '.$e
  40. );
  41. return false;
  42. }
  43. }
  44. if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_username'])) {
  45. if (isset($_GET['query'])) {
  46. $query = explode('/', $_GET['query']);
  47. $action = (isset($query[0])) ? $query[0] : null;
  48. $category = (isset($query[1])) ? $query[1] : null;
  49. $object = (isset($query[2])) ? $query[2] : null;
  50. $extra = (isset($query[3])) ? $query[3] : null;
  51. // accept json in request body
  52. if($_SERVER['HTTP_CONTENT_TYPE'] === 'application/json') {
  53. $request = file_get_contents('php://input');
  54. $requestDecoded = json_decode($request, true);
  55. // check for valid json
  56. if ($action != 'get' && $requestDecoded === null) {
  57. http_response_code(400);
  58. echo json_encode(array(
  59. 'type' => 'error',
  60. 'msg' => 'Request body doesn\'t contain valid json!'
  61. ));
  62. exit;
  63. }
  64. // add
  65. if ($action == 'add') {
  66. $_POST['attr'] = $request;
  67. }
  68. // edit
  69. if ($action == 'edit') {
  70. $_POST['attr'] = json_encode($requestDecoded['attr']);
  71. $_POST['items'] = json_encode($requestDecoded['items']);
  72. }
  73. // delete
  74. if ($action == 'delete') {
  75. $_POST['items'] = $request;
  76. }
  77. }
  78. api_log($_POST);
  79. $request_incomplete = json_encode(array(
  80. 'type' => 'error',
  81. 'msg' => 'Cannot find attributes in post data'
  82. ));
  83. switch ($action) {
  84. case "add":
  85. if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username'])) {
  86. http_response_code(403);
  87. echo json_encode(array(
  88. 'type' => 'error',
  89. 'msg' => 'API read/write access denied'
  90. ));
  91. exit();
  92. }
  93. function process_add_return($return) {
  94. $generic_failure = json_encode(array(
  95. 'type' => 'error',
  96. 'msg' => 'Cannot add item'
  97. ));
  98. $generic_success = json_encode(array(
  99. 'type' => 'success',
  100. 'msg' => 'Task completed'
  101. ));
  102. if ($return === false) {
  103. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
  104. }
  105. else {
  106. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
  107. }
  108. }
  109. if (!isset($_POST['attr'])) {
  110. echo $request_incomplete;
  111. exit;
  112. }
  113. else {
  114. $attr = (array)json_decode($_POST['attr'], true);
  115. unset($attr['csrf_token']);
  116. }
  117. // only allow POST requests to POST API endpoints
  118. if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  119. http_response_code(405);
  120. echo json_encode(array(
  121. 'type' => 'error',
  122. 'msg' => 'only POST method is allowed'
  123. ));
  124. exit();
  125. }
  126. switch ($category) {
  127. case "time_limited_alias":
  128. process_add_return(mailbox('add', 'time_limited_alias', $attr));
  129. break;
  130. case "relayhost":
  131. process_add_return(relayhost('add', $attr));
  132. break;
  133. case "transport":
  134. process_add_return(transport('add', $attr));
  135. break;
  136. case "rsetting":
  137. process_add_return(rsettings('add', $attr));
  138. break;
  139. case "mailbox":
  140. process_add_return(mailbox('add', 'mailbox', $attr));
  141. break;
  142. case "oauth2-client":
  143. process_add_return(oauth2('add', 'client', $attr));
  144. break;
  145. case "domain":
  146. process_add_return(mailbox('add', 'domain', $attr));
  147. break;
  148. case "resource":
  149. process_add_return(mailbox('add', 'resource', $attr));
  150. break;
  151. case "alias":
  152. process_add_return(mailbox('add', 'alias', $attr));
  153. break;
  154. case "filter":
  155. process_add_return(mailbox('add', 'filter', $attr));
  156. break;
  157. case "global-filter":
  158. process_add_return(mailbox('add', 'global_filter', $attr));
  159. break;
  160. case "domain-policy":
  161. process_add_return(policy('add', 'domain', $attr));
  162. break;
  163. case "mailbox-policy":
  164. process_add_return(policy('add', 'mailbox', $attr));
  165. break;
  166. case "alias-domain":
  167. process_add_return(mailbox('add', 'alias_domain', $attr));
  168. break;
  169. case "fwdhost":
  170. process_add_return(fwdhost('add', $attr));
  171. break;
  172. case "dkim":
  173. process_add_return(dkim('add', $attr));
  174. break;
  175. case "dkim_duplicate":
  176. process_add_return(dkim('duplicate', $attr));
  177. break;
  178. case "dkim_import":
  179. process_add_return(dkim('import', $attr));
  180. break;
  181. case "domain-admin":
  182. process_add_return(domain_admin('add', $attr));
  183. break;
  184. case "admin":
  185. process_add_return(admin('add', $attr));
  186. break;
  187. case "syncjob":
  188. process_add_return(mailbox('add', 'syncjob', $attr));
  189. break;
  190. case "bcc":
  191. process_add_return(bcc('add', $attr));
  192. break;
  193. case "recipient_map":
  194. process_add_return(recipient_map('add', $attr));
  195. break;
  196. case "tls-policy-map":
  197. process_add_return(tls_policy_maps('add', $attr));
  198. break;
  199. case "app-passwd":
  200. process_add_return(app_passwd('add', $attr));
  201. break;
  202. // return no route found if no case is matched
  203. default:
  204. http_response_code(404);
  205. echo json_encode(array(
  206. 'type' => 'error',
  207. 'msg' => 'route not found'
  208. ));
  209. exit();
  210. }
  211. break;
  212. case "get":
  213. function process_get_return($data) {
  214. echo (!isset($data) || empty($data)) ? '{}' : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
  215. }
  216. // only allow GET requests to GET API endpoints
  217. if ($_SERVER['REQUEST_METHOD'] != 'GET') {
  218. http_response_code(405);
  219. echo json_encode(array(
  220. 'type' => 'error',
  221. 'msg' => 'only GET method is allowed'
  222. ));
  223. exit();
  224. }
  225. if (!isset($_SESSION['pending_mailcow_cc_username'])) {
  226. switch ($category) {
  227. case "u2f-registration":
  228. header('Content-Type: application/javascript');
  229. if (($_SESSION["mailcow_cc_role"] == "admin" || $_SESSION["mailcow_cc_role"] == "domainadmin") && $_SESSION["mailcow_cc_username"] == $object) {
  230. list($req, $sigs) = $u2f->getRegisterData(get_u2f_registrations($object));
  231. $_SESSION['regReq'] = json_encode($req);
  232. $_SESSION['regSigs'] = json_encode($sigs);
  233. echo 'var req = ' . json_encode($req) . ';';
  234. echo 'var registeredKeys = ' . json_encode($sigs) . ';';
  235. echo 'var appId = req.appId;';
  236. echo 'var registerRequests = [{version: req.version, challenge: req.challenge}];';
  237. }
  238. else {
  239. return;
  240. }
  241. break;
  242. case "u2f-authentication":
  243. header('Content-Type: application/javascript');
  244. if (isset($_SESSION['pending_mailcow_cc_username']) && $_SESSION['pending_mailcow_cc_username'] == $object) {
  245. $auth_data = $u2f->getAuthenticateData(get_u2f_registrations($object));
  246. $challenge = $auth_data[0]->challenge;
  247. $appId = $auth_data[0]->appId;
  248. foreach ($auth_data as $each) {
  249. $key = array(); // Empty array
  250. $key['version'] = $each->version;
  251. $key['keyHandle'] = $each->keyHandle;
  252. $registeredKey[] = $key;
  253. }
  254. $_SESSION['authReq'] = json_encode($auth_data);
  255. echo 'var appId = "' . $appId . '";';
  256. echo 'var challenge = ' . json_encode($challenge) . ';';
  257. echo 'var registeredKeys = ' . json_encode($registeredKey) . ';';
  258. }
  259. else {
  260. return;
  261. }
  262. break;
  263. case "rspamd":
  264. switch ($object) {
  265. case "actions":
  266. $curl = curl_init();
  267. curl_setopt($curl, CURLOPT_UNIX_SOCKET_PATH, '/var/lib/rspamd/rspamd.sock');
  268. curl_setopt($curl, CURLOPT_URL,"http://rspamd/stat");
  269. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  270. $data = curl_exec($curl);
  271. if ($data) {
  272. $return = array();
  273. $stats_array = json_decode($data, true)['actions'];
  274. $stats_array['soft reject'] = $stats_array['soft reject'] + $stats_array['greylist'];
  275. unset($stats_array['greylist']);
  276. foreach ($stats_array as $action => $count) {
  277. $return[] = array($action, $count);
  278. }
  279. echo json_encode($return, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
  280. }
  281. elseif (!isset($data) || empty($data)) {
  282. echo '{}';
  283. }
  284. break;
  285. }
  286. break;
  287. case "domain":
  288. switch ($object) {
  289. case "all":
  290. $domains = mailbox('get', 'domains');
  291. if (!empty($domains)) {
  292. foreach ($domains as $domain) {
  293. if ($details = mailbox('get', 'domain_details', $domain)) {
  294. $data[] = $details;
  295. }
  296. else {
  297. continue;
  298. }
  299. }
  300. process_get_return($data);
  301. }
  302. else {
  303. echo '{}';
  304. }
  305. break;
  306. default:
  307. $data = mailbox('get', 'domain_details', $object);
  308. process_get_return($data);
  309. break;
  310. }
  311. break;
  312. case "app-passwd":
  313. switch ($object) {
  314. case "all":
  315. if (empty($extra)) {
  316. $app_passwds = app_passwd('get');
  317. }
  318. else {
  319. $app_passwds = app_passwd('get', array('username' => $extra));
  320. }
  321. if (!empty($app_passwds)) {
  322. foreach ($app_passwds as $app_passwd) {
  323. $details = app_passwd('details', array('id' => $app_passwd['id']));
  324. if ($details !== false) {
  325. $data[] = $details;
  326. }
  327. else {
  328. continue;
  329. }
  330. }
  331. process_get_return($data);
  332. }
  333. else {
  334. echo '{}';
  335. }
  336. break;
  337. default:
  338. $data = app_passwd('details', array('id' => $object['id']));
  339. process_get_return($data);
  340. break;
  341. }
  342. break;
  343. case "mailq":
  344. switch ($object) {
  345. case "all":
  346. $mailq = mailq('get');
  347. if (!empty($mailq)) {
  348. echo $mailq;
  349. }
  350. else {
  351. echo '{}';
  352. }
  353. break;
  354. }
  355. break;
  356. case "global_filters":
  357. $global_filters = mailbox('get', 'global_filter_details');
  358. switch ($object) {
  359. case "all":
  360. if (!empty($global_filters)) {
  361. process_get_return($global_filters);
  362. }
  363. else {
  364. echo '{}';
  365. }
  366. break;
  367. case "prefilter":
  368. if (!empty($global_filters['prefilter'])) {
  369. process_get_return($global_filters['prefilter']);
  370. }
  371. else {
  372. echo '{}';
  373. }
  374. break;
  375. case "postfilter":
  376. if (!empty($global_filters['postfilter'])) {
  377. process_get_return($global_filters['postfilter']);
  378. }
  379. else {
  380. echo '{}';
  381. }
  382. break;
  383. }
  384. break;
  385. case "rl-domain":
  386. switch ($object) {
  387. case "all":
  388. $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
  389. if (!empty($domains)) {
  390. foreach ($domains as $domain) {
  391. if ($details = ratelimit('get', 'domain', $domain)) {
  392. $details['domain'] = $domain;
  393. $data[] = $details;
  394. }
  395. else {
  396. continue;
  397. }
  398. }
  399. process_get_return($data);
  400. }
  401. else {
  402. echo '{}';
  403. }
  404. break;
  405. default:
  406. $data = ratelimit('get', 'domain', $object);
  407. process_get_return($data);
  408. break;
  409. }
  410. break;
  411. case "rl-mbox":
  412. switch ($object) {
  413. case "all":
  414. $domains = mailbox('get', 'domains');
  415. if (!empty($domains)) {
  416. foreach ($domains as $domain) {
  417. $mailboxes = mailbox('get', 'mailboxes', $domain);
  418. if (!empty($mailboxes)) {
  419. foreach ($mailboxes as $mailbox) {
  420. if ($details = ratelimit('get', 'mailbox', $mailbox)) {
  421. $details['mailbox'] = $mailbox;
  422. $data[] = $details;
  423. }
  424. else {
  425. continue;
  426. }
  427. }
  428. }
  429. }
  430. process_get_return($data);
  431. }
  432. else {
  433. echo '{}';
  434. }
  435. break;
  436. default:
  437. $data = ratelimit('get', 'mailbox', $object);
  438. process_get_return($data);
  439. break;
  440. }
  441. break;
  442. case "relayhost":
  443. switch ($object) {
  444. case "all":
  445. $relayhosts = relayhost('get');
  446. if (!empty($relayhosts)) {
  447. foreach ($relayhosts as $relayhost) {
  448. if ($details = relayhost('details', $relayhost['id'])) {
  449. $data[] = $details;
  450. }
  451. else {
  452. continue;
  453. }
  454. }
  455. process_get_return($data);
  456. }
  457. else {
  458. echo '{}';
  459. }
  460. break;
  461. default:
  462. $data = relayhost('details', $object);
  463. process_get_return($data);
  464. break;
  465. }
  466. break;
  467. case "transport":
  468. switch ($object) {
  469. case "all":
  470. $transports = transport('get');
  471. if (!empty($transports)) {
  472. foreach ($transports as $transport) {
  473. if ($details = transport('details', $transport['id'])) {
  474. $data[] = $details;
  475. }
  476. else {
  477. continue;
  478. }
  479. }
  480. process_get_return($data);
  481. }
  482. else {
  483. echo '{}';
  484. }
  485. break;
  486. default:
  487. $data = transport('details', $object);
  488. process_get_return($data);
  489. break;
  490. }
  491. break;
  492. case "rsetting":
  493. switch ($object) {
  494. case "all":
  495. $rsettings = rsettings('get');
  496. if (!empty($rsettings)) {
  497. foreach ($rsettings as $rsetting) {
  498. if ($details = rsettings('details', $rsetting['id'])) {
  499. $data[] = $details;
  500. }
  501. else {
  502. continue;
  503. }
  504. }
  505. process_get_return($data);
  506. }
  507. else {
  508. echo '{}';
  509. }
  510. break;
  511. default:
  512. $data = rsetting('details', $object);
  513. process_get_return($data);
  514. break;
  515. }
  516. break;
  517. case "oauth2-client":
  518. switch ($object) {
  519. case "all":
  520. $clients = oauth2('get', 'clients');
  521. if (!empty($clients)) {
  522. foreach ($clients as $client) {
  523. if ($details = oauth2('details', 'client', $client)) {
  524. $data[] = $details;
  525. }
  526. else {
  527. continue;
  528. }
  529. }
  530. process_get_return($data);
  531. }
  532. else {
  533. echo '{}';
  534. }
  535. break;
  536. default:
  537. $data = oauth2('details', 'client', $object);
  538. process_get_return($data);
  539. break;
  540. }
  541. break;
  542. case "logs":
  543. switch ($object) {
  544. case "dovecot":
  545. // 0 is first record, so empty is fine
  546. if (isset($extra)) {
  547. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  548. $logs = get_logs('dovecot-mailcow', $extra);
  549. }
  550. else {
  551. $logs = get_logs('dovecot-mailcow');
  552. }
  553. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  554. break;
  555. case "ratelimited":
  556. // 0 is first record, so empty is fine
  557. if (isset($extra)) {
  558. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  559. $logs = get_logs('ratelimited', $extra);
  560. }
  561. else {
  562. $logs = get_logs('ratelimited');
  563. }
  564. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  565. break;
  566. case "netfilter":
  567. // 0 is first record, so empty is fine
  568. if (isset($extra)) {
  569. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  570. $logs = get_logs('netfilter-mailcow', $extra);
  571. }
  572. else {
  573. $logs = get_logs('netfilter-mailcow');
  574. }
  575. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  576. break;
  577. case "postfix":
  578. // 0 is first record, so empty is fine
  579. if (isset($extra)) {
  580. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  581. $logs = get_logs('postfix-mailcow', $extra);
  582. }
  583. else {
  584. $logs = get_logs('postfix-mailcow');
  585. }
  586. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  587. break;
  588. case "autodiscover":
  589. // 0 is first record, so empty is fine
  590. if (isset($extra)) {
  591. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  592. $logs = get_logs('autodiscover-mailcow', $extra);
  593. }
  594. else {
  595. $logs = get_logs('autodiscover-mailcow');
  596. }
  597. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  598. break;
  599. case "sogo":
  600. // 0 is first record, so empty is fine
  601. if (isset($extra)) {
  602. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  603. $logs = get_logs('sogo-mailcow', $extra);
  604. }
  605. else {
  606. $logs = get_logs('sogo-mailcow');
  607. }
  608. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  609. break;
  610. case "ui":
  611. // 0 is first record, so empty is fine
  612. if (isset($extra)) {
  613. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  614. $logs = get_logs('mailcow-ui', $extra);
  615. }
  616. else {
  617. $logs = get_logs('mailcow-ui');
  618. }
  619. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  620. break;
  621. case "watchdog":
  622. // 0 is first record, so empty is fine
  623. if (isset($extra)) {
  624. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  625. $logs = get_logs('watchdog-mailcow', $extra);
  626. }
  627. else {
  628. $logs = get_logs('watchdog-mailcow');
  629. }
  630. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  631. break;
  632. case "acme":
  633. // 0 is first record, so empty is fine
  634. if (isset($extra)) {
  635. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  636. $logs = get_logs('acme-mailcow', $extra);
  637. }
  638. else {
  639. $logs = get_logs('acme-mailcow');
  640. }
  641. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  642. break;
  643. case "api":
  644. // 0 is first record, so empty is fine
  645. if (isset($extra)) {
  646. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  647. $logs = get_logs('api-mailcow', $extra);
  648. }
  649. else {
  650. $logs = get_logs('api-mailcow');
  651. }
  652. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  653. break;
  654. case "rspamd-history":
  655. // 0 is first record, so empty is fine
  656. if (isset($extra)) {
  657. $extra = preg_replace('/[^\d\-]/i', '', $extra);
  658. $logs = get_logs('rspamd-history', $extra);
  659. }
  660. else {
  661. $logs = get_logs('rspamd-history');
  662. }
  663. echo (isset($logs) && !empty($logs)) ? json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) : '{}';
  664. break;
  665. // return no route found if no case is matched
  666. default:
  667. http_response_code(404);
  668. echo json_encode(array(
  669. 'type' => 'error',
  670. 'msg' => 'route not found'
  671. ));
  672. exit();
  673. }
  674. break;
  675. case "mailbox":
  676. switch ($object) {
  677. case "all":
  678. if (empty($extra)) {
  679. $domains = mailbox('get', 'domains');
  680. }
  681. else {
  682. $domains = array($extra);
  683. }
  684. if (!empty($domains)) {
  685. foreach ($domains as $domain) {
  686. $mailboxes = mailbox('get', 'mailboxes', $domain);
  687. if (!empty($mailboxes)) {
  688. foreach ($mailboxes as $mailbox) {
  689. if ($details = mailbox('get', 'mailbox_details', $mailbox)) {
  690. $data[] = $details;
  691. }
  692. else {
  693. continue;
  694. }
  695. }
  696. }
  697. }
  698. process_get_return($data);
  699. }
  700. else {
  701. echo '{}';
  702. }
  703. break;
  704. default:
  705. $data = mailbox('get', 'mailbox_details', $object);
  706. process_get_return($data);
  707. break;
  708. }
  709. break;
  710. case "syncjobs":
  711. switch ($object) {
  712. case "all":
  713. $domains = mailbox('get', 'domains');
  714. if (!empty($domains)) {
  715. foreach ($domains as $domain) {
  716. $mailboxes = mailbox('get', 'mailboxes', $domain);
  717. if (!empty($mailboxes)) {
  718. foreach ($mailboxes as $mailbox) {
  719. $syncjobs = mailbox('get', 'syncjobs', $mailbox);
  720. if (!empty($syncjobs)) {
  721. foreach ($syncjobs as $syncjob) {
  722. if (isset($extra)) {
  723. $details = mailbox('get', 'syncjob_details', $syncjob, explode(',', $extra));
  724. }
  725. else {
  726. $details = mailbox('get', 'syncjob_details', $syncjob);
  727. }
  728. if ($details) {
  729. $data[] = $details;
  730. }
  731. else {
  732. continue;
  733. }
  734. }
  735. }
  736. }
  737. }
  738. }
  739. process_get_return($data);
  740. }
  741. else {
  742. echo '{}';
  743. }
  744. break;
  745. default:
  746. $syncjobs = mailbox('get', 'syncjobs', $object);
  747. if (!empty($syncjobs)) {
  748. foreach ($syncjobs as $syncjob) {
  749. if (isset($extra)) {
  750. $details = mailbox('get', 'syncjob_details', $syncjob, explode(',', $extra));
  751. }
  752. else {
  753. $details = mailbox('get', 'syncjob_details', $syncjob);
  754. }
  755. if ($details) {
  756. $data[] = $details;
  757. }
  758. else {
  759. continue;
  760. }
  761. }
  762. }
  763. process_get_return($data);
  764. break;
  765. }
  766. break;
  767. case "active-user-sieve":
  768. if (isset($object)) {
  769. $sieve_filter = mailbox('get', 'active_user_sieve', $object);
  770. if (!empty($sieve_filter)) {
  771. $data[] = $sieve_filter;
  772. }
  773. }
  774. process_get_return($data);
  775. break;
  776. case "filters":
  777. switch ($object) {
  778. case "all":
  779. $domains = mailbox('get', 'domains');
  780. if (!empty($domains)) {
  781. foreach ($domains as $domain) {
  782. $mailboxes = mailbox('get', 'mailboxes', $domain);
  783. if (!empty($mailboxes)) {
  784. foreach ($mailboxes as $mailbox) {
  785. $filters = mailbox('get', 'filters', $mailbox);
  786. if (!empty($filters)) {
  787. foreach ($filters as $filter) {
  788. if ($details = mailbox('get', 'filter_details', $filter)) {
  789. $data[] = $details;
  790. }
  791. else {
  792. continue;
  793. }
  794. }
  795. }
  796. }
  797. }
  798. }
  799. process_get_return($data);
  800. }
  801. else {
  802. echo '{}';
  803. }
  804. break;
  805. default:
  806. $filters = mailbox('get', 'filters', $object);
  807. if (!empty($filters)) {
  808. foreach ($filters as $filter) {
  809. if ($details = mailbox('get', 'filter_details', $filter)) {
  810. $data[] = $details;
  811. }
  812. else {
  813. continue;
  814. }
  815. }
  816. }
  817. process_get_return($data);
  818. break;
  819. }
  820. break;
  821. case "bcc":
  822. switch ($object) {
  823. case "all":
  824. $bcc_items = bcc('get');
  825. if (!empty($bcc_items)) {
  826. foreach ($bcc_items as $bcc_item) {
  827. if ($details = bcc('details', $bcc_item)) {
  828. $data[] = $details;
  829. }
  830. else {
  831. continue;
  832. }
  833. }
  834. }
  835. process_get_return($data);
  836. break;
  837. default:
  838. $data = bcc('details', $object);
  839. if (!empty($data)) {
  840. $data[] = $details;
  841. }
  842. process_get_return($data);
  843. break;
  844. }
  845. break;
  846. case "recipient_map":
  847. switch ($object) {
  848. case "all":
  849. $recipient_map_items = recipient_map('get');
  850. if (!empty($recipient_map_items)) {
  851. foreach ($recipient_map_items as $recipient_map_item) {
  852. if ($details = recipient_map('details', $recipient_map_item)) {
  853. $data[] = $details;
  854. }
  855. else {
  856. continue;
  857. }
  858. }
  859. }
  860. process_get_return($data);
  861. break;
  862. default:
  863. $data = recipient_map('details', $object);
  864. if (!empty($data)) {
  865. $data[] = $details;
  866. }
  867. process_get_return($data);
  868. break;
  869. }
  870. break;
  871. case "tls-policy-map":
  872. switch ($object) {
  873. case "all":
  874. $tls_policy_maps_items = tls_policy_maps('get');
  875. if (!empty($tls_policy_maps_items)) {
  876. foreach ($tls_policy_maps_items as $tls_policy_maps_item) {
  877. if ($details = tls_policy_maps('details', $tls_policy_maps_item)) {
  878. $data[] = $details;
  879. }
  880. else {
  881. continue;
  882. }
  883. }
  884. }
  885. process_get_return($data);
  886. break;
  887. default:
  888. $data = tls_policy_maps('details', $object);
  889. if (!empty($data)) {
  890. $data[] = $details;
  891. }
  892. process_get_return($data);
  893. break;
  894. }
  895. break;
  896. case "policy_wl_mailbox":
  897. switch ($object) {
  898. default:
  899. $data = policy('get', 'mailbox', $object)['whitelist'];
  900. process_get_return($data);
  901. break;
  902. }
  903. break;
  904. case "policy_bl_mailbox":
  905. switch ($object) {
  906. default:
  907. $data = policy('get', 'mailbox', $object)['blacklist'];
  908. process_get_return($data);
  909. break;
  910. }
  911. break;
  912. case "policy_wl_domain":
  913. switch ($object) {
  914. default:
  915. $data = policy('get', 'domain', $object)['whitelist'];
  916. process_get_return($data);
  917. break;
  918. }
  919. break;
  920. case "policy_bl_domain":
  921. switch ($object) {
  922. default:
  923. $data = policy('get', 'domain', $object)['blacklist'];
  924. process_get_return($data);
  925. break;
  926. }
  927. break;
  928. case "time_limited_aliases":
  929. switch ($object) {
  930. default:
  931. $data = mailbox('get', 'time_limited_aliases', $object);
  932. process_get_return($data);
  933. break;
  934. }
  935. break;
  936. case "fail2ban":
  937. switch ($object) {
  938. default:
  939. $data = fail2ban('get');
  940. process_get_return($data);
  941. break;
  942. }
  943. break;
  944. case "resource":
  945. switch ($object) {
  946. case "all":
  947. $domains = mailbox('get', 'domains');
  948. if (!empty($domains)) {
  949. foreach ($domains as $domain) {
  950. $resources = mailbox('get', 'resources', $domain);
  951. if (!empty($resources)) {
  952. foreach ($resources as $resource) {
  953. if ($details = mailbox('get', 'resource_details', $resource)) {
  954. $data[] = $details;
  955. }
  956. else {
  957. continue;
  958. }
  959. }
  960. }
  961. }
  962. process_get_return($data);
  963. }
  964. else {
  965. echo '{}';
  966. }
  967. break;
  968. default:
  969. $data = mailbox('get', 'resource_details', $object);
  970. process_get_return($data);
  971. break;
  972. }
  973. break;
  974. case "fwdhost":
  975. switch ($object) {
  976. case "all":
  977. process_get_return(fwdhost('get'));
  978. break;
  979. default:
  980. process_get_return(fwdhost('details', $object));
  981. break;
  982. }
  983. break;
  984. case "quarantine":
  985. // "all" will not print details
  986. switch ($object) {
  987. case "all":
  988. process_get_return(quarantine('get'));
  989. break;
  990. default:
  991. process_get_return(quarantine('details', $object));
  992. break;
  993. }
  994. break;
  995. case "alias-domain":
  996. switch ($object) {
  997. case "all":
  998. $alias_domains = mailbox('get', 'alias_domains');
  999. if (!empty($alias_domains)) {
  1000. foreach ($alias_domains as $alias_domain) {
  1001. if ($details = mailbox('get', 'alias_domain_details', $alias_domain)) {
  1002. $data[] = $details;
  1003. }
  1004. else {
  1005. continue;
  1006. }
  1007. }
  1008. }
  1009. process_get_return($data);
  1010. break;
  1011. default:
  1012. process_get_return(mailbox('get', 'alias_domain_details', $object));
  1013. break;
  1014. }
  1015. break;
  1016. case "alias":
  1017. switch ($object) {
  1018. case "all":
  1019. if (empty($extra)) {
  1020. $domains = array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'));
  1021. }
  1022. else {
  1023. $domains = array($extra);
  1024. }
  1025. if (!empty($domains)) {
  1026. foreach ($domains as $domain) {
  1027. $aliases = mailbox('get', 'aliases', $domain);
  1028. if (!empty($aliases)) {
  1029. foreach ($aliases as $alias) {
  1030. if ($details = mailbox('get', 'alias_details', $alias)) {
  1031. $data[] = $details;
  1032. }
  1033. else {
  1034. continue;
  1035. }
  1036. }
  1037. }
  1038. }
  1039. process_get_return($data);
  1040. }
  1041. else {
  1042. echo '{}';
  1043. }
  1044. break;
  1045. default:
  1046. process_get_return(mailbox('get', 'alias_details', $object));
  1047. break;
  1048. }
  1049. break;
  1050. case "domain-admin":
  1051. switch ($object) {
  1052. case "all":
  1053. $domain_admins = domain_admin('get');
  1054. if (!empty($domain_admins)) {
  1055. foreach ($domain_admins as $domain_admin) {
  1056. if ($details = domain_admin('details', $domain_admin)) {
  1057. $data[] = $details;
  1058. }
  1059. else {
  1060. continue;
  1061. }
  1062. }
  1063. process_get_return($data);
  1064. }
  1065. else {
  1066. echo '{}';
  1067. }
  1068. break;
  1069. default:
  1070. process_get_return(domain_admin('details', $object));
  1071. break;
  1072. }
  1073. break;
  1074. case "admin":
  1075. switch ($object) {
  1076. case "all":
  1077. $admins = admin('get');
  1078. if (!empty($admins)) {
  1079. foreach ($admins as $admin) {
  1080. if ($details = admin('details', $admin)) {
  1081. $data[] = $details;
  1082. }
  1083. else {
  1084. continue;
  1085. }
  1086. }
  1087. process_get_return($data);
  1088. }
  1089. else {
  1090. echo '{}';
  1091. }
  1092. break;
  1093. default:
  1094. process_get_return(admin('details', $object));
  1095. break;
  1096. }
  1097. break;
  1098. case "dkim":
  1099. switch ($object) {
  1100. default:
  1101. $data = dkim('details', $object);
  1102. process_get_return($data);
  1103. break;
  1104. }
  1105. break;
  1106. case "presets":
  1107. switch ($object) {
  1108. case "rspamd":
  1109. process_get_return(presets('get', 'rspamd'));
  1110. break;
  1111. case "sieve":
  1112. process_get_return(presets('get', 'sieve'));
  1113. break;
  1114. }
  1115. break;
  1116. case "status":
  1117. switch ($object) {
  1118. case "containers":
  1119. $containers = (docker('info'));
  1120. foreach ($containers as $container => $container_info) {
  1121. $container . ' (' . $container_info['Config']['Image'] . ')';
  1122. $containerstarttime = ($container_info['State']['StartedAt']);
  1123. $containerstate = ($container_info['State']['Status']);
  1124. $containerimage = ($container_info['Config']['Image']);
  1125. $temp[$container] = array(
  1126. 'type' => 'info',
  1127. 'container' => $container,
  1128. 'state' => $containerstate,
  1129. 'started_at' => $containerstarttime,
  1130. 'image' => $containerimage
  1131. );
  1132. }
  1133. echo json_encode($temp, JSON_UNESCAPED_SLASHES);
  1134. break;
  1135. case "vmail":
  1136. $exec_fields_vmail = array('cmd' => 'system', 'task' => 'df', 'dir' => '/var/vmail');
  1137. $vmail_df = explode(',', json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields_vmail), true));
  1138. $temp = array(
  1139. 'type' => 'info',
  1140. 'disk' => $vmail_df[0],
  1141. 'used' => $vmail_df[2],
  1142. 'total'=> $vmail_df[1],
  1143. 'used_percent' => $vmail_df[4]
  1144. );
  1145. echo json_encode($temp, JSON_UNESCAPED_SLASHES);
  1146. break;
  1147. case "solr":
  1148. $solr_status = solr_status();
  1149. $solr_size = ($solr_status['status']['dovecot-fts']['index']['size']);
  1150. $solr_documents = ($solr_status['status']['dovecot-fts']['index']['numDocs']);
  1151. if (strtolower(getenv('SKIP_SOLR')) != 'n') {
  1152. $solr_enabled = false;
  1153. }
  1154. else {
  1155. $solr_enabled = true;
  1156. }
  1157. echo json_encode(array(
  1158. 'type' => 'info',
  1159. 'solr_enabled' => $solr_enabled,
  1160. 'solr_size' => $solr_size,
  1161. 'solr_documents' => $solr_documents
  1162. ));
  1163. break;
  1164. }
  1165. break;
  1166. break;
  1167. // return no route found if no case is matched
  1168. default:
  1169. http_response_code(404);
  1170. echo json_encode(array(
  1171. 'type' => 'error',
  1172. 'msg' => 'route not found'
  1173. ));
  1174. exit();
  1175. }
  1176. }
  1177. break;
  1178. case "delete":
  1179. if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username'])) {
  1180. http_response_code(403);
  1181. echo json_encode(array(
  1182. 'type' => 'error',
  1183. 'msg' => 'API read/write access denied'
  1184. ));
  1185. exit();
  1186. }
  1187. function process_delete_return($return) {
  1188. $generic_failure = json_encode(array(
  1189. 'type' => 'error',
  1190. 'msg' => 'Cannot delete item'
  1191. ));
  1192. $generic_success = json_encode(array(
  1193. 'type' => 'success',
  1194. 'msg' => 'Task completed'
  1195. ));
  1196. if ($return === false) {
  1197. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
  1198. }
  1199. else {
  1200. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
  1201. }
  1202. }
  1203. if (!isset($_POST['items'])) {
  1204. echo $request_incomplete;
  1205. exit;
  1206. }
  1207. else {
  1208. $items = (array)json_decode($_POST['items'], true);
  1209. }
  1210. // only allow POST requests to POST API endpoints
  1211. if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  1212. http_response_code(405);
  1213. echo json_encode(array(
  1214. 'type' => 'error',
  1215. 'msg' => 'only POST method is allowed'
  1216. ));
  1217. exit();
  1218. }
  1219. switch ($category) {
  1220. case "alias":
  1221. process_delete_return(mailbox('delete', 'alias', array('id' => $items)));
  1222. break;
  1223. case "oauth2-client":
  1224. process_delete_return(oauth2('delete', 'client', array('id' => $items)));
  1225. break;
  1226. case "app-passwd":
  1227. process_delete_return(app_passwd('delete', array('id' => $items)));
  1228. break;
  1229. case "relayhost":
  1230. process_delete_return(relayhost('delete', array('id' => $items)));
  1231. break;
  1232. case "transport":
  1233. process_delete_return(transport('delete', array('id' => $items)));
  1234. break;
  1235. case "rsetting":
  1236. process_delete_return(rsettings('delete', array('id' => $items)));
  1237. break;
  1238. case "syncjob":
  1239. process_delete_return(mailbox('delete', 'syncjob', array('id' => $items)));
  1240. break;
  1241. case "filter":
  1242. process_delete_return(mailbox('delete', 'filter', array('id' => $items)));
  1243. break;
  1244. case "mailq":
  1245. process_delete_return(mailq('delete', array('qid' => $items)));
  1246. break;
  1247. case "qitem":
  1248. process_delete_return(quarantine('delete', array('id' => $items)));
  1249. break;
  1250. case "bcc":
  1251. process_delete_return(bcc('delete', array('id' => $items)));
  1252. break;
  1253. case "recipient_map":
  1254. process_delete_return(recipient_map('delete', array('id' => $items)));
  1255. break;
  1256. case "tls-policy-map":
  1257. process_delete_return(tls_policy_maps('delete', array('id' => $items)));
  1258. break;
  1259. case "fwdhost":
  1260. process_delete_return(fwdhost('delete', array('forwardinghost' => $items)));
  1261. break;
  1262. case "dkim":
  1263. process_delete_return(dkim('delete', array('domains' => $items)));
  1264. break;
  1265. case "domain":
  1266. file_put_contents('/tmp/dssaa', $items);
  1267. process_delete_return(mailbox('delete', 'domain', array('domain' => $items)));
  1268. break;
  1269. case "alias-domain":
  1270. process_delete_return(mailbox('delete', 'alias_domain', array('alias_domain' => $items)));
  1271. break;
  1272. case "mailbox":
  1273. process_delete_return(mailbox('delete', 'mailbox', array('username' => $items)));
  1274. break;
  1275. case "resource":
  1276. process_delete_return(mailbox('delete', 'resource', array('name' => $items)));
  1277. break;
  1278. case "mailbox-policy":
  1279. process_delete_return(policy('delete', 'mailbox', array('prefid' => $items)));
  1280. break;
  1281. case "domain-policy":
  1282. process_delete_return(policy('delete', 'domain', array('prefid' => $items)));
  1283. break;
  1284. case "time_limited_alias":
  1285. process_delete_return(mailbox('delete', 'time_limited_alias', array('address' => $items)));
  1286. break;
  1287. case "eas_cache":
  1288. process_delete_return(mailbox('delete', 'eas_cache', array('username' => $items)));
  1289. break;
  1290. case "sogo_profile":
  1291. process_delete_return(mailbox('delete', 'sogo_profile', array('username' => $items)));
  1292. break;
  1293. case "domain-admin":
  1294. process_delete_return(domain_admin('delete', array('username' => $items)));
  1295. break;
  1296. case "admin":
  1297. process_delete_return(admin('delete', array('username' => $items)));
  1298. break;
  1299. case "rlhash":
  1300. echo ratelimit('delete', null, implode($items));
  1301. break;
  1302. // return no route found if no case is matched
  1303. default:
  1304. http_response_code(404);
  1305. echo json_encode(array(
  1306. 'type' => 'error',
  1307. 'msg' => 'route not found'
  1308. ));
  1309. exit();
  1310. }
  1311. break;
  1312. case "edit":
  1313. if ($_SESSION['mailcow_cc_api_access'] == 'ro' || isset($_SESSION['pending_mailcow_cc_username'])) {
  1314. http_response_code(403);
  1315. echo json_encode(array(
  1316. 'type' => 'error',
  1317. 'msg' => 'API read/write access denied'
  1318. ));
  1319. exit();
  1320. }
  1321. function process_edit_return($return) {
  1322. $generic_failure = json_encode(array(
  1323. 'type' => 'error',
  1324. 'msg' => 'Cannot edit item'
  1325. ));
  1326. $generic_success = json_encode(array(
  1327. 'type' => 'success',
  1328. 'msg' => 'Task completed'
  1329. ));
  1330. if ($return === false) {
  1331. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_failure;
  1332. }
  1333. else {
  1334. echo isset($_SESSION['return']) ? json_encode($_SESSION['return']) : $generic_success;
  1335. }
  1336. }
  1337. if (!isset($_POST['attr'])) {
  1338. echo $request_incomplete;
  1339. exit;
  1340. }
  1341. else {
  1342. $attr = (array)json_decode($_POST['attr'], true);
  1343. unset($attr['csrf_token']);
  1344. $items = isset($_POST['items']) ? (array)json_decode($_POST['items'], true) : null;
  1345. }
  1346. // only allow POST requests to POST API endpoints
  1347. if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  1348. http_response_code(405);
  1349. echo json_encode(array(
  1350. 'type' => 'error',
  1351. 'msg' => 'only POST method is allowed'
  1352. ));
  1353. exit();
  1354. }
  1355. switch ($category) {
  1356. case "bcc":
  1357. process_edit_return(bcc('edit', array_merge(array('id' => $items), $attr)));
  1358. break;
  1359. case "pushover":
  1360. process_edit_return(pushover('edit', array_merge(array('username' => $items), $attr)));
  1361. break;
  1362. case "pushover-test":
  1363. process_edit_return(pushover('test', array_merge(array('username' => $items), $attr)));
  1364. break;
  1365. case "oauth2-client":
  1366. process_edit_return(oauth2('edit', 'client', array_merge(array('id' => $items), $attr)));
  1367. break;
  1368. case "recipient_map":
  1369. process_edit_return(recipient_map('edit', array_merge(array('id' => $items), $attr)));
  1370. break;
  1371. case "app-passwd":
  1372. process_edit_return(app_passwd('edit', array_merge(array('id' => $items), $attr)));
  1373. break;
  1374. case "tls-policy-map":
  1375. process_edit_return(tls_policy_maps('edit', array_merge(array('id' => $items), $attr)));
  1376. break;
  1377. case "alias":
  1378. process_edit_return(mailbox('edit', 'alias', array_merge(array('id' => $items), $attr)));
  1379. break;
  1380. case "rspamd-map":
  1381. process_edit_return(rspamd('edit', array_merge(array('map' => $items), $attr)));
  1382. break;
  1383. case "app_links":
  1384. process_edit_return(customize('edit', 'app_links', $attr));
  1385. break;
  1386. case "relayhost":
  1387. process_edit_return(relayhost('edit', array_merge(array('id' => $items), $attr)));
  1388. break;
  1389. case "transport":
  1390. process_edit_return(transport('edit', array_merge(array('id' => $items), $attr)));
  1391. break;
  1392. case "rsetting":
  1393. process_edit_return(rsettings('edit', array_merge(array('id' => $items), $attr)));
  1394. break;
  1395. case "delimiter_action":
  1396. process_edit_return(mailbox('edit', 'delimiter_action', array_merge(array('username' => $items), $attr)));
  1397. break;
  1398. case "tls_policy":
  1399. process_edit_return(mailbox('edit', 'tls_policy', array_merge(array('username' => $items), $attr)));
  1400. break;
  1401. case "quarantine_notification":
  1402. process_edit_return(mailbox('edit', 'quarantine_notification', array_merge(array('username' => $items), $attr)));
  1403. break;
  1404. case "qitem":
  1405. process_edit_return(quarantine('edit', array_merge(array('id' => $items), $attr)));
  1406. break;
  1407. case "quarantine":
  1408. process_edit_return(quarantine('edit', $attr));
  1409. break;
  1410. case "quota_notification":
  1411. process_edit_return(quota_notification('edit', $attr));
  1412. break;
  1413. case "mailq":
  1414. process_edit_return(mailq('edit', array_merge(array('qid' => $items), $attr)));
  1415. break;
  1416. case "time_limited_alias":
  1417. process_edit_return(mailbox('edit', 'time_limited_alias', array_merge(array('address' => $items), $attr)));
  1418. break;
  1419. case "mailbox":
  1420. process_edit_return(mailbox('edit', 'mailbox', array_merge(array('username' => $items), $attr)));
  1421. break;
  1422. case "syncjob":
  1423. process_edit_return(mailbox('edit', 'syncjob', array_merge(array('id' => $items), $attr)));
  1424. break;
  1425. case "filter":
  1426. process_edit_return(mailbox('edit', 'filter', array_merge(array('id' => $items), $attr)));
  1427. break;
  1428. case "resource":
  1429. process_edit_return(mailbox('edit', 'resource', array_merge(array('name' => $items), $attr)));
  1430. break;
  1431. case "domain":
  1432. process_edit_return(mailbox('edit', 'domain', array_merge(array('domain' => $items), $attr)));
  1433. break;
  1434. case "rl-domain":
  1435. process_edit_return(ratelimit('edit', 'domain', array_merge(array('object' => $items), $attr)));
  1436. break;
  1437. case "rl-mbox":
  1438. process_edit_return(ratelimit('edit', 'mailbox', array_merge(array('object' => $items), $attr)));
  1439. break;
  1440. case "user-acl":
  1441. process_edit_return(acl('edit', 'user', array_merge(array('username' => $items), $attr)));
  1442. break;
  1443. case "da-acl":
  1444. process_edit_return(acl('edit', 'domainadmin', array_merge(array('username' => $items), $attr)));
  1445. break;
  1446. case "alias-domain":
  1447. process_edit_return(mailbox('edit', 'alias_domain', array_merge(array('alias_domain' => $items), $attr)));
  1448. break;
  1449. case "spam-score":
  1450. process_edit_return(mailbox('edit', 'spam_score', array_merge(array('username' => $items), $attr)));
  1451. break;
  1452. case "domain-admin":
  1453. process_edit_return(domain_admin('edit', array_merge(array('username' => $items), $attr)));
  1454. break;
  1455. case "admin":
  1456. process_edit_return(admin('edit', array_merge(array('username' => $items), $attr)));
  1457. break;
  1458. case "fwdhost":
  1459. process_edit_return(fwdhost('edit', array_merge(array('fwdhost' => $items), $attr)));
  1460. break;
  1461. case "fail2ban":
  1462. process_edit_return(fail2ban('edit', array_merge(array('network' => $items), $attr)));
  1463. break;
  1464. case "ui_texts":
  1465. process_edit_return(customize('edit', 'ui_texts', $attr));
  1466. break;
  1467. case "self":
  1468. if ($_SESSION['mailcow_cc_role'] == "domainadmin") {
  1469. process_edit_return(domain_admin('edit', $attr));
  1470. }
  1471. elseif ($_SESSION['mailcow_cc_role'] == "user") {
  1472. process_edit_return(edit_user_account($attr));
  1473. }
  1474. break;
  1475. // return no route found if no case is matched
  1476. default:
  1477. http_response_code(404);
  1478. echo json_encode(array(
  1479. 'type' => 'error',
  1480. 'msg' => 'route not found'
  1481. ));
  1482. exit();
  1483. }
  1484. break;
  1485. // return no route found if no case is matched
  1486. default:
  1487. http_response_code(404);
  1488. echo json_encode(array(
  1489. 'type' => 'error',
  1490. 'msg' => 'route not found'
  1491. ));
  1492. exit();
  1493. }
  1494. }
  1495. if ($_SESSION['mailcow_cc_api'] === true) {
  1496. if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) {
  1497. unset($_SESSION['return']);
  1498. }
  1499. }
  1500. }