mailbox.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <?php
  2. require_once "inc/prerequisites.inc.php";
  3. if ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin") {
  4. require_once "inc/header.inc.php";
  5. $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
  6. ?>
  7. <div class="container">
  8. <div class="row">
  9. <div class="col-md-12">
  10. <div class="panel panel-default">
  11. <div class="panel-heading">
  12. <h3 class="panel-title"><?=$lang['mailbox']['domains'];?> <span class="badge" id="numRowsDomain"></span></h3>
  13. <div class="pull-right">
  14. <span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
  15. <i class="glyphicon glyphicon-filter"></i>
  16. </span>
  17. <?php
  18. if ($_SESSION['mailcow_cc_role'] == "admin"):
  19. ?>
  20. <a href="/add.php?domain"><span class="glyphicon glyphicon-plus"></span></a>
  21. <?php
  22. endif;
  23. ?>
  24. </div>
  25. </div>
  26. <div class="panel-body">
  27. <input type="text" class="form-control" id="domaintable-filter" data-action="filter" data-filters="#domaintable" placeholder="Filter" />
  28. </div>
  29. <div class="table-responsive">
  30. <table class="table table-striped sortable-theme-bootstrap" data-sortable id="domaintable">
  31. <thead>
  32. <tr>
  33. <th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
  34. <th class="sort-table" style="min-width: 81px;"><?=$lang['mailbox']['aliases'];?></th>
  35. <th class="sort-table" style="min-width: 99px;"><?=$lang['mailbox']['mailboxes'];?></th>
  36. <th class="sort-table" style="min-width: 172px;"><?=$lang['mailbox']['mailbox_quota'];?></th>
  37. <th class="sort-table" style="min-width: 117px;"><?=$lang['mailbox']['domain_quota'];?></th>
  38. <?php
  39. if ($_SESSION['mailcow_cc_role'] == "admin"):
  40. ?>
  41. <th class="sort-table" style="min-width: 105px;"><?=$lang['mailbox']['backup_mx'];?></th>
  42. <?php
  43. endif;
  44. ?>
  45. <th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
  46. <th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
  47. </tr>
  48. </thead>
  49. <tbody>
  50. <?php
  51. try {
  52. $stmt = $pdo->prepare("SELECT
  53. `domain`,
  54. `aliases`,
  55. `mailboxes`,
  56. `maxquota` * 1048576 AS `maxquota`,
  57. `quota` * 1048576 AS `quota`,
  58. CASE `backupmx` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `backupmx`,
  59. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  60. FROM `domain` WHERE
  61. `domain` IN (
  62. SELECT `domain` FROM `domain_admins` WHERE `username`= :username AND `active`='1'
  63. )
  64. OR 'admin'= :admin");
  65. $stmt->execute(array(
  66. ':username' => $_SESSION['mailcow_cc_username'],
  67. ':admin' => $_SESSION['mailcow_cc_role'],
  68. ));
  69. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  70. }
  71. catch (PDOException $e) {
  72. $_SESSION['return'] = array(
  73. 'type' => 'danger',
  74. 'msg' => 'MySQL: '.$e
  75. );
  76. return false;
  77. }
  78. if(!empty($rows)):
  79. while($row = array_shift($rows)):
  80. try {
  81. $stmt = $pdo->prepare("SELECT COUNT(*) AS `count` FROM `alias`
  82. WHERE `domain`= :domain
  83. AND `address` NOT IN (
  84. SELECT `username` FROM `mailbox`)");
  85. $stmt->execute(array(':domain' => $row['domain']));
  86. $AliasData = $stmt->fetch(PDO::FETCH_ASSOC);
  87. $stmt = $pdo->prepare("SELECT
  88. COUNT(*) AS `count`,
  89. COALESCE(SUM(`quota`), '0') AS `quota`
  90. FROM `mailbox`
  91. WHERE `domain` = :domain");
  92. $stmt->execute(array(':domain' => $row['domain']));
  93. $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC);
  94. }
  95. catch (PDOException $e) {
  96. $_SESSION['return'] = array(
  97. 'type' => 'danger',
  98. 'msg' => 'MySQL: '.$e
  99. );
  100. return false;
  101. }
  102. ?>
  103. <tr id="data">
  104. <td><?=htmlspecialchars($row['domain']);?></td>
  105. <td><?=intval($AliasData['count']);?> / <?=intval($row['aliases']);?></td>
  106. <td><?=$MailboxData['count'];?> / <?=$row['mailboxes'];?></td>
  107. <td><?=formatBytes(intval($row['maxquota']), 2);?></td>
  108. <td><?=formatBytes(intval($MailboxData['quota']), 2);?> / <?=formatBytes(intval($row['quota']));?></td>
  109. <?php
  110. if ($_SESSION['mailcow_cc_role'] == "admin"):
  111. ?>
  112. <td><?=$row['backupmx'];?></td>
  113. <?php
  114. endif;
  115. ?>
  116. <td><?=$row['active'];?></td>
  117. <?php
  118. if ($_SESSION['mailcow_cc_role'] == "admin"):
  119. ?>
  120. <td style="text-align: right;">
  121. <div class="btn-group">
  122. <a href="/edit.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
  123. <a href="/delete.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
  124. </div>
  125. </td>
  126. <?php
  127. else:
  128. ?>
  129. <td style="text-align: right;">
  130. <div class="btn-group">
  131. <a href="/edit.php?domain=<?=urlencode($row['domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
  132. </div>
  133. </td>
  134. </tr>
  135. <?php
  136. endif;
  137. endwhile;
  138. else:
  139. ?>
  140. <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
  141. <?php
  142. endif;
  143. ?>
  144. </tbody>
  145. <?php
  146. if ($_SESSION['mailcow_cc_role'] == "admin"):
  147. ?>
  148. <tfoot>
  149. <tr id="no-data">
  150. <td colspan="8" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
  151. <a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a>
  152. </td>
  153. </tr>
  154. </tfoot>
  155. <?php
  156. endif;
  157. ?>
  158. </table>
  159. </div>
  160. </div>
  161. </div>
  162. </div>
  163. <div class="row">
  164. <div class="col-md-12">
  165. <div class="panel panel-default">
  166. <div class="panel-heading">
  167. <h3 class="panel-title"><?=$lang['mailbox']['domain_aliases'];?> <span class="badge" id="numRowsDomainAlias"></span></h3>
  168. <div class="pull-right">
  169. <span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
  170. <i class="glyphicon glyphicon-filter"></i>
  171. </span>
  172. <a href="/add.php?aliasdomain"><span class="glyphicon glyphicon-plus"></span></a>
  173. </div>
  174. </div>
  175. <div class="panel-body">
  176. <input type="text" class="form-control" id="domainaliastable-filter" data-action="filter" data-filters="#domainaliastable" placeholder="Filter" />
  177. </div>
  178. <div class="table-responsive">
  179. <table class="table table-striped sortable-theme-bootstrap" data-sortable id="domainaliastable">
  180. <thead>
  181. <tr>
  182. <th class="sort-table" style="min-width: 67px;"><?=$lang['mailbox']['alias'];?></th>
  183. <th class="sort-table" style="min-width: 127px;"><?=$lang['mailbox']['target_domain'];?></th>
  184. <th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
  185. <th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
  186. </tr>
  187. </thead>
  188. <tbody>
  189. <?php
  190. try {
  191. $stmt = $pdo->prepare("SELECT
  192. `alias_domain`,
  193. `target_domain`,
  194. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  195. FROM `alias_domain`
  196. WHERE `target_domain` IN (
  197. SELECT `domain` FROM `domain_admins`
  198. WHERE `username`= :username
  199. AND `active`='1'
  200. )
  201. OR 'admin' = :admin");
  202. $stmt->execute(array(
  203. ':username' => $_SESSION['mailcow_cc_username'],
  204. ':admin' => $_SESSION['mailcow_cc_role'],
  205. ));
  206. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  207. } catch(PDOException $e) {
  208. $_SESSION['return'] = array(
  209. 'type' => 'danger',
  210. 'msg' => 'MySQL: '.$e
  211. );
  212. }
  213. if(!empty($rows)):
  214. while($row = array_shift($rows)):
  215. ?>
  216. <tr id="data">
  217. <td><?=htmlspecialchars($row['alias_domain']);?></td>
  218. <td><?=htmlspecialchars($row['target_domain']);?></td>
  219. <td><?=$row['active'];?></td>
  220. <td style="text-align: right;">
  221. <div class="btn-group">
  222. <a href="/edit.php?aliasdomain=<?=urlencode($row['alias_domain']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
  223. <a href="/delete.php?aliasdomain=<?=urlencode($row['alias_domain']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
  224. </div>
  225. </td>
  226. </tr>
  227. <?php
  228. endwhile;
  229. else:
  230. ?>
  231. <tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
  232. <?php
  233. endif;
  234. ?>
  235. </tbody>
  236. <tfoot>
  237. <tr id="no-data">
  238. <td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
  239. <a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a>
  240. </td>
  241. </tr>
  242. </tfoot>
  243. </table>
  244. </div>
  245. </div>
  246. </div>
  247. </div>
  248. <div class="row">
  249. <div class="col-md-12">
  250. <div class="panel panel-default">
  251. <div class="panel-heading">
  252. <h3 class="panel-title"><?=$lang['mailbox']['mailboxes'];?> <span class="badge" id="numRowsMailbox"></span></h3>
  253. <div class="pull-right">
  254. <span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
  255. <i class="glyphicon glyphicon-filter"></i>
  256. </span>
  257. <a href="/add.php?mailbox"><span class="glyphicon glyphicon-plus"></span></a>
  258. </div>
  259. </div>
  260. <div class="panel-body">
  261. <input type="text" class="form-control" id="mailboxtable-filter" data-action="filter" data-filters="#mailboxtable" placeholder="Filter" />
  262. </div>
  263. <div class="table-responsive">
  264. <table class="table table-striped sortable-theme-bootstrap" data-sortable id="mailboxtable">
  265. <thead>
  266. <tr>
  267. <th class="sort-table" style="min-width: 100px;"><?=$lang['mailbox']['username'];?></th>
  268. <th class="sort-table" style="min-width: 98px;"><?=$lang['mailbox']['fname'];?></th>
  269. <th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
  270. <th class="sort-table" style="min-width: 75px;"><?=$lang['mailbox']['quota'];?></th>
  271. <th class="sort-table" style="min-width: 99px;"><?=$lang['mailbox']['in_use'];?></th>
  272. <th class="sort-table" style="min-width: 100px;"><?=$lang['mailbox']['msg_num'];?></th>
  273. <th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
  274. <th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
  275. </tr>
  276. </thead>
  277. <tbody>
  278. <?php
  279. try {
  280. $stmt = $pdo->prepare("SELECT
  281. `domain`.`backupmx`,
  282. `mailbox`.`username`,
  283. `mailbox`.`name`,
  284. CASE `mailbox`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`,
  285. `mailbox`.`domain`,
  286. `mailbox`.`quota`,
  287. `quota2`.`bytes`,
  288. `quota2`.`messages`
  289. FROM `mailbox`, `quota2`, `domain`
  290. WHERE (`mailbox`.`username` = `quota2`.`username`)
  291. AND (`domain`.`domain` = `mailbox`.`domain`)
  292. AND (`mailbox`.`domain` IN (
  293. SELECT `domain` FROM `domain_admins`
  294. WHERE `username`= :username
  295. AND `active`='1'
  296. )
  297. OR 'admin' = :admin)");
  298. $stmt->execute(array(
  299. ':username' => $_SESSION['mailcow_cc_username'],
  300. ':admin' => $_SESSION['mailcow_cc_role'],
  301. ));
  302. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  303. }
  304. catch (PDOException $e) {
  305. $_SESSION['return'] = array(
  306. 'type' => 'danger',
  307. 'msg' => 'MySQL: '.$e
  308. );
  309. return false;
  310. }
  311. if(!empty($rows)):
  312. while($row = array_shift($rows)):
  313. ?>
  314. <tr id="data">
  315. <?php
  316. if ($row['backupmx'] == "0"):
  317. ?>
  318. <td><?=htmlspecialchars($row['username']);?></td>
  319. <?php
  320. else:
  321. ?>
  322. <td><span data-toggle="tooltip" title="Relayed"><i class="glyphicon glyphicon-forward"></i> <?=htmlspecialchars($row['username']);?></span></td>
  323. <?php
  324. endif;
  325. ?>
  326. <td><?=htmlspecialchars($row['name'], ENT_QUOTES, 'UTF-8');?></td>
  327. <td><?=htmlspecialchars($row['domain']);?></td>
  328. <td><?=formatBytes(intval($row['bytes']), 2);?> / <?=formatBytes(intval($row['quota']), 2);?></td>
  329. <td style="min-width:120px;">
  330. <?php
  331. $percentInUse = round((intval($row['bytes']) / intval($row['quota'])) * 100);
  332. if ($percentInUse >= 90) {
  333. $pbar = "progress-bar-danger";
  334. }
  335. elseif ($percentInUse >= 75) {
  336. $pbar = "progress-bar-warning";
  337. }
  338. else {
  339. $pbar = "progress-bar-success";
  340. }
  341. ?>
  342. <div class="progress">
  343. <div class="progress-bar <?=$pbar;?>" role="progressbar" aria-valuenow="<?=$percentInUse;?>" aria-valuemin="0" aria-valuemax="100" style="min-width:2em;width: <?=$percentInUse;?>%;">
  344. <?=$percentInUse;?>%
  345. </div>
  346. </div>
  347. </td>
  348. <td><?=$row['messages'];?></td>
  349. <td><?=$row['active'];?></td>
  350. <td style="text-align: right;">
  351. <div class="btn-group">
  352. <a href="/edit.php?mailbox=<?=urlencode($row['username']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
  353. <a href="/delete.php?mailbox=<?=urlencode($row['username']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
  354. </div>
  355. </td>
  356. </tr>
  357. <?php
  358. endwhile;
  359. else:
  360. ?>
  361. <tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
  362. <?php
  363. endif;
  364. ?>
  365. </tbody>
  366. <tfoot>
  367. <tr id="no-data">
  368. <td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
  369. <a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a>
  370. </td>
  371. </tr>
  372. </tfoot>
  373. </table>
  374. </div>
  375. </div>
  376. </div>
  377. </div>
  378. <div class="row">
  379. <div class="col-md-12">
  380. <div class="panel panel-default">
  381. <div class="panel-heading">
  382. <h3 class="panel-title"><?=$lang['mailbox']['aliases'];?> <span class="badge" id="numRowsAlias"></span></h3>
  383. <div class="pull-right">
  384. <span class="clickable filter" data-toggle="tooltip" title="<?=$lang['mailbox']['filter_table'];?>" data-container="body">
  385. <i class="glyphicon glyphicon-filter"></i>
  386. </span>
  387. <a href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
  388. </div>
  389. </div>
  390. <div class="panel-body">
  391. <input type="text" class="form-control" id="aliastable-filter" data-action="filter" data-filters="#aliastable" placeholder="Filter" />
  392. </div>
  393. <div class="table-responsive">
  394. <table class="table table-striped sortable-theme-bootstrap" data-sortable id="aliastable">
  395. <thead>
  396. <tr>
  397. <th class="sort-table" style="min-width: 67px;"><?=$lang['mailbox']['alias'];?></th>
  398. <th class="sort-table" style="min-width: 119px;"><?=$lang['mailbox']['target_address'];?></th>
  399. <th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
  400. <th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
  401. <th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['mailbox']['action'];?></th>
  402. </tr>
  403. </thead>
  404. <tbody>
  405. <?php
  406. try {
  407. $stmt = $pdo->prepare("SELECT
  408. `address`,
  409. `goto`,
  410. `domain`,
  411. CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
  412. FROM alias
  413. WHERE (
  414. `address` NOT IN (
  415. SELECT `username` FROM `mailbox`
  416. )
  417. AND `address` != `goto`
  418. ) AND (`domain` IN (
  419. SELECT `domain` FROM `domain_admins`
  420. WHERE `username` = :username
  421. AND active='1'
  422. )
  423. OR 'admin' = :admin)");
  424. $stmt->execute(array(
  425. ':username' => $_SESSION['mailcow_cc_username'],
  426. ':admin' => $_SESSION['mailcow_cc_role'],
  427. ));
  428. $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
  429. }
  430. catch (PDOException $e) {
  431. $_SESSION['return'] = array(
  432. 'type' => 'danger',
  433. 'msg' => 'MySQL: '.$e
  434. );
  435. return false;
  436. }
  437. if(!empty($rows)):
  438. while($row = array_shift($rows)):
  439. ?>
  440. <tr id="data">
  441. <td>
  442. <?php
  443. if(!filter_var($row['address'], FILTER_VALIDATE_EMAIL)):
  444. ?>
  445. <span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span> Catch-all @<?=htmlspecialchars($row['domain']);?>
  446. <?php
  447. else:
  448. echo htmlspecialchars($row['address']);
  449. endif;
  450. ?>
  451. </td>
  452. <td>
  453. <?php
  454. foreach(explode(",", $row['goto']) as $goto) {
  455. echo nl2br(htmlspecialchars($goto.PHP_EOL));
  456. }
  457. ?>
  458. </td>
  459. <td><?=htmlspecialchars($row['domain']);?></td>
  460. <td><?=$row['active'];?></td>
  461. <td style="text-align: right;">
  462. <div class="btn-group">
  463. <a href="/edit.php?alias=<?=urlencode($row['address']);?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> <?=$lang['mailbox']['edit'];?></a>
  464. <a href="/delete.php?alias=<?=urlencode($row['address']);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['mailbox']['remove'];?></a>
  465. </div>
  466. </td>
  467. </tr>
  468. <?php
  469. endwhile;
  470. else:
  471. ?>
  472. <tr id="no-data"><td colspan="5" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record'];?></td></tr>
  473. <?php
  474. endif;
  475. ?>
  476. </tbody>
  477. <tfoot>
  478. <tr id="no-data">
  479. <td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
  480. <a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a>
  481. </td>
  482. </tr>
  483. </tfoot>
  484. </table>
  485. </div>
  486. </div>
  487. </div>
  488. </div>
  489. </div> <!-- /container -->
  490. <script src="js/sorttable.js"></script>
  491. <script src="js/mailbox.js"></script>
  492. <?php
  493. require_once("inc/footer.inc.php");
  494. } else {
  495. header('Location: /');
  496. exit();
  497. }
  498. ?>