From 2da4ca5da84bb035671685fddf1cd8ee908a495b Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Tue, 17 Jan 2023 17:04:01 +0800 Subject: [PATCH] Add saveReceivedEmail service --- packages/api/src/routers/svc/emails.ts | 21 ++++++++++--------- packages/api/src/services/received_emails.ts | 20 ++++++++++++++++++ .../db/migrations/0107.do.received_emails.sql | 21 ++++++++++++++++++- 3 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 packages/api/src/services/received_emails.ts diff --git a/packages/api/src/routers/svc/emails.ts b/packages/api/src/routers/svc/emails.ts index 5fa138812..6c865224b 100644 --- a/packages/api/src/routers/svc/emails.ts +++ b/packages/api/src/routers/svc/emails.ts @@ -27,6 +27,15 @@ interface ForwardEmailMessage { forwardedFrom?: string } +function isForwardEmailMessage(data: any): data is ForwardEmailMessage { + return ( + 'from' in data && + 'to' in data && + 'subject' in data && + ('html' in data || 'text' in data) + ) +} + const logger = buildLogger('app.dispatch') export function emailsServiceRouter() { @@ -37,7 +46,6 @@ export function emailsServiceRouter() { logger.info('email forward router') const { message, expired } = readPushSubscription(req) - logger.info('pubsub message:', { message, expired }) if (!message) { res.status(400).send('Bad Request') @@ -51,15 +59,8 @@ export function emailsServiceRouter() { } try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const data: ForwardEmailMessage = JSON.parse(message) - - if ( - !('from' in data) || - !('to' in data) || - !('subject' in data) || - (!('html' in data) && !('text' in data)) - ) { + const data = JSON.parse(message) as unknown + if (!isForwardEmailMessage(data)) { logger.error('Invalid message') res.status(400).send('Bad Request') return diff --git a/packages/api/src/services/received_emails.ts b/packages/api/src/services/received_emails.ts new file mode 100644 index 000000000..272c8ff26 --- /dev/null +++ b/packages/api/src/services/received_emails.ts @@ -0,0 +1,20 @@ +import { ReceivedEmail } from '../entity/received_email' +import { getRepository } from '../entity/utils' + +export const saveReceivedEmail = async ( + from: string, + to: string, + subject: string, + text: string, + html: string, + userId: string +): Promise => { + return getRepository(ReceivedEmail).save({ + from, + to, + subject, + text, + html, + user: { id: userId }, + }) +} diff --git a/packages/db/migrations/0107.do.received_emails.sql b/packages/db/migrations/0107.do.received_emails.sql index 887e0e406..e87966bd9 100755 --- a/packages/db/migrations/0107.do.received_emails.sql +++ b/packages/db/migrations/0107.do.received_emails.sql @@ -19,6 +19,25 @@ CREATE TABLE omnivore.received_emails ( CREATE TRIGGER received_emails_modtime BEFORE UPDATE ON omnivore.received_emails FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column(); -GRANT SELECT, INSERT, UPDATE ON omnivore.received_emails TO omnivore_user; +GRANT SELECT, INSERT, UPDATE, DELETE ON omnivore.received_emails TO omnivore_user; + +-- Create a trigger to keep the most recent 20 emails for each user +CREATE OR REPLACE FUNCTION omnivore.delete_old_received_emails() + RETURNS trigger AS $$ + BEGIN + DELETE FROM omnivore.received_emails + WHERE id NOT IN ( + SELECT id FROM omnivore.received_emails + WHERE user_id = NEW.user_id + ORDER BY created_at DESC + LIMIT 20 + ); + RETURN NEW; + END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER delete_old_received_emails + AFTER INSERT ON omnivore.received_emails + FOR EACH ROW EXECUTE PROCEDURE omnivore.delete_old_received_emails(); COMMIT;