From 084c4afdc37eff43b8995ac11ebb4df2988ab3bf Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Thu, 1 Jul 2021 20:12:17 +1000 Subject: [PATCH] Update email code to send an email per EditUserCell using multiple recipients is break of privacy since user will be able to see each other's emails. --- app/api/src/graphql/email.sdl.ts | 2 -- app/api/src/lib/sendmail.ts | 6 ++-- app/api/src/services/email/email.ts | 29 +++++++++++++++---- .../src/components/AdminParts/AdminParts.js | 2 +- .../AdminPartsCell/AdminPartsCell.js | 2 +- .../components/EditUserCell/EditUserCell.js | 2 +- .../src/components/IdePartCell/IdePartCell.js | 2 +- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app/api/src/graphql/email.sdl.ts b/app/api/src/graphql/email.sdl.ts index 81ae8fa..64607ef 100644 --- a/app/api/src/graphql/email.sdl.ts +++ b/app/api/src/graphql/email.sdl.ts @@ -7,8 +7,6 @@ export const schema = gql` type EmailResponse { accepted: [String!]! rejected: [String!]! - messageId: String! - envelope: Envelope } input Email { diff --git a/app/api/src/lib/sendmail.ts b/app/api/src/lib/sendmail.ts index a524fdb..aa365fa 100644 --- a/app/api/src/lib/sendmail.ts +++ b/app/api/src/lib/sendmail.ts @@ -1,7 +1,7 @@ import nodemailer, { SendMailOptions } from 'nodemailer' -interface Args { - to: SendMailOptions['to'] +export interface SendMailArgs { + to: string from: SendMailOptions['from'] subject: string text: string @@ -26,7 +26,7 @@ export function sendMail({ from, subject, text, -}: Args): Promise { +}: SendMailArgs): Promise { const transporter = nodemailer.createTransport({ host: 'smtp.mailgun.org', port: 587, diff --git a/app/api/src/services/email/email.ts b/app/api/src/services/email/email.ts index 0d237fb..1463571 100644 --- a/app/api/src/services/email/email.ts +++ b/app/api/src/services/email/email.ts @@ -1,26 +1,45 @@ import { requireAuth } from 'src/lib/auth' import { sendMail } from 'src/lib/sendmail' +import type { SendMailArgs } from 'src/lib/sendmail' import { users } from 'src/services/users/users' export const sendAllUsersEmail = async ({ input: { body, subject } }) => { requireAuth({ role: 'admin' }) - const recipients = (await users()).map(({ email }) => email) const from = { address: 'news@mail.cadhub.xyz', name: 'CadHub', } - const result = await sendMail({ - to: recipients, + const emails: SendMailArgs[] = (await users()).map(({ email }) => ({ + to: email, from, subject, text: body, + })) + const emailPromises = emails.map((email) => sendMail(email)) + const accepted = [] + const rejected = [] + const result = await Promise.allSettled(emailPromises) + result.forEach((result) => { + if (result.status === 'fulfilled') { + accepted.push(result.value.accepted[0]) + } else { + rejected.push(result.reason) + } }) await sendMail({ to: 'k.hutten@protonmail.ch', from, subject: `All users email report`, - text: JSON.stringify(result, null, 2), + text: JSON.stringify( + { + accepted, + rejected, + originalEmailList: emails, + }, + null, + 2 + ), }) - return result + return { accepted, rejected } } diff --git a/app/web/src/components/AdminParts/AdminParts.js b/app/web/src/components/AdminParts/AdminParts.js index 06ea1b8..89a281f 100644 --- a/app/web/src/components/AdminParts/AdminParts.js +++ b/app/web/src/components/AdminParts/AdminParts.js @@ -5,7 +5,7 @@ import { Link, routes } from '@redwoodjs/router' import { QUERY } from 'src/components/AdminPartsCell' const DELETE_PART_MUTATION = gql` - mutation DeletePartMutation($id: String!) { + mutation DeletePartMutationAdmin($id: String!) { deletePart(id: $id) { id } diff --git a/app/web/src/components/AdminPartsCell/AdminPartsCell.js b/app/web/src/components/AdminPartsCell/AdminPartsCell.js index a401087..4b4d55f 100644 --- a/app/web/src/components/AdminPartsCell/AdminPartsCell.js +++ b/app/web/src/components/AdminPartsCell/AdminPartsCell.js @@ -3,7 +3,7 @@ import { Link, routes } from '@redwoodjs/router' import AdminParts from 'src/components/AdminParts' export const QUERY = gql` - query PARTS { + query PARTS_ADMIN { parts { id title diff --git a/app/web/src/components/EditUserCell/EditUserCell.js b/app/web/src/components/EditUserCell/EditUserCell.js index ae328eb..676811e 100644 --- a/app/web/src/components/EditUserCell/EditUserCell.js +++ b/app/web/src/components/EditUserCell/EditUserCell.js @@ -5,7 +5,7 @@ import { navigate, routes } from '@redwoodjs/router' import UserProfile from 'src/components/UserProfile' export const QUERY = gql` - query FIND_USER_BY_ID($userName: String!) { + query FIND_USER_BY_USERNAME($userName: String!) { user: userName(userName: $userName) { id userName diff --git a/app/web/src/components/IdePartCell/IdePartCell.js b/app/web/src/components/IdePartCell/IdePartCell.js index 1b2c7d1..aac04ea 100644 --- a/app/web/src/components/IdePartCell/IdePartCell.js +++ b/app/web/src/components/IdePartCell/IdePartCell.js @@ -24,7 +24,7 @@ export const QUERY = gql` ` const UPDATE_PART_MUTATION = gql` - mutation UpdatePartMutation($id: String!, $input: UpdatePartInput!) { + mutation UpdatePartMutationIde($id: String!, $input: UpdatePartInput!) { updatePart(id: $id, input: $input) { id }