This commit is contained in:
matt (tomatoj) 2020-06-02 15:29:58 +02:00
parent 5f859da3f4
commit e0ba0d8f1c
16 changed files with 641 additions and 2 deletions

View file

@ -1,2 +1,41 @@
# PHP Temporary Email # Temporary Email made with PHP
Temporary email created with 99% of PHP(imap) and 1% of JS
You can check its live version at [billieiscute.xyz](https://billieiscute.xyz/temp/)
PHP-Temporary-Email is self-hosted temporary email library. You can use it on any website that has PHP IMAP
## Installation
Clone this repositary
```bash
git clone https://github.com/xxx/xx
```
Install IMAP for php (Linux)
```bash
sudo apt-get install php5-imap
sudo php5enmod imap
```
Install IMAP for php (MacOS)
```bash
brew reinstall php56 --with-imap
```
Open 'assets/php/get-imap-details.php'
Set IMAP connection details in format
```php
imap_open("{address}", "username", "password");
```
Set other details such as delete timeframe and so on.
## Usage
After this you can deploy the repo on your server.
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
## License
[GNU AGPLv3](https://choosealicense.com/licenses/agpl-3.0/)

37
src/assets/css/style.css Normal file
View file

@ -0,0 +1,37 @@
body{
color: white;
}
.change-on-hover:hover{
color: rgb(255, 0, 157);
font-weight: bolder;
}
.message-header{
position: absolute;
top: 30%;
left: 22%;
}
.message-body{
position: absolute;
top: 45%;
left:14vw;
padding:1rem 30%;
border-radius: 10px;
margin-bottom: 2rem;
}
.footer{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #111111;
color: white;
text-align: center;
}
.footer a{
font-weight: bolder;
color:rgb(255, 0, 157);
text-decoration: none;
}
.footer a:hover{
color:blue;
}

92
src/assets/js/script.js Normal file
View file

@ -0,0 +1,92 @@
function CheckEmailOnLoad(){
if(GatherCookie('t_email_address_1').length != 0)
{
//If cookie already exist, get email address from it and set it as current email address
var current_address = GatherCookie('t_email_address_1');
document.getElementById("mail-field").value = current_address;
document.cookie = "t_email_address_1="+current_address+"; expires=Jan, 1 Dec 2999 12:00:00 UTC";
}
else{
//If cookie doesn't exist, generate random address, and set it as current.
var current_address = GenerateRandomAddress(8).toLowerCase()+"@billieiscute.xyz";
document.getElementById("mail-field").value = current_address;
document.cookie = "t_email_address_1="+current_address+"; expires=Jan, 1 Dec 2999 12:00:00 UTC";
}
setTimeout(function() { location.reload(); }, 25000);
}
function CopyEmailAddress(){
//Copy all informations into clipboard, basic js function.
var copyText = document.getElementById("mail-field");
copyText.select();
copyText.setSelectionRange(0, 99999);
copyText.select
document.execCommand("copy");
}
function ChangeEmailAddress(){
//Check if email address is blacklisted, if it is, use random address instead
if(CheckEmailAddress((document.getElementById("mail-field").value).split('@')[0]))
{
//Email address is blacklisted
var current_address = GenerateRandomAddress(8).toLowerCase()+"@billieiscute.xyz";
document.getElementById("mail-field").value = current_address;
document.cookie = "t_email_address_1="+current_address+"; expires=Jan, 1 Dec 2999 12:00:00 UTC";
location.reload();
}
else
{
//Email address isn't blacklisted
document.getElementById("mail-field").value = document.getElementById("mail-field").value+"@billieiscute.xyz";
var current_address = document.getElementById("mail-field").value;
document.cookie = "t_email_address_1="+current_address+"; expires=Jan, 1 Dec 2999 12:00:00 UTC";
location.reload();
}
}
//Gather the cookie, as cookies are not being saved as string value;
function GatherCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
//Generator of random email addresses.
function GenerateRandomAddress(length)
{
var result= '';
var characters= 'abcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
//Check if the email address that user want to use isn't on our blacklist.
//This is using deprecated method, as it was the way that came on my mind.
//You can convert this as you want to, but this is working just fine as of now.
function CheckEmailAddress(email){
blacklisted = false;
$.ajax({
url : "./assets/php/check-email-prefix.php?email="+email,
type : "get",
async: false,
success : function(data) {
if(data){
blacklisted=true;
}
else{
blacklisted=false;
}
},
error: function() {
}
});
return blacklisted;
}

View file

@ -0,0 +1,6 @@
<?php
require('get-imap-details.php');
$email = $_GET['email']; //Get email address from query (https://address/?email=test)
//Return the value itself, used in js to pass the value in js function
echo BlacklistedEmailAddresses($email);
?>

View file

@ -0,0 +1,63 @@
<?php
//Log every sigle action on the website, logs also when the website refreshes itself (depends on where you use this function)
function LogAllActions(){
$servername = "localhost"; //Server address the database is hosted on
$username = "root"; //Your database manager username
$password = ""; //Your database manager password
$dbname = "billieiscute"; //Name of database itself
$email_address = $_COOKIE['t_email_address_1']; //Get email address to log from cookie
$table_name = "emails"; //Get table you want to save data into
$accessed_by = GetAccessedBy(); //Get ip address of user that accessed specific email address
date_default_timezone_set("UTC"); //Set default timezone to UTC, so we always get UTC date
$date_unix = gmdate("Y-m-d\TH:i:s\Z"); //Format UTC time
$unix = time(); //Get UTC timestamp
$conn = new mysqli($servername, $username, $password, $dbname); //Create connection between current server and database
if ($conn->connect_error)
{
//Error occured, do some action you want to do
//Redirect, log, or return some value here
}
$sql = "INSERT INTO $table_name (email_address, accessed_by, unix_timestamp,date_time)
VALUES ('$email_adress','$accessed_by','$unix','$date_unix')"; //Get table, select fields and insert values into it
if ($conn->query($sql) === TRUE)
{
//Record successfully saved into database
//You can continue in logging here, or eventually display message / return value
}
else
{
//Error occured when writing into databse, do some action here.
//You can put redirect, messages and so on here.
}
$conn->close();
}
function GetAccessedBy()
{
//Get every single possible redirect, and get ip address from it (you can't get address behind VPN with this)
//I recommend encrypting the output. So in case of data breach nothing will be 'leaked'
//I'm not doing it here, as I wouldn't be able to debug on localhost then.
$ipaddress = '';
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
$ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
return $ipaddress;
}
?>

View file

@ -0,0 +1,27 @@
<?php
require('get-imap-details.php');
//Delete all emails older than 7 days using cron jobs.
//You can also set custom deletation in 'get-imap-details.php'
DeleteOldMessages();
function DeleteOldMessages()
{
$imap = OpenImap();
$messages = imap_check($imap);
$imap_result = imap_fetch_overview($imap,"1:{$messages->Nmsgs}",0); //Get overview of messages in catchall inbox.
foreach(array_reverse($imap_result) as $email)
{
//Delete the email only if it's not already deleted.
if($email->deleted !=1)
{
$email_timestamp = $email->udate;
if(time()-GetDeleteTime() > $email_timestamp)
{
imap_delete($imap, $email->msgno);
}
}
}
//Delete all messages marked for delete, you can command the line below and keep them in your 'trash bin'
imap_expunge($imap);
imap_close($imap);
}
?>

View file

@ -0,0 +1,63 @@
<?php
require('get-imap-details.php');
require('database-logging.php');
date_default_timezone_set('UTC');
function DisplayEmails($email_address)
{
//Open Imap with given credentials.
//LogAllActions(); //Un-Command this line if you want to log all actions.
$imap = OpenImap();
$messages = imap_check($imap); //Load all messages that are in our catchall inbox
$messages_displayed = 0; //Count of emails already displayed
$max_messages_on_screen = 50; //Max messages you want to display at once, in this case 50
$email_in_blacklist = false;
$imap_result = imap_fetch_overview($imap,"1:{$messages->Nmsgs}",0);
foreach(array_reverse($imap_result) as $email)
{
//Check if the email address isn't blacklisted, if it is, don't display anything.
if(!BlacklistedEmailAddresses(explode('@',$email_address)[0]))
{
if($email->deleted !=1)
{
//Go through all emails, but display only emails for the current email address
if($email->to == $email_address && $messages_displayed <= $max_messages_on_screen)
{
$messages_displayed += 1;
$message_id = $email->msgno;
$header = imap_header($imap, $message_id);
//The part of message we'll display as preview, you can change how many characters you want to display below.
$characters_to_display = 50;
$message_preview = substr(imap_fetchbody($imap, $message_id, 1), 0, $characters_to_display);
$sender_address = $header->from[0]->mailbox."@".$header->from[0]->host;
//Display all email as separate table raw.
//You can change this by chaning the echo below onto your own one
echo "<tr onclick=\"window.open('./view/?id=$message_id', '_blank')\"><th scope=\"row\">$sender_address</th><td>$email->subject</td><td>$message_preview</td></tr>";
}
$email_timestamp = $email->udate;
//Check for every email if it's older than 7 days. If it is, delete.
//This is only used when the page is loaded by someone, if you want to automate this in cron jobs please check 'delete-old-emails.php'
//You can change delete timeframe in 'get-imap-details.php'
if(time()-GetDeleteTime() > $email_timestamp)
{
imap_delete($imap, $email->msgno); //Mark message with specific id as 'for delete'
}
}
}
else
{
$email_in_blacklist = true; //Email is in blacklist, don't display anything.
}
}
//Display this content if there are no messages matching this email address
if($messages_displayed == 0 && !$email_in_blacklist){
echo "<tr><th scope=\"row\">This inbox is completely empty</th></tr>";
}
//Display if current email address is in blacklist, thus user can't access its content
else if($email_in_blacklist){
echo "<tr><th scope=\"row\">You can't view this email address</th></tr>";
}
//Delete all messages marked for delete, you can command the line below and keep them in your 'trash bin'
imap_expunge($imap);
imap_close($imap);
}
?>

View file

@ -0,0 +1,35 @@
<?php
//Enable this if you want to display warnings, error, notices and so on. (Simply command the line below)
//error_reporting(0);
function OpenImap()
{
//Set your imap connection details, the format is usually
//imap_open("{domain:143/novalidate-cert}", "username", "password")
//With your own imap details of course.
return imap_open("{address:143/novalidate-cert}", "username", "password");
}
function GetDeleteTime()
{
$delete_in_days = 7; //Change this if you want to delete messages later/earlier
return $delete_in_days * 24 * 60 *60; //Return the value in seconds, so we can compare it to unix timestamp of email
}
function EnableApiView()
{
return true; //Change this depending on if you want to enable 'message' folder (API display) or no
}
function BlacklistedEmailAddresses($email_address)
{
//Add email prefixes you want to not be accessible by anyone, such as test,admin,owner and so on
$blacklisted_emails = [
"catchall",
"admin",
"test",
"owner"
];
return in_array($email_address,$blacklisted_emails);
}
//Return error page location, so we don't have to change it in every single script manually.
function GetNotFoundPage(){
return '../404/';
}
?>

53
src/index.php Normal file
View file

@ -0,0 +1,53 @@
<?php
require('assets/php/get-emails.php')
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="assets/css/style.css">
<title>Billie is cute || Temporary E-Mail</title>
</head>
<body style="background-color: #1a1a1a;" onload="CheckEmailOnLoad()">
<div class="header" style="text-align:center;margin-bottom: 2rem;margin-top: 1rem;">
<a href="https://billieiscute.xyz" style="text-decoration:none;color:white;">
<div style="font-size:5rem;font-weight:bolder;line-height: 0.85;">
Billie<span style="font-size:7rem;color: rgb(255, 0, 157);">IS</span>Cute
</div>
<div>
<span style="font-size: 2vw;">Temporary <span style="color: rgb(255, 0, 157);font-weight: bolder;">E-mail</span></span>
</div>
</a>
</div>
<div style="text-align:center;">
<span class="change-on-hover" onclick="CopyEmailAddress()">E-mail address (click to copy)</span>
<div class="input-group" style="width: 25%;margin-left: 36.9%;">
<input style="text-align: center;" type="text" class="form-control" value="default@billieiscute.xyz" id="mail-field" onchange="ChangeEmailAddress()">
</div>
</div>
<div style="width:50%;margin-left:24%;margin-top:1rem;margin-bottom:5rem;">
<table class="table table-dark" style="background-color: #111111;" id="inbox">
<thead>
<tr style="color: rgb(255, 0, 157);text-align: center;font-weight: bolder;border:solid #111111 3px;border-radius: 10rem;">
<th scope="col">From</th>
<th scope="col">Title</th>
<th scope="col">Preview</th>
</tr>
</thead>
<tbody style="text-align: center;">
<?php
//Display all emails for current email address (the email address stored in cookies);
DisplayEmails($_COOKIE['t_email_address_1']);
?>
</tbody>
</table>
</div>
<div class="footer">
<p style="margin-top:1rem;">This project is open source, and is available on <a href="https://github.com" target="_blank">Github</a></p>
</div>
<script src="assets/js/script.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</body>
</html>

32
src/message/index.php Normal file
View file

@ -0,0 +1,32 @@
<?php
require('../assets/php/get-imap-details.php');
if(EnableApiView())
{
GetMessageDetails();
}
else
{
//Error message to display when this view is disabled.
//You can also redirect this page to your 404 error page, so it'll look like it doesn't even exist.
//Redirect using header, so header("Location: location"); die();
echo "403 access not allowed";
}
//Get all message details, and display the as array
function GetMessageDetails()
{
$message_id = $_GET["id"];
$imap = OpenImap();
$header = imap_header($imap, $message_id);
if($header)
{
$message_body = imap_fetchbody($imap, $message_id, 1);
print_r($header);
echo "<br>";
echo $message_body;
}
else{
echo "Message with id $message_id doesn't exist";
die();
}
}
?>

2
src/templates/info.txt Normal file
View file

@ -0,0 +1,2 @@
All templates i've created and used later in this project.
You can use them as inspiration.

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="assets/css/style.css">
<title>Billie is cute || Temporary E-Mail</title>
</head>
<body style="background-color: #1a1a1a;" onload="CheckEmailOnLoad()">
<div class="header" style="text-align:center;margin-bottom: 2rem;margin-top: 1rem;">
<div style="font-size:5rem;font-weight:bolder;line-height: 0.85;">
Billie<span style="font-size:7rem;color: rgb(255, 0, 157);">IS</span>Cute
</div>
<div>
<span style="font-size: 2vw;">Temporary <span style="color: rgb(255, 0, 157);font-weight: bolder;">E-mail</span></span>
</div>
</div>
<div style="text-align:center;">
<span class="change-on-hover" onclick="CopyEmailAddress()">E-mail address (click to copy)</span>
<div class="input-group" style="width: 25%;margin-left: 36.9%;" onclick="CopyEmailAddress()">
<input style="text-align: center;" type="text" class="form-control" value="default@billieiscute.xyz" id="mail-field" onchange="ChangeEmailAddress()">
</div>
</div>
<div style="width:50%;margin-left:24%;margin-top:1rem;">
<table class="table table-dark" style="background-color: #111111;" id="inbox">
<thead>
<tr style="color: rgb(255, 0, 157);text-align: center;font-weight: bolder;border:solid #111111 3px;border-radius: 10rem;">
<th scope="col">From</th>
<th scope="col">Title</th>
<th scope="col">Preview</th>
</tr>
</thead>
<tbody style="text-align: center;">
<tr onclick="window.open('./message/?id=$message_id', '_blank')"><th scope=\"row\">$sender_address</th><td>$email->subject</td><td>$message_preview</td></tr>
</tbody>
</table>
</div>
<script src="assets/js/script.js"></script>
<script src="https://ajax.cloudflare.com/cdn-cgi/scripts/7089c43e/cloudflare-static/rocket-loader.min.js" data-cf-settings="b848fd4a4b7a31ff3ab93689-|49" defer=""></script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<?php
$mbox = imap_open("{address:143/novalidate-cert}", "username", "password");
echo "<h1>Mailboxes</h1>\n";
$folders = imap_listmailbox($mbox, "{imap.example.org:143}", "*");
if ($folders == false) {
echo "Call failed<br />\n";
} else {
foreach ($folders as $val) {
echo $val . "<br />\n";
}
}
echo "<h1>Headers in INBOX</h1>\n";
$headers = imap_headers($mbox);
if ($headers == false) {
echo "Call failed<br />\n";
} else {
foreach ($headers as $val) {
print_r(imap_header($mbox,$val["number"]));
echo $val . "<br />\n";
}
}
imap_close($mbox);
?>

View file

@ -0,0 +1,14 @@
<?php
$mbox = imap_open("{address:143/novalidate-cert}", "username", "password")
or die("can't connect: " . imap_last_error());
$MC = imap_check($mbox);
// Fetch an overview for all messages in INBOX
$result = imap_fetch_overview($mbox,"1:{$MC->Nmsgs}",0);
foreach ($result as $overview) {
echo "#{$overview->msgno} ({$overview->date}) - From: {$overview->from}
{$overview->subject} {$overview->to}\n";
}
imap_close($mbox);
?>

32
src/templates/view.html Normal file
View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="assets/css/style.css">
<title>Billie is cute || Temporary E-Mail || Viewing $message_id</title>
</head>
<body style="background-color: #1a1a1a;">
<div class="header" style="text-align:center;margin-bottom: 2rem;margin-top: 1rem;">
<div style="font-size:5rem;font-weight:bolder;line-height: 0.85;">
Billie<span style="font-size:7rem;color: rgb(255, 0, 157);">IS</span>Cute
</div>
<div>
<span style="font-size: 2vw;">Temporary <span style="color: rgb(255, 0, 157);font-weight: bolder;">E-mail</span></span>
</div>
</div>
<div class="message">
<div class="message-header">
From : $address_from
<br>To : $address_to
<br>On : $message_date
<br>Message:
<br>
<div style="background-color: rgb(24, 24, 24);padding:0 25vw;border-radius: 10px;">
this is test email
</div>
</div>
</div>
</body>
</html>

74
src/view/index.php Normal file
View file

@ -0,0 +1,74 @@
<?php
$message_id = $_GET["id"];
require('../assets/php/get-imap-details.php');
$imap = OpenImap();
$header = imap_header($imap, $message_id);
//Check if the email was already deleted, if it was redired to error page (in this case 404)
if($header)
{
//Get all message details we need, such as from,to,date and title and sender name.
if($header->Deleted == 'D')
{
header('Location: '.GetNotFoundPage());
die();
}
$from = $header->from[0]->personal;
$from_address = $header->from[0]->mailbox."@".$header->from[0]->host;
$to_address = $header->toaddress;
$title = $header->subject;
$date = $header->date;
$message_body = imap_fetchbody($imap, $message_id, 1);
//Convert all links in emails to simple href, so in case the link is really long it won't display the site in some weird way.
//It'll simply convert https://test.com into <a href="https://test.com" target="_blank">link</a>
preg_match_all('/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i', $message_body, $result, PREG_PATTERN_ORDER);
foreach($result as $links){
foreach($links as $link){
$message_body = str_replace($link,"<a href=\"$link\" target=\"_blank\">link</a>",$message_body);
}
}
}
else{
//Redirect to error page in case email with specific id doesn't exist
header('Location: '.GetNotFoundPage());
die();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="../assets/css/style.css">
<title>Billie is cute || Temporary E-Mail - Viewing <?php echo $message_id;?></title>
</head>
<body style="background-color: #1a1a1a;">
<div class="header" style="text-align:center;margin-bottom: 2rem;margin-top: 1rem;">
<a href="https://billieiscute.xyz" style="text-decoration:none;color:white;">
<div style="font-size:5rem;font-weight:bolder;line-height: 0.85;">
Billie<span style="font-size:7rem;color: rgb(255, 0, 157);">IS</span>Cute
</div>
<div>
<span style="font-size: 2vw;">Temporary <span style="color: rgb(255, 0, 157);font-weight: bolder;">E-mail</span></span>
</div>
</a>
</div>
<div class="message">
<div class="message-header">
<span style="font-weight:bolder;font-size:1.5rem;">From:</span> <span style=";color: rgb(255, 0, 157)"><?php echo $from; ?></span>
<br><span style="font-weight:bolder;font-size:1.5rem;">From Address:</span> <span style="color: rgb(255, 0, 157)"><?php echo $from_address; ?></span>
<br><span style="font-weight:bolder;font-size:1.5rem;">To:</span> <span style="color: rgb(255, 0, 157)"><?php echo $to_address; ?></span>
<br><span style="font-weight:bolder;font-size:1.5rem;">On:</span> <span style="color: rgb(255, 0, 157)"><?php echo $date; ?></span>
<br><span style="font-weight:bolder;font-size:1.5rem;">Title:</span> <span style="color: rgb(255, 0, 157)"><?php echo $title; ?></span>
<br><span style="font-weight:bolder;font-size:1.5rem;">Message:</span>
<br>
<div style="background-color: rgb(24, 24, 24);width:75%;padding:1rem;border-radius:10px;margin-bottom: 5rem;">
<?php echo $message_body; ?>
</div>
</div>
</div>
<div class="footer">
<p style="margin-top:1rem;">This project is open source, and is available on <a href="https://github.com" target="_blank">Github</a></p>
</div>
</body>
</html>