Skip to content

Commit

Permalink
v1.1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
geek-at committed Nov 21, 2023
1 parent 45f2693 commit b1ad361
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 30 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
@@ -1,14 +1,21 @@
# Changelog

## Nov 19th 2023 - V1.1.3
## V1.1.5
- Added support for plaintext file attachments
- Updated the way attachments are stored. Now it's md5 + filename

## V1.1.4
- Fixed crash when email contains attachment

## V1.1.3
- Switched SMTP server to Python3 and aiosmptd
- Switched PHP backend to PHP8.1
- Implemented content-id replacement with smart link to API so embedded images will now work
- Updated JSON to include details about attachments (filename,size in bytes,id,cid and a download URL)
- Removed quotes from ini settings
- Made docker start script more neat

## Nov 13th 2023 - V1.0.0
## V1.0.0
- Launch of V1.0.0
- Complete rewrite of the GUI
- Breaking: New API (/rss, /json, /api) instead of old `api.php` calls
46 changes: 28 additions & 18 deletions python/mailserver3.py
Expand Up @@ -6,7 +6,7 @@
import re
import time
import json
import uuid
import hashlib
import configparser
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
Expand Down Expand Up @@ -48,22 +48,15 @@ async def handle_DATA(self, server, session, envelope):
if part.get_content_maintype() == 'multipart':
continue
if part.get_content_type() == 'text/plain':
plaintext += part.get_payload()
#if it's a file
if part.get_filename() is not None:
attachments['file%d' % len(attachments)] = self.handleAttachment(part)
else:
plaintext += part.get_payload()
elif part.get_content_type() == 'text/html':
html += part.get_payload()
else:
filename = part.get_filename()
cid = part.get('Content-ID')
if cid is not None:
cid = cid[1:-1]
elif part.get('Content-ID') is not None:
cid = part.get('Content-ID')
else:
cid = str(uuid.uuid4())
logger.debug('Handling attachment: "%s" of type "%s" with CID "%s"',filename, part.get_content_type(), cid)
if filename is None:
filename = 'untitled'
attachments['file%d' % len(attachments)] = (filename,part.get_payload(decode=True),cid)
attachments['file%d' % len(attachments)] = self.handleAttachment(part)

for em in rcpts:
em = em.lower()
Expand Down Expand Up @@ -106,15 +99,16 @@ async def handle_DATA(self, server, session, envelope):
if not os.path.exists("../data/"+em+"/attachments"):
os.mkdir( "../data/"+em+"/attachments", 0o755 )
attd = attachments[att]
file = open("../data/"+em+"/attachments/"+filenamebase+"-"+attd[0], 'wb')
file_id = attd[3]
file = open("../data/"+em+"/attachments/"+file_id, 'wb')
file.write(attd[1])
file.close()
edata["attachments"].append(filenamebase+"-"+attd[0])
edata["attachments"].append(file_id)
edata["attachments_details"].append({
"filename":attd[0],
"cid":attd[2],
"id":filenamebase+"-"+attd[0],
"download_url":URL+"/api/attachment/"+em+"/"+filenamebase+"-"+attd[0],
"id":attd[3],
"download_url":URL+"/api/attachment/"+em+"/"+file_id,
"size":len(attd[1])
})

Expand All @@ -123,6 +117,22 @@ async def handle_DATA(self, server, session, envelope):
json.dump(savedata, outfile)

return '250 OK'

def handleAttachment(self, part):
filename = part.get_filename()
if filename is None:
filename = 'untitled'
cid = part.get('Content-ID')
if cid is not None:
cid = cid[1:-1]
elif part.get('X-Attachment-Id') is not None:
cid = part.get('X-Attachment-Id')
else: # else create a unique id using md5 of the attachment
cid = hashlib.md5(part.get_payload(decode=True)).hexdigest()
fid = hashlib.md5(filename.encode('utf-8')).hexdigest()+filename
logger.debug('Handling attachment: "%s" (ID: "%s") of type "%s" with CID "%s"',filename, fid,part.get_content_type(), cid)

return (filename,part.get_payload(decode=True),cid,fid)

def replace_cid_with_attachment_id(self, html_content, attachments,filenamebase,email):
# Replace cid references with attachment filename
Expand Down
10 changes: 2 additions & 8 deletions web/inc/OpenTrashmailBackend.class.php
Expand Up @@ -152,18 +152,12 @@ function getRawMail($email,$id,$htmlbody=false)

function getAttachment($email,$attachment)
{
$id = substr($attachment,0,13);
$attachment = substr($attachment,14);
if(!filter_var($email, FILTER_VALIDATE_EMAIL))
return $this->error('Invalid email address');
else if(!is_numeric($id))
return $this->error('Invalid id');
else if(!emailIDExists($email,$id))
return $this->error('Email not found');
else if(!attachmentExists($email,$id,$attachment))
else if(!attachmentExists($email,$attachment))
return $this->error('Attachment not found');
$dir = getDirForEmail($email);
$file = $dir.DS.'attachments'.DS.$id.'-'.$attachment;
$file = $dir.DS.'attachments'.DS.$attachment;
$mime = mime_content_type($file);
header('Content-Type: '.$mime);
header('Content-Length: ' . filesize($file));
Expand Down
4 changes: 2 additions & 2 deletions web/inc/core.php
Expand Up @@ -127,9 +127,9 @@ function listEmailAdresses()
return $o;
}

function attachmentExists($email,$id,$attachment)
function attachmentExists($email,$id,$attachment=false)
{
return file_exists(getDirForEmail($email).DS.'attachments'.DS.$id.'-'.$attachment);
return file_exists(getDirForEmail($email).DS.'attachments'.DS.$id.(($attachment)?'-'.$attachment:''));
}

function listAttachmentsOfMailID($email,$id)
Expand Down

0 comments on commit b1ad361

Please sign in to comment.