frontend.template.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. /*
  3. input:
  4. User $user - User object
  5. array $config - config array
  6. array $emails - array of emails
  7. */
  8. require_once './autolink.php';
  9. // Load HTML Purifier
  10. $purifier_config = HTMLPurifier_Config::createDefault();
  11. $purifier_config->set('HTML.Nofollow', true);
  12. $purifier_config->set('HTML.ForbiddenElements', array("img"));
  13. $purifier = new HTMLPurifier($purifier_config);
  14. \Moment\Moment::setLocale($config['locale']);
  15. $mailIds = array_map(function ($mail) {
  16. return $mail->id;
  17. }, $emails);
  18. $mailIdsJoinedString = filter_var(join('|', $mailIds), FILTER_SANITIZE_SPECIAL_CHARS);
  19. // define bigger renderings here to keep the php sections within the html short.
  20. function niceDate($date) {
  21. $m = new \Moment\Moment($date, date_default_timezone_get());
  22. return $m->calendar();
  23. }
  24. function printMessageBody($email, $purifier) {
  25. global $config;
  26. // To avoid showing empty mails, first purify the html and plaintext
  27. // before checking if they are empty.
  28. $safeHtml = $purifier->purify($email->textHtml);
  29. $safeText = htmlspecialchars($email->textPlain);
  30. $safeText = nl2br($safeText);
  31. $safeText = \AutoLinkExtension::auto_link_text($safeText);
  32. $hasHtml = strlen(trim($safeHtml)) > 0;
  33. $hasText = strlen(trim($safeText)) > 0;
  34. if ($config['prefer_plaintext']) {
  35. if ($hasText) {
  36. echo $safeText;
  37. } else {
  38. echo $safeHtml;
  39. }
  40. } else {
  41. if ($hasHtml) {
  42. echo $safeHtml;
  43. } else {
  44. echo $safeText;
  45. }
  46. }
  47. }
  48. ?>
  49. <!doctype html>
  50. <html lang="en">
  51. <head>
  52. <meta charset="utf-8">
  53. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  54. <!-- Bootstrap CSS -->
  55. <link rel="stylesheet" href="assets/bootstrap/4.1.1/bootstrap.min.css"
  56. integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
  57. crossorigin="anonymous">
  58. <link rel="stylesheet" href="assets/fontawesome/v5.0.13/all.css"
  59. integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp"
  60. crossorigin="anonymous">
  61. <title><?php
  62. echo $emails ? "(" . count($emails) . ") " : "";
  63. echo $user->address ?></title>
  64. <link rel="stylesheet" href="assets/spinner.css">
  65. <link rel="stylesheet" href="assets/custom.css">
  66. <script>
  67. var mailCount = <?php echo count($emails)?>;
  68. setInterval(function () {
  69. var r = new XMLHttpRequest();
  70. r.open("GET", "?action=has_new_messages&address=<?php echo $user->address?>&email_ids=<?php echo $mailIdsJoinedString?>", true);
  71. r.onreadystatechange = function () {
  72. if (r.readyState != 4 || r.status != 200) return;
  73. if (r.responseText > 0) {
  74. console.log("There are", r.responseText, "new mails.");
  75. document.getElementById("new-content-avalable").style.display = 'block';
  76. // If there are no emails displayed, we can reload the page without losing any state.
  77. if (mailCount === 0) {
  78. location.reload();
  79. }
  80. }
  81. };
  82. r.send();
  83. }, 15000);
  84. </script>
  85. </head>
  86. <body>
  87. <div id="new-content-avalable">
  88. <div class="alert alert-info alert-fixed" role="alert">
  89. <strong>New emails</strong> have arrived.
  90. <button type="button" class="btn btn-outline-secondary" onclick="location.reload()">
  91. <i class="fas fa-sync"></i>
  92. Reload!
  93. </button>
  94. </div>
  95. <!-- move the rest of the page a bit down to show all content -->
  96. <div style="height: 3rem">&nbsp;</div>
  97. </div>
  98. <header>
  99. <div class="container">
  100. <p class="lead ">
  101. Your disposable mailbox is ready.
  102. </p>
  103. <div class="row" id="address-box-normal">
  104. <div class="col my-address-block">
  105. <span id="my-address"><?php echo $user->address ?></span>&nbsp;<button class="copy-button" data-clipboard-target="#my-address">Copy</button>
  106. </div>
  107. <div class="col get-new-address-col">
  108. <button type="button" class="btn btn-outline-dark"
  109. data-toggle="collapse" title="choose your own address"
  110. data-target=".change-address-toggle"
  111. aria-controls="address-box-normal address-box-edit" aria-expanded="false">
  112. <i class="fas fa-magic"></i> Change address
  113. </button>
  114. </div>
  115. </div>
  116. <form class="collapse change-address-toggle" id="address-box-edit" action="?action=redirect" method="post">
  117. <div class="card">
  118. <div class="card-body">
  119. <p>
  120. <a href="?action=random" role="button" class="btn btn-dark">
  121. <i class="fa fa-random"></i>
  122. Open random mailbox
  123. </a>
  124. </p>
  125. or create your own address:
  126. <div class="form-row align-items-center">
  127. <div class="col-sm">
  128. <label class="sr-only" for="inlineFormInputName">username</label>
  129. <input name="username" type="text" class="form-control" id="inlineFormInputName"
  130. placeholder="username"
  131. value="<?php echo $user->username ?>">
  132. </div>
  133. <div class="col-sm-auto my-1">
  134. <label class="sr-only" for="inlineFormInputGroupUsername">Domain</label>
  135. <div class="input-group">
  136. <div class="input-group-prepend">
  137. <div class="input-group-text">@</div>
  138. </div>
  139. <select class="custom-select" id="inlineFormInputGroupUsername" name="domain">
  140. <?php
  141. foreach ($config['domains'] as $aDomain) {
  142. $selected = $aDomain === $user->domain ? ' selected ' : '';
  143. print "<option value='$aDomain' $selected>$aDomain</option>";
  144. }
  145. ?>
  146. </select>
  147. </div>
  148. </div>
  149. <div class="col-auto my-1">
  150. <button type="submit" class="btn btn-primary">Open mailbox</button>
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. </form>
  156. </div>
  157. </header>
  158. <main>
  159. <div class="container">
  160. <div id="email-list" class="list-group">
  161. <?php
  162. foreach ($emails as $email) {
  163. $safe_email_id = filter_var($email->id, FILTER_VALIDATE_INT); ?>
  164. <a class="list-group-item list-group-item-action email-list-item" data-toggle="collapse"
  165. href="#mail-box-<?php echo $email->id ?>"
  166. role="button"
  167. aria-expanded="false" aria-controls="mail-box-<?php echo $email->id ?>">
  168. <div class="media">
  169. <button class="btn btn-white open-collapse-button">
  170. <i class="fas fa-caret-right expand-button-closed"></i>
  171. <i class="fas fa-caret-down expand-button-opened"></i>
  172. </button>
  173. <div class="media-body">
  174. <h6 class="list-group-item-heading"><?php echo filter_var($email->fromName, FILTER_SANITIZE_SPECIAL_CHARS) ?>
  175. <span class="text-muted"><?php echo filter_var($email->fromAddress, FILTER_SANITIZE_SPECIAL_CHARS) ?></span>
  176. <small class="float-right"
  177. title="<?php echo $email->date ?>"><?php echo niceDate($email->date) ?></small>
  178. </h6>
  179. <p class="list-group-item-text text-truncate" style="width: 75%">
  180. <?php echo filter_var($email->subject, FILTER_SANITIZE_SPECIAL_CHARS); ?>
  181. </p>
  182. </div>
  183. </div>
  184. </a>
  185. <div id="mail-box-<?php echo $email->id ?>" role="tabpanel" aria-labelledby="headingCollapse1"
  186. class="card-collapse collapse"
  187. aria-expanded="true">
  188. <div class="card-body">
  189. <div class="card-block email-body">
  190. <div class="float-right primary">
  191. <a class="btn btn-outline-primary btn-sm" download="true"
  192. role="button"
  193. href="<?php echo "?action=download_email&email_id=$safe_email_id&address=$user->address" ?>">
  194. Download
  195. </a>
  196. <a class="btn btn-outline-danger btn-sm"
  197. role="button"
  198. href="<?php echo "?action=delete_email&email_id=$safe_email_id&address=$user->address" ?>">
  199. Delete
  200. </a>
  201. </div>
  202. <?php printMessageBody($email, $purifier); ?>
  203. </div>
  204. </div>
  205. </div>
  206. <?php
  207. } ?>
  208. <?php
  209. if (empty($emails)) {
  210. ?>
  211. <div id="empty-mailbox">
  212. <p>The mailbox is empty. Checking for new emails automatically. </p>
  213. <div class="spinner">
  214. <div class="rect1"></div>
  215. <div class="rect2"></div>
  216. <div class="rect3"></div>
  217. <div class="rect4"></div>
  218. <div class="rect5"></div>
  219. </div>
  220. </div>
  221. <?php
  222. } ?>
  223. </div>
  224. </div>
  225. </main>
  226. <footer>
  227. <div class="container">
  228. <!-- <select id="language-selection" class="custom-select" title="Language">-->
  229. <!-- <option selected>English</option>-->
  230. <!-- <option value="1">Deutsch</option>-->
  231. <!-- <option value="2">Two</option>-->
  232. <!-- <option value="3">Three</option>-->
  233. <!-- </select>-->
  234. <!-- <br>-->
  235. <small class="text-justify quick-summary">
  236. This is a disposable mailbox service. Whoever knows your username, can read your emails.
  237. Emails will be deleted after 30 days.
  238. <a data-toggle="collapse" href="#about"
  239. aria-expanded="false"
  240. aria-controls="about">
  241. Show Details
  242. </a>
  243. </small>
  244. <div class="card card-body collapse" id="about" style="max-width: 40rem">
  245. <p class="text-justify">This disposable mailbox keeps your main mailbox clean from spam.</p>
  246. <p class="text-justify">Just choose an address and use it on websites you don't trust and
  247. don't
  248. want to use
  249. your
  250. main email address.
  251. Once you are done, you can just forget about the mailbox. All the spam stays here and does
  252. not
  253. fill up
  254. your
  255. main mailbox.
  256. </p>
  257. <p class="text-justify">
  258. You select the address you want to use and received emails will be displayed
  259. automatically.
  260. There is no registration and no passwords. If you know the address, you can read the
  261. emails.
  262. <strong>Basically, all emails are public. So don't use it for sensitive data.</strong>
  263. </p>
  264. </div>
  265. <p>
  266. <small>Powered by
  267. <a href="https://notabug.org/nipos/disposable-mailbox"><strong>nipos/disposable-mailbox</strong></a>
  268. </small>
  269. </p>
  270. </div>
  271. </footer>
  272. <!-- jQuery first, then Popper.js, then Bootstrap JS -->
  273. <script src="assets/jquery/jquery-3.3.1.slim.min.js"
  274. integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
  275. crossorigin="anonymous"></script>
  276. <script src="assets/popper.js/1.14.3/umd/popper.min.js"
  277. integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
  278. crossorigin="anonymous"></script>
  279. <script src="assets/bootstrap/4.1.1/bootstrap.min.js"
  280. integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T"
  281. crossorigin="anonymous"></script>
  282. <script src="assets/clipboard.js/clipboard.min.js"
  283. integrity="sha384-8CYhPwYlLELodlcQV713V9ZikA3DlCVaXFDpjHfP8Z36gpddf/Vrt47XmKDsCttu"
  284. crossorigin="anonymous"></script>
  285. <script>
  286. clipboard = new ClipboardJS('[data-clipboard-target]');
  287. $(function () {
  288. $('[data-tooltip="tooltip"]').tooltip()
  289. });
  290. /** from https://github.com/twbs/bootstrap/blob/c11132351e3e434f6d4ed72e5a418eb692c6a319/assets/js/src/application.js */
  291. clipboard.on('success', function (e) {
  292. $(e.trigger)
  293. .attr('title', 'Copied!')
  294. .tooltip('_fixTitle')
  295. .tooltip('show')
  296. .tooltip('_fixTitle');
  297. e.clearSelection();
  298. });
  299. </script>
  300. </body>
  301. </html>