diff --git a/packages/api/src/resolvers/recent_emails/index.ts b/packages/api/src/resolvers/recent_emails/index.ts index b3c28e8aa..ef4955ec0 100644 --- a/packages/api/src/resolvers/recent_emails/index.ts +++ b/packages/api/src/resolvers/recent_emails/index.ts @@ -115,6 +115,14 @@ export const markEmailAsItemResolver = authorized< }, newsletterEmail ) + if (!success) { + log.info('newsletter not created', recentEmail.id) + + return { + errorCodes: [MarkEmailAsItemErrorCode.BadRequest], + } + } + // update received email type await updateReceivedEmail(recentEmail.id, 'article') diff --git a/packages/api/src/routers/svc/newsletters.ts b/packages/api/src/routers/svc/newsletters.ts index 861ba3d69..537293690 100644 --- a/packages/api/src/routers/svc/newsletters.ts +++ b/packages/api/src/routers/svc/newsletters.ts @@ -3,6 +3,7 @@ import { createPubSubClient, readPushSubscription, } from '../../datalayer/pubsub' +import { SubscriptionStatus } from '../../generated/graphql' import { getNewsletterEmail, updateConfirmationCode, @@ -13,6 +14,7 @@ import { saveNewsletterEmail, } from '../../services/save_newsletter_email' import { saveUrlFromEmail } from '../../services/save_url' +import { getSubscriptionByNameAndUserId } from '../../services/subscriptions' import { isUrl } from '../../utils/helpers' interface SetConfirmationCodeMessage { @@ -128,6 +130,16 @@ export function newsletterServiceRouter() { return res.status(500).send('Error saving url from email') } } else { + // do not subscribe if subscription already exists and is unsubscribed + const existingSubscription = await getSubscriptionByNameAndUserId( + data.author, + newsletterEmail.user.id + ) + if (existingSubscription?.status === SubscriptionStatus.Unsubscribed) { + console.log('newsletter already unsubscribed:', data.author) + return res.status(200).send('newsletter already unsubscribed') + } + // save newsletter instead const result = await saveNewsletterEmail(data, newsletterEmail, saveCtx) if (!result) { diff --git a/packages/api/src/services/save_newsletter_email.ts b/packages/api/src/services/save_newsletter_email.ts index 2befa5cde..b8e6ee8bf 100644 --- a/packages/api/src/services/save_newsletter_email.ts +++ b/packages/api/src/services/save_newsletter_email.ts @@ -67,27 +67,24 @@ export const saveNewsletterEmail = async ( return false } - if (!page.siteIcon || isBase64Image(page.siteIcon)) { + let icon = page.siteIcon + if (!icon || isBase64Image(icon)) { // fetch favicon if not already set or is a base64 image - const favicon = await fetchFavicon(page.url) - if (favicon) { - page.siteIcon = favicon - await updatePage(page.id, { siteIcon: favicon }, saveCtx) + icon = await fetchFavicon(page.url) + if (icon) { + await updatePage(page.id, { siteIcon: icon }, saveCtx) } } - // creates or updates subscription only if their is a valid unsubscribe link - if (data.unsubMailTo || data.unsubHttpUrl) { - const subscriptionId = await saveSubscription({ - userId: newsletterEmail.user.id, - name: data.author, - newsletterEmail, - unsubscribeMailTo: data.unsubMailTo, - unsubscribeHttpUrl: data.unsubHttpUrl, - icon: page.siteIcon, - }) - console.log('subscription saved', subscriptionId) - } + const subscriptionId = await saveSubscription({ + userId: newsletterEmail.user.id, + name: data.author, + newsletterEmail, + unsubscribeMailTo: data.unsubMailTo, + unsubscribeHttpUrl: data.unsubHttpUrl, + icon, + }) + console.log('subscription saved', subscriptionId) // adds newsletters label to page const result = await addLabelToPage(saveCtx, page.id, { diff --git a/packages/api/src/services/subscriptions.ts b/packages/api/src/services/subscriptions.ts index 794dd8404..d00d19f6c 100644 --- a/packages/api/src/services/subscriptions.ts +++ b/packages/api/src/services/subscriptions.ts @@ -78,6 +78,16 @@ const sendUnsubscribeHttpRequest = async (url: string): Promise => { } } +export const getSubscriptionByNameAndUserId = async ( + name: string, + userId: string +): Promise => { + return getRepository(Subscription).findOneBy({ + name, + user: { id: userId }, + }) +} + export const saveSubscription = async ({ userId, name,