From 37ed2955ff71a6fcde5ceb35c8e879bc573c2a6a Mon Sep 17 00:00:00 2001 From: Dream Hunter Date: Wed, 22 May 2024 20:48:03 +0800 Subject: [PATCH] fix: webhook JSON.stringify (#263) --- smtp_proxy_server/imap_server.py | 15 ++++++++--- smtp_proxy_server/parse_email.py | 1 - worker/src/mails_api/webhook_settings.ts | 33 ++++++++++++++++-------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/smtp_proxy_server/imap_server.py b/smtp_proxy_server/imap_server.py index 6b7be2eb..138a5d33 100644 --- a/smtp_proxy_server/imap_server.py +++ b/smtp_proxy_server/imap_server.py @@ -73,7 +73,7 @@ class SimpleMailbox: return 0 def getMessageCount(self): - return 2 ** 31 - 1 + return self.message_count or 1000 def getRecentCount(self): return 0 @@ -99,7 +99,7 @@ class SimpleMailbox: if "UIDNEXT" in names: r["UIDNEXT"] = self.getMessageCount() + 1 if "UIDVALIDITY" in names: - r["UIDVALIDITY"] = self.getUID() + r["UIDVALIDITY"] = self.getUIDValidity() if "UNSEEN" in names: r["UNSEEN"] = self.getUnseenCount() return defer.succeed(r) @@ -114,10 +114,11 @@ class SimpleMailbox: def fetchINBOX(self, messages): start, end = messages.ranges[0] start = max(start, 1) + limit = min(20, end - start + 1) if end and end >= start else 20 if self.message_count > 0 and start > self.message_count: return [] res = requests.get( - f"{settings.proxy_url}/api/mails?limit=20&offset={start - 1}", headers={ + f"{settings.proxy_url}/api/mails?limit={limit}&offset={start - 1}", headers={ "Authorization": f"Bearer {self.password}", "Content-Type": "application/json" } @@ -138,10 +139,11 @@ class SimpleMailbox: def fetchSENT(self, messages): start, end = messages.ranges[0] start = max(start, 1) + limit = min(20, end - start + 1) if end >= start else 20 if self.message_count > 0 and start > self.message_count: return [] res = requests.get( - f"{settings.proxy_url}/api/sendbox?limit=20&offset={start - 1}", headers={ + f"{settings.proxy_url}/api/sendbox?limit={limit}&offset={start - 1}", headers={ "Authorization": f"Bearer {self.password}", "Content-Type": "application/json" } @@ -194,8 +196,13 @@ class SimpleIMAPServer(imap4.IMAP4Server): self.factory = factory def lineReceived(self, line): + # _logger.info(f"Received: {line}") super().lineReceived(line) + def sendLine(self, line): + # _logger.info(f"Sent: {line}") + super().sendLine(line) + @implementer(IRealm) class SimpleRealm: diff --git a/smtp_proxy_server/parse_email.py b/smtp_proxy_server/parse_email.py index d9feabfa..861ab144 100644 --- a/smtp_proxy_server/parse_email.py +++ b/smtp_proxy_server/parse_email.py @@ -3,7 +3,6 @@ import json import logging import email -from email.header import Header from email.message import Message from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText diff --git a/worker/src/mails_api/webhook_settings.ts b/worker/src/mails_api/webhook_settings.ts index 4f1fc59a..50626904 100644 --- a/worker/src/mails_api/webhook_settings.ts +++ b/worker/src/mails_api/webhook_settings.ts @@ -59,7 +59,12 @@ async function sendWebhook(settings: WebhookSettings, formatMap: WebhookMail): P // send webhook let body = settings.body; for (const key of Object.keys(formatMap)) { - body = body.replace(new RegExp(`\\$\\{${key}\\}`, "g"), formatMap[key as keyof WebhookMail]); + body = body.replace( + new RegExp(`\\$\\{${key}\\}`, "g"), + JSON.stringify( + formatMap[key as keyof WebhookMail] + ).replace(/^"(.*)"$/, '\$1') + ); } const response = await fetch(settings.url, { method: settings.method, @@ -95,10 +100,10 @@ export async function trigerWebhook( const res = await sendWebhook(settings, { from: parsedEmail.from.address || "", to: address, - headers: JSON.stringify(parsedEmail.headers, null, 2), - subject: JSON.stringify(parsedEmail.subject) || "", - raw: JSON.stringify(raw_mail), - parsedText: JSON.stringify(parsedEmail.text) || JSON.stringify(parsedEmail.html) || "" + headers: JSON.stringify(parsedEmail.headers), + subject: parsedEmail.subject || "", + raw: raw_mail, + parsedText: parsedEmail.text || parsedEmail.html || "" }); if (!res.success) { console.log(res.message); @@ -107,13 +112,19 @@ export async function trigerWebhook( async function testWebhookSettings(c: Context): Promise { const settings = await c.req.json(); + const { address } = c.get("jwtPayload"); + // random raw email + const raw = await c.env.DB.prepare( + `SELECT raw FROM raw_mails WHERE address = ? ORDER BY RANDOM() LIMIT 1` + ).bind(address).first("raw"); + const parsedEmail = raw ? await PostalMime.parse(raw) : {} as any; const res = await sendWebhook(settings, { - from: "from@test.com", - to: "to@test.com", - headers: "headers", - subject: "test", - raw: "test", - parsedText: "test" + from: parsedEmail?.from?.address || "test@test.com", + to: address, + headers: JSON.stringify(parsedEmail?.headers || { "X-Test": "test" }), + subject: parsedEmail?.subject || "test subject", + raw: raw || "test raw email", + parsedText: parsedEmail?.text || parsedEmail?.html || "test parsed text" }); if (!res.success) { return c.text(res.message || "send webhook error", 400);