Add support to the case when from address is in Name <address> format

This commit is contained in:
Hongbo Wu
2022-07-28 10:26:15 +08:00
parent 0bdab51bbd
commit c99c1db57e
7 changed files with 39 additions and 22 deletions

View File

@ -13,6 +13,7 @@ import {
getTitleFromEmailSubject,
isProbablyArticle,
isProbablyNewsletter,
parseEmailAddress,
} from '../../utils/parser'
import { saveNewsletterEmail } from '../../services/save_newsletter_email'
import { saveEmail } from '../../services/save_email'
@ -75,6 +76,7 @@ export function emailsServiceRouter() {
}
const user = newsletterEmail.user
const ctx = { pubsub: createPubSubClient(), uid: user.id }
const parsedFrom = parseEmailAddress(data.from)
if (await isProbablyNewsletter(data.html)) {
logger.info('handling as newsletter', data)
@ -83,7 +85,7 @@ export function emailsServiceRouter() {
email: data.to,
title: data.subject,
content: data.html,
author: data.from,
author: parsedFrom.name,
url: (await findNewsletterUrl(data.html)) || generateUniqueUrl(),
unsubMailTo: data.unsubMailTo,
unsubHttpUrl: data.unsubHttpUrl,
@ -95,11 +97,11 @@ export function emailsServiceRouter() {
return
}
if (await isProbablyArticle(data.from, data.subject)) {
if (await isProbablyArticle(parsedFrom.address, data.subject)) {
logger.info('handling as article', data)
await saveEmail(ctx, {
title: getTitleFromEmailSubject(data.subject),
author: data.from,
author: parsedFrom.name,
url: generateUniqueUrl(),
originalContent: data.html,
})

View File

@ -19,6 +19,7 @@ import { getRepository } from '../entity/utils'
import { User } from '../entity/user'
import { ILike } from 'typeorm'
import { v4 as uuid } from 'uuid'
import addressparser from 'addressparser'
const logger = buildLogger('utils.parse')
@ -567,3 +568,14 @@ export const getTitleFromEmailSubject = (subject: string) => {
const title = subject.replace(ARTICLE_PREFIX, '')
return title.trim()
}
export const parseEmailAddress = (from: string): addressparser.EmailAddress => {
// get author name from email
// e.g. 'Jackson Harper from Omnivore App <jacksonh@substack.com>'
// or 'Mike Allen <mike@axios.com>'
const parsed = addressparser(from)
if (parsed.length > 0) {
return parsed[0]
}
return { name: from, address: from }
}

View File

@ -64,7 +64,7 @@ export const deleteTestUser = async (name: string) => {
await AppDataSource.createQueryBuilder()
.delete()
.from(User)
.where({ email: `${name}@fake.com` })
.where({ email: `${name}@omnivore.app` })
.execute()
}
@ -77,7 +77,7 @@ export const createTestUser = async (
const [newUser] = await createUser({
provider: 'GOOGLE',
sourceUserId: 'fake-user-id-' + name,
email: `${name}@fake.com`,
email: `${name}@omnivore.app`,
username: name,
bio: `i am ${name}`,
name: name,
@ -93,7 +93,7 @@ export const createUserWithoutProfile = async (name: string): Promise<User> => {
return getRepository(User).save({
source: 'GOOGLE',
sourceUserId: 'fake-user-id-' + name,
email: `${name}@fake.com`,
email: `${name}@omnivore.app`,
name: name,
})
}

View File

@ -28,11 +28,11 @@ describe('Newsletters API', () => {
// create test newsletter emails
const newsletterEmail1 = await createTestNewsletterEmail(
user,
'Test_email_address_1@fake-email.com'
'Test_email_address_1@omnivore.app'
)
const newsletterEmail2 = await createTestNewsletterEmail(
user,
'Test_email_address_2@fake-email.com'
'Test_email_address_2@omnivore.app'
)
newsletterEmails = [newsletterEmail1, newsletterEmail2]
})

View File

@ -47,7 +47,7 @@ describe('auth router', () => {
before(() => {
password = validPassword
username = 'Some_username'
email = `${username}@fake.com`
email = `${username}@omnivore.app`
name = 'Some name'
})
@ -397,9 +397,7 @@ describe('auth router', () => {
it('redirects to forgot-password page with success message', async () => {
const res = await emailResetPasswordReq(email).expect(302)
expect(res.header.location).to.endWith(
'/auth/reset-sent'
)
expect(res.header.location).to.endWith('/auth/reset-sent')
})
})
@ -434,9 +432,7 @@ describe('auth router', () => {
it('redirects to email-login page with error code PENDING_VERIFICATION', async () => {
const res = await emailResetPasswordReq(email).expect(302)
expect(res.header.location).to.endWith(
'/auth/reset-sent'
)
expect(res.header.location).to.endWith('/auth/reset-sent')
})
})
})
@ -448,9 +444,7 @@ describe('auth router', () => {
it('redirects to forgot-password page with error code USER_NOT_FOUND', async () => {
const res = await emailResetPasswordReq(email).expect(302)
expect(res.header.location).to.endWith(
'/auth/reset-sent'
)
expect(res.header.location).to.endWith('/auth/reset-sent')
})
})
})
@ -501,9 +495,7 @@ describe('auth router', () => {
const res = await resetPasswordRequest(token, 'new_password').expect(
302
)
expect(res.header.location).to.contain(
'/api/client/auth?tok'
)
expect(res.header.location).to.contain('/api/client/auth?tok')
})
it('resets password', async () => {

View File

@ -12,7 +12,7 @@ import { getPageById } from '../../src/elastic/pages'
describe('PDF attachments Router', () => {
const username = 'fakeUser'
const newsletterEmail = 'fakeEmail@fake-email.com'
const newsletterEmail = 'fakeEmail@omnivore.app'
let user: User
let authToken: string

View File

@ -9,6 +9,7 @@ import {
getTitleFromEmailSubject,
isProbablyArticle,
isProbablyNewsletter,
parseEmailAddress,
parsePageMetadata,
parsePreparedContent,
} from '../../src/utils/parser'
@ -179,3 +180,13 @@ describe('getTitleFromEmailSubject', () => {
expect(getTitleFromEmailSubject(subject)).to.eql(title)
})
})
describe('parseEmailAddress', () => {
const email = 'Tester <tester@omnivore.app>'
it('returns the name and address', () => {
const { name, address } = parseEmailAddress(email)
expect(name).to.eql('Tester')
expect(address).to.eql('tester@omnivore.app')
})
})