1$(document).ready(function() { 2 3 "use strict"; 4 5 new ClipboardJS('.btn-copy'); 6 7 8 9 $(".btn-copy").on("click", function() { 10 11 let copyIcon = document.querySelector("#copyIcon"); 12 let inputField = document.querySelector("#mainEmail"); 13 14 if (inputField) { 15 // Focus and select the input field 16 inputField.focus(); 17 inputField.select(); 18 } 19 20 if (copyIcon) { 21 copyIcon.classList.remove("far", "fa-clone"); 22 copyIcon.classList.add("fas", "fa-check"); 23 24 setTimeout(function() { 25 copyIcon.classList.remove("fas", "fa-check"); 26 copyIcon.classList.add("far", "fa-clone"); 27 }, 500); 28 } 29 }); 30 31 AOS.init({disable: 'mobile'}); 32 33 var email = $("#mainEmail"), 34 email_token = $("#email_token"), 35 history_total = 0, 36 _token = $('meta[name="csrf-token"]').attr('content'); 37 window.data = localStorage.getItem('emails'); 38 window.myLanding; 39 window.stop = false; 40 window.check_is_runing = false; 41 42 const rootStyles = getComputedStyle(document.documentElement); 43 const secondaryColor = rootStyles.getPropertyValue('--secondary_color').trim(); 44 45 window.transferCompletedAudio = new Audio(BASE_PATH + "assets/audio/notification.mp3"); 46 47 48 $("#refresh").on("click", function(e) { 49 e.preventDefault(); // Prevent the default link behavior 50 location.reload(); // Reload the page 51 }); 52 53 const iframe = document.getElementById('myContent'); 54 55 if (iframe) { 56 iframe.addEventListener('load', function() { 57 // Function to set iframe height to match its content height 58 function setIframeHeight() { 59 const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; 60 if (iframeDocument && iframeDocument.body) { 61 // Ensure styles within iframe do not add unnecessary scroll 62 iframeDocument.body.style.margin = '0'; 63 iframeDocument.body.style.padding = '0'; 64 iframe.style.height = (iframeDocument.documentElement.scrollHeight + 5) + 'px'; 65 66 } 67 } 68 69 // Call the function initially 70 setIframeHeight(); 71 setTimeout(setIframeHeight, 500); // delay in milliseconds 72 }); 73 74 var message_id = $('#message_id').val(); 75 var is_seen = $('#is_seen').val(); 76 77 $.ajax({ 78 url: BASE_PATH + 'is-seen', 79 type: "POST", 80 data: { 81 _token: _token, 82 is_seen: is_seen, 83 message_id: message_id, 84 }, 85 success: function(data) { 86 }, 87 error: function(data) { 88 }, 89 }); 90 91 } 92 93 $("#save_message").on("click", function() { 94 var message_id = $('#message_id').val(); 95 $("#save_message").prop('disabled', true); 96 $("#save_message").attr("title", please_wait); 97 $("#save_message").attr("data-bs-original-title", please_wait); 98 $("#save_message").html( 99 '<i class="fa-solid fa-circle-notch fa-spin"></i>'); 100 $.ajax({ 101 url: BASE_PATH + 'messages', 102 type: "POST", 103 data: { 104 _token: _token, 105 message_id: message_id, 106 }, 107 success: function(data) { 108 109 $("#save_message").prop('disabled', false); 110 111 if (data.favorited) { 112 $("#save_message").html( 113 '<i class="fa-solid fa-heart star-icon-color"></i>'); 114 $("#save_message").attr("title", favorited); 115 $("#save_message").attr("data-bs-original-title", favorited); 116 } else { 117 $("#save_message").html('<i class="fa-regular fa-heart"></i>'); 118 $("#save_message").attr("title", not_favorited); 119 $("#save_message").attr("data-bs-original-title", not_favorited); 120 } 121 122 flasher.success(data.message, flasher_success); 123 124 }, 125 error: function(data) { 126 $("#save_message").prop('disabled', false); 127 $("#save_message").html('<i class="fa-regular fa-heart"></i>'); 128 $("#save_message").attr("title", not_favorited); 129 $("#save_message").attr("data-bs-original-title", not_favorited); 130 var res = parseData(data); 131 var message = res.responseJSON.message; 132 flasher.error(message, flasher_error); 133 134 }, 135 }); 136 }); 137 138 139 140 function landing_email(pass = false) { 141 142 if (email.val().length == 0 || email.val() == landing || pass) { 143 setButtonState(true); 144 email.val(landing); 145 window.myLanding = setInterval(function() { 146 var val = ""; 147 switch (email.val()) { 148 case landing: 149 val = landing + "."; 150 break; 151 152 case landing + ".": 153 val = landing + ".."; 154 break; 155 156 case landing + "..": 157 val = landing + "..."; 158 break; 159 case landing + "...": 160 val = landing; 161 break; 162 } 163 email.val(val); 164 }, 100); 165 } 166 } 167 168 169 // Enable or disable buttons based on the "disabled" parameter 170 function setButtonState(disabled = false) { 171 var buttons = $(".disable-button"); 172 173 if (disabled) { 174 buttons.prop('disabled', true); 175 } else { 176 setTimeout(function() { 177 buttons.prop('disabled', false); 178 }, 500); // delay in milliseconds 179 } 180 181 } 182 183 // Parse data into an object, handling possible errors 184 function parseData(data) { 185 if (!data) return {}; 186 try { 187 return typeof data === 'object' ? data : JSON.parse(data); 188 } catch (e) { 189 console.error('Unable to parse data:', e); 190 return {}; 191 } 192 } 193 194 195 function success_message(data, message = null) { 196 197 if (message != null) { 198 flasher.success(message, flasher_success); 199 } 200 201 clearInterval(window.myLanding); 202 203 var res = parseData(data); 204 205 window.check_is_runing = true; 206 email.val(res.mailbox); 207 email_token.val(res.email_token); 208 localStorage.setItem('histories', JSON.stringify(res.histories)); 209 let histories = JSON.parse(localStorage.getItem("histories")); 210 convertLocalStorageEmailsToHtmlHistory(histories, true); 211 212 window.stop = false;
213 214 setButtonState(); 215 216 return res; 217 218 } 219 220 function messages() { 221 222 window.check_is_runing = false; 223 224 const controller = new AbortController(); 225 226 if (window.stop) { 227 return false; 228 } 229 230 let captcha = $('#captcha-response').val(); 231 232 landing_email(); 233 234 axios.post(BASE_PATH + 'get_messages', { 235 _token: _token, 236 captcha: captcha 237 }, { 238 signal: controller.signal 239 }) 240 .then(function(response) { 241 242 Progress.configure({ 243 color: [secondaryColor] 244 }); 245 Progress.configure({ 246 speed: 1 247 }); 248 Progress.complete(); 249 var res = success_message(response.data); 250 251 if (res.messages.length == 0) { 252 $(".mailbox").addClass("empty"); 253 $("#mailbox").html(""); 254 } else { 255 $(".mailbox").removeClass("empty"); 256 $("#mailbox").html(""); 257 } 258 259 var count_notification = 0; 260 261 _.forEach(res.messages, function(item, index, object) { 262 263 if (saveIdToLocalStorage(item.id)) { 264 count_notification++; 265 } 266 267 var is_seen = ""; 268 if (!item.is_seen) { 269 is_seen = '<span class="is_seen_message">' + new_message + 270 '</span>'; 271 } 272 273 $("#mailbox").prepend(` 274 <div class="mailbox-item mailbox-custom-link" data-url="${BASE_PATH}view/${item.id}"> 275 <!-- Start Mailbox Item Col --> 276 <div class="mailbox-item-col"> 277 <a href="${BASE_PATH}view/${item.id}"> 278 <p>${item.from}</p> 279 <p class="small">${item.from_email}</p> 280 </a> 281 </div> 282 <!-- End Mailbox Item Col --> 283 <!-- Start Mailbox Item Col --> 284 <div class="mailbox-item-col"> 285 <a href="${BASE_PATH}view/${item.id}" class="link link-primary">${item.subject}</a> 286 </div> 287 <!-- End Mailbox Item Col --> 288 <!-- Start Mailbox Item Col --> 289 <div class="mailbox-item-col small"> 290 <time>${moment(item.receivedAt).format("hh:mm A DD/MM/YYYY ")}</time> 291 </div> 292 <!-- End Mailbox Item Col --> 293 ${is_seen} 294 </div> 295 `); 296 297 }); 298 299 if (count_notification > 0) { 300 transferCompletedAudio.play().catch(function(error) { 301 console.error('Audio playback failed:', error); 302 }); 303 flashTitle("New Message Received!"); 304 } 305 }) 306 .catch(function(error) { 307 if (axios.isCancel(error)) { 308 console.log("Axios request was cancelled by user"); 309 } else { 310 email.val(error.response.data.message); 311 clearInterval(window.myLanding); 312 313 } 314 }); 315 316 // Use the cancel token to cancel the request on click 317 $(".kill").on("click", function() { 318 controller.abort(); 319 window.check_is_runing = true; 320 }); 321 } 322 323 let clickCount = 0; 324 let resetClicksTimeout; 325 326 327 $("#delete").on("click", function() { 328 329 // Increment click count 330 clickCount++; 331 332 // If this is the first click, start the timer to reset the count 333 if (!resetClicksTimeout) { 334 resetClicksTimeout = setTimeout(function() { 335 clickCount = 0; 336 resetClicksTimeout = null; 337 }, 60000); // Reset after 1 second 338 } 339 340 // If clicks exceed 2 within 1 second, prevent further actions and show alert 341 if (clickCount > 2) { 342 flasher.error(limit_error, flasher_error); 343 return; // Prevent further execution if more than 2 clicks in 1 second 344 } 345 346 347 window.stop = true; 348 landing_email(true); 349
350 axios.post(BASE_PATH + 'delete', { 351 _token: _token 352 }) 353 .then(function(response) { 354 success_message(response.data, email_deleted_message); 355 call_messsage(); 356 }) 357 .catch(function(error) { 358 window.stop = false; 359 setButtonState(); 360 }); 361 362 }); 363 364 $('body').on('click', '.mailbox-custom-link', function(event) { 365 // Get the URL from the data-url attribute 366 var url = $(this).attr("data-url"); 367 368 // Navigate to the URL when the div is clicked 369 window.location.href = url; 370 }); 371 372 373 $('body').on('click', '.history_choose_email', function(event) { 374 const id = $(this).attr('for').split('@'); 375 const name = id[0]; 376 const domain = id[1]; 377 const old_email = $("#mainEmail").val(); 378 379 window.stop = true; 380 landing_email(true); 381 382 // clear box function 383 384 axios.post(BASE_PATH + 'change_email', { 385 _token: _token, 386 name: name, 387 domain: domain, 388 }) 389 .then((response) => { 390 $('#history').modal('toggle'); 391 success_message(response.data, email_changed_message); 392 call_messsage(); 393 }) 394 .catch((error) => { 395 clearInterval(window.myLanding); 396 window.stop = false; 397 setButtonState(); 398 email.val(old_email); 399 400 var errors = error.response.data.errors 401 402 for (const field in errors) { 403 if (errors.hasOwnProperty(field)) { 404 const errorMessages = errors[field]; 405 errorMessages.forEach(errorMessage => { 406 flasher.error(errorMessage, flasher_error); 407 }); 408 } 409 } 410 411 }); 412 }); 413 414 415 $("#change_email").on("click", function() { 416 417 var name = $("#random_code_input").val(); 418 var domain = $("#name_domain").val(); 419 var old_email = $("#mainEmail").val(); 420 421 window.stop = true; 422 423 landing_email(true); 424 425 // clear box function 426 427 axios.post(BASE_PATH + 'change', { 428 _token: _token, 429 name: name, 430 domain: domain, 431 }) 432 .then(function(response) { 433 434 $('#changeEmail').modal('toggle'); 435 $("#random_code_input").val(''); 436 437 success_message(response.data, email_changed_message); 438 call_messsage(); 439 440 }) 441 .catch(function(error) { 442 443 444 var errors = error.response.data.errors 445 446 for (const field in errors) { 447 if (errors.hasOwnProperty(field)) { 448 const errorMessages = errors[field]; 449 errorMessages.forEach(errorMessage => { 450 flasher.error(errorMessage, flasher_error); 451 }); 452 } 453 } 454 455 clearInterval(window.myLanding); 456 window.stop = false; 457 setButtonState(); 458 email.val(old_email); 459 460 }); 461 462 }); 463 464 465 $('body').on('click', '#delete_history', function(event) { 466 467 $('#delete_history').prop('disabled', true); 468 window.stop = true; 469 470 const emailsHistory = JSON.parse(localStorage.getItem("histories")); 471 const checkedEmails = $('.all_emails_checkbox:checkbox:checked').map(function() { 472 473 var delete_email = $(this).val(); 474 if (isValidEmail(delete_email)) { 475 if (delete_email != email.val()) { 476 return delete_email; 477 } 478 } 479 480 }).get(); 481 482 if (checkedEmails.length == 0) { 483 $('.all_emails_checkbox').prop('checked', false); 484 } 485 486 axios.post(BASE_PATH + 'delete_emails', { 487 _token: _token, 488 emails: checkedEmails, 489 }) 490 .then((response) => { 491 $('#delete_history').prop('disabled', false); 492 window.stop = false;
493 if (response.data.success) { 494 const updatedEmailsHistory = emailsHistory.filter(function(emailObj) { 495 return !checkedEmails.includes(emailObj.email); 496 }); 497 498 localStorage.setItem('histories', JSON.stringify(updatedEmailsHistory)); 499 convertLocalStorageEmailsToHtmlHistory(updatedEmailsHistory); 500 $("#search_history").val(''); 501 } 502 }) 503 .catch((error) => { 504 window.stop = false; 505 $('#delete_history').prop('disabled', false); 506 }); 507 }); 508 509 function call_messsage() { 510 $(".mailbox").addClass("empty"); 511 $("#mailbox").html(""); 512 messages(); 513 } 514 515 function saveIdToLocalStorage(id) { 516 try { 517 if (typeof(Storage) !== "undefined") { 518 let idsArray = JSON.parse(localStorage.getItem("idArray")) || []; 519 if (!idsArray.includes(id)) { 520 idsArray.push(id); 521 localStorage.setItem("idArray", JSON.stringify(idsArray)); 522 return true; 523 } 524 return false; 525 } else { 526 return false; 527 } 528 } catch (error) { 529 console.error("An error occurred while saving to Local Storage: " + error.message); 530 return false; 531 } 532 } 533 534 $("#show_history").on("click", function() { 535 $("#search_history").val(''); 536 // Pass the cached email history to the rendering function 537 let histories = JSON.parse(localStorage.getItem("histories")); 538 convertLocalStorageEmailsToHtmlHistory(histories); 539 540 $('#history').modal('show'); 541 }); 542 543 544 function convertLocalStorageEmailsToHtmlHistory(emailsData, check_search = false) { 545 546 if (check_search) { 547 if ($("#search_history").val() != "" || $(".all_emails_checkbox ").is(":checked")) { 548 return false; 549 } 550 } 551 552 const getMonthName = item => moment(item.time, 'YYYY-MM-DD hh:mm:ss').format('YYYY-MM-DD'); 553 const emailsGroupedByMonth = _.groupBy(_.orderBy(emailsData, 'time', 'asc'), getMonthName); 554 555 // Group emails by month using Moment.js library 556 557 // Clear contents of 'mail-history' element 558 const $mailHistory = $('#mail-history'); 559 $mailHistory.html(''); 560 561 // Generate HTML for each month's group of emails 562 let dayIndex = 1; 563 if (emailsData.length === 0) { 564 // Display message if history is empty 565 $mailHistory.html(` 566 <div class="mail-history-empty"> 567 <h5>The email history is empty.</h5> 568 </div> 569 `); 570 } else { 571 _.forEach(emailsGroupedByMonth, function(emailsInMonth, monthKey) { 572 573 // Create div element for each day's emails 574 const $mailHistoryDay = $(` 575 <div class="mail-history-day"> 576 <div class="mail-history-day-header text-start"> 577 <div class="form-check"> 578 <input class="form-check-input all_emails_checkbox check_all" id="check${dayIndex}" type="checkbox" /> 579 </div> 580 <p class="mb-0">${moment(monthKey).format('dddd - YYYY/MM/DD')}</p> 581 </div> 582 <div class="mail-history-day-body" id="mail-history-day-body${dayIndex}"> 583 </div> 584 </div> 585 `); 586 587 // Append day's div element to 'mail-history' element 588 $mailHistory.prepend($mailHistoryDay); 589 590 // Generate HTML for each email in the day's group 591 _.forEach(emailsInMonth, function(emailData) { 592 593 // Create button label based on email status 594 let buttonLabel; 595 if (emailData.current === true) { 596 buttonLabel = '<label class="ms-auto label_bluer">' + current_message + 597 '</label>'; 598 } else { 599 buttonLabel = 600 `<label class="kill btn btn-primary btn-sm history_choose_email" for="${emailData.email}">${choose_message}</label>`; 601 } 602 603 // Create div element for the email 604 const $mailHistoryItem = $(` 605 <div class="mail-history-item"> 606 <div class="form-check"> 607 <input class="form-check-input all_emails_checkbox check${dayIndex}" value="${emailData.email}" type="checkbox" /> 608 </div>
609 <span>${moment(emailData.time).format('hh:mm A')}</span> 610 <label class="email">${emailData.email}</label> 611 ${buttonLabel} 612 </div> 613 `); 614 615 // Append email div element to the day's body 616 $(`#mail-history-day-body${dayIndex}`).prepend($mailHistoryItem); 617 }); 618 619 dayIndex++; 620 }); 621 } 622 623 // Update email count and message 624 625 let histories = JSON.parse(localStorage.getItem("histories")).length; 626 $('#history-count').html(histories); 627 } 628 629 630 $("#search_history").keyup(function() { 631 var search_history = $(this).val(); 632 633 const monthName = item => moment(item.time, 'YYYY-MM-DD hh:mm:ss').format( 634 'YYYY-MM-DD'); 635 636 var results = _.filter(JSON.parse(localStorage.getItem("histories")), function(obj) { 637 return obj.email.indexOf(search_history) !== -1; 638 }); 639 640 if (results.length == 0) { 641 642 $('#mail-history').html(` 643 <div class="mail-history-empty"> 644 <h5> ${search_history_message} "${search_history}"</h5> 645 </div> 646 `); 647 648 } else { 649 convertLocalStorageEmailsToHtmlHistory(results); 650 }; 651 }); 652 653 654 655 $('body').on('click', '.check_all', function(event) { 656 const id = $(this).attr('id'); 657 $('.' + id).prop('checked', this.checked); 658 }); 659 660 $("#show_qr_code").on("click", function() { 661 var emailVal = email_token.val(); 662 if (emailVal.length == 0) { 663 return; 664 } 665 $("#qrcode").html(''); 666 var qrcode = new QRCode(document.getElementById("qrcode"), { 667 text: BASE_PATH + "go-to-email/" + emailVal, 668 width: 200, 669 height: 200, 670 colorDark: "#000000", 671 colorLight: "#ffffff", 672 correctLevel: QRCode.CorrectLevel.H 673 }); 674 $('#qrCode').modal('show'); 675 }); 676 677 678 function isValidEmail(email) { 679 // Regular expression for email validation 680 var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 681 return emailRegex.test(email); 682 } 683 684 function genCode(charsLength = 10) { 685 var chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 686 var code = ""; 687 for (var i = 1; i <= charsLength; i++) { 688 var randomNumber = Math.floor(Math.random() * chars.length); 689 code += chars.substring(randomNumber, randomNumber + 1); 690 } 691 692 return code; 693 } 694 695 696 window.myCallback = function setResponse(response) { 697 document.getElementById('captcha-response').value = response; 698 window.check_recaptcha = true; 699 } 700 701 702 function check_messgaes() { 703 704 if (window.check_is_runing && window.check_recaptcha) { 705 messages(); 706 } 707 } 708 709 710 function recaptcha_works() { 711 if (window.check_recaptcha) { 712 messages(); 713 clearInterval(window.set_recaptch); 714 } else { 715 grecaptcha.execute(); 716 } 717 } 718 719 let mailbox_email = document.querySelector("#mainEmail"); 720 721 if (mailbox_email) { 722 try { 723 setInterval(check_messgaes, 1000 * fetch_time); 724 window.set_recaptch = setInterval(recaptcha_works, 1000); 725 } catch (error) {} 726 } 727 728 $("#random_code").click(function() { 729 $("#random_code_input").val(genCode()); 730 }) 731 732 733 let originalTitle = document.title; 734 735 function flashTitle(newTitle) { 736 let flash = true; 737 let interval = setInterval(function() { 738 document.title = flash ? newTitle : originalTitle; 739 flash = !flash; 740 }, 1000); 741 742 // Stop flashing after a few seconds (you can adjust the duration) 743 setTimeout(function() { 744 clearInterval(interval); 745 document.title = originalTitle; 746 }, 1000000); 747 } 748 749});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.