From b891e547c910847d3f7778429cefbd2287276621 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 24 Apr 2023 21:03:39 +0800 Subject: [PATCH 1/2] Make content optional --- packages/api/src/routers/svc/newsletters.ts | 23 +++++++++++-------- .../api/src/services/save_newsletter_email.ts | 9 ++++++-- packages/inbound-email-handler/src/index.ts | 4 +--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/api/src/routers/svc/newsletters.ts b/packages/api/src/routers/svc/newsletters.ts index cc67a935a..861ba3d69 100644 --- a/packages/api/src/routers/svc/newsletters.ts +++ b/packages/api/src/routers/svc/newsletters.ts @@ -20,6 +20,16 @@ interface SetConfirmationCodeMessage { confirmationCode: string } +const isNewsletterMessage = (data: any): data is NewsletterMessage => { + return ( + 'email' in data && + 'title' in data && + 'author' in data && + 'url' in data && + 'receivedEmailId' in data + ) +} + export function newsletterServiceRouter() { const router = express.Router() @@ -90,17 +100,10 @@ export function newsletterServiceRouter() { } try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const data = JSON.parse(message) as NewsletterMessage - if ( - !('email' in data) || - !('content' in data) || - !('title' in data) || - !('author' in data) - ) { + const data = JSON.parse(message) as unknown + if (!isNewsletterMessage(data)) { console.log('invalid newsletter message', data) - res.status(400).send('Bad Request') - return + return res.status(400).send('Bad Request') } // get user from newsletter email diff --git a/packages/api/src/services/save_newsletter_email.ts b/packages/api/src/services/save_newsletter_email.ts index fd558ae14..2befa5cde 100644 --- a/packages/api/src/services/save_newsletter_email.ts +++ b/packages/api/src/services/save_newsletter_email.ts @@ -14,12 +14,12 @@ import { SaveContext, saveEmail, SaveEmailInput } from './save_email' import { saveSubscription } from './subscriptions' export interface NewsletterMessage { - from: string email: string - content: string url: string title: string author: string + content?: string + from?: string unsubMailTo?: string unsubHttpUrl?: string receivedEmailId: string @@ -43,6 +43,11 @@ export const saveNewsletterEmail = async ( }, }) + if (!data.content) { + console.log('newsletter not created, no content:', data.email) + return false + } + const saveCtx = ctx || { pubsub: createPubSubClient(), uid: newsletterEmail.user.id, diff --git a/packages/inbound-email-handler/src/index.ts b/packages/inbound-email-handler/src/index.ts index 4ecf6fb57..1555b41de 100644 --- a/packages/inbound-email-handler/src/index.ts +++ b/packages/inbound-email-handler/src/index.ts @@ -175,14 +175,12 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction( await pubsub.topic(NEWSLETTER_EMAIL_RECEIVED_TOPIC).publishMessage({ json: { email: to, - content: html, + content: html || text, // html is preferred url: generateUniqueUrl(), title: subject, author: parseAuthor(from), - text, unsubMailTo: unsubscribe?.mailTo, unsubHttpUrl: unsubscribe?.httpUrl, - forwardedFrom, receivedEmailId, ...newsletterMessage, }, From 3841734debf7d2bb9a1e3983d0cde8f5d4afba18 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 24 Apr 2023 21:16:44 +0800 Subject: [PATCH 2/2] Fix forwarded email subject being treated as an URL, for example "Fwd: subject" --- packages/api/src/utils/helpers.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/api/src/utils/helpers.ts b/packages/api/src/utils/helpers.ts index 0f0861c99..f65994d21 100644 --- a/packages/api/src/utils/helpers.ts +++ b/packages/api/src/utils/helpers.ts @@ -18,6 +18,7 @@ import { } from '../generated/graphql' import { CreateArticlesSuccessPartial } from '../resolvers' import { Claims, WithDataSourcesContext } from '../resolvers/types' +import { validateUrl } from '../services/create_page_save_request' import { Merge } from '../util' interface InputObject { @@ -292,9 +293,10 @@ export const unescapeHtml = (html: string): string => { export const isUrl = (str: string): boolean => { try { - new URL(str) + validateUrl(str) return true } catch { + console.log('not an url', str) return false } }