From 05be9b81b5af3879ce3bf7d37d8ca5272b64bf86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?So=CC=88nmez=20Kartal?= Date: Fri, 20 Oct 2023 20:55:59 +0300 Subject: [PATCH] feat(core): email relay --- .github/workflows/main-core.yaml | 8 + .github/workflows/next-core.yaml | 8 + .github/workflows/release-core.yaml | 8 + ...-mime-npm-1.0.16-5981a9ed49-adcfd1432a.zip | Bin 0 -> 55247 bytes packages/types/account.ts | 1 + platform/core/.dev.vars.example | 4 + platform/core/package.json | 3 + platform/core/src/index.ts | 12 ++ platform/core/src/relay.ts | 138 ++++++++++++++++++ platform/core/src/types.ts | 4 + platform/core/wrangler.current.toml | 3 + platform/core/wrangler.dev.toml | 3 + platform/core/wrangler.next.toml | 3 + platform/core/wrangler.toml | 3 + yarn.lock | 10 ++ 15 files changed, 208 insertions(+) create mode 100644 .yarn/cache/postal-mime-npm-1.0.16-5981a9ed49-adcfd1432a.zip create mode 100644 platform/core/src/relay.ts diff --git a/.github/workflows/main-core.yaml b/.github/workflows/main-core.yaml index d868789e23..00b9bc0a4f 100644 --- a/.github/workflows/main-core.yaml +++ b/.github/workflows/main-core.yaml @@ -62,6 +62,10 @@ jobs: INTERNAL_DKIM_SELECTOR + INTERNAL_RELAY_DKIM_DOMAIN + INTERNAL_RELAY_DKIM_SELECTOR + SECRET_RELAY_DKIM_PRIVATE_KEY + INTERNAL_GOOGLE_OAUTH_CLIENT_ID SECRET_GOOGLE_OAUTH_CLIENT_SECRET @@ -92,6 +96,10 @@ jobs: INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }} + INTERNAL_RELAY_DKIM_DOMAIN: ${{ secrets.INTERNAL_RELAY_DKIM_DOMAIN }} + INTERNAL_RELAY_DKIM_SELECTOR: ${{ secrets.INTERNAL_RELAY_DKIM_SELECTOR }} + SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }} + INTERNAL_GOOGLE_OAUTH_CLIENT_ID: ${{ vars.INTERNAL_GOOGLE_OAUTH_CLIENT_ID_DEV }} SECRET_GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.SECRET_GOOGLE_OAUTH_CLIENT_SECRET_DEV }} diff --git a/.github/workflows/next-core.yaml b/.github/workflows/next-core.yaml index f35a4b7af1..617ec5442d 100644 --- a/.github/workflows/next-core.yaml +++ b/.github/workflows/next-core.yaml @@ -62,6 +62,10 @@ jobs: INTERNAL_DKIM_SELECTOR + INTERNAL_RELAY_DKIM_DOMAIN + INTERNAL_RELAY_DKIM_SELECTOR + SECRET_RELAY_DKIM_PRIVATE_KEY + INTERNAL_GOOGLE_OAUTH_CLIENT_ID SECRET_GOOGLE_OAUTH_CLIENT_SECRET @@ -92,6 +96,10 @@ jobs: INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }} + INTERNAL_RELAY_DKIM_DOMAIN: ${{ secrets.INTERNAL_RELAY_DKIM_DOMAIN }} + INTERNAL_RELAY_DKIM_SELECTOR: ${{ secrets.INTERNAL_RELAY_DKIM_SELECTOR }} + SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }} + INTERNAL_GOOGLE_OAUTH_CLIENT_ID: ${{ vars.INTERNAL_GOOGLE_OAUTH_CLIENT_ID_TEST }} SECRET_GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.SECRET_GOOGLE_OAUTH_CLIENT_SECRET_TEST }} diff --git a/.github/workflows/release-core.yaml b/.github/workflows/release-core.yaml index 08a8f403b9..6a58b2cfa7 100644 --- a/.github/workflows/release-core.yaml +++ b/.github/workflows/release-core.yaml @@ -61,6 +61,10 @@ jobs: INTERNAL_DKIM_SELECTOR + INTERNAL_RELAY_DKIM_DOMAIN + INTERNAL_RELAY_DKIM_SELECTOR + SECRET_RELAY_DKIM_PRIVATE_KEY + INTERNAL_GOOGLE_OAUTH_CLIENT_ID SECRET_GOOGLE_OAUTH_CLIENT_SECRET @@ -91,6 +95,10 @@ jobs: INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }} + INTERNAL_RELAY_DKIM_DOMAIN: ${{ secrets.INTERNAL_RELAY_DKIM_DOMAIN }} + INTERNAL_RELAY_DKIM_SELECTOR: ${{ secrets.INTERNAL_RELAY_DKIM_SELECTOR }} + SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }} + INTERNAL_GOOGLE_OAUTH_CLIENT_ID: ${{ vars.INTERNAL_GOOGLE_OAUTH_CLIENT_ID_PROD }} SECRET_GOOGLE_OAUTH_CLIENT_SECRET: ${{ secrets.SECRET_GOOGLE_OAUTH_CLIENT_SECRET_PROD }} diff --git a/.yarn/cache/postal-mime-npm-1.0.16-5981a9ed49-adcfd1432a.zip b/.yarn/cache/postal-mime-npm-1.0.16-5981a9ed49-adcfd1432a.zip new file mode 100644 index 0000000000000000000000000000000000000000..8730f51517575996178867f849d2d632937ab03d GIT binary patch literal 55247 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 + readonly rawSize: number + + setReject(reason: string): void + forward(rcptTo: string, headers?: Headers): Promise +} + +interface MailChannelAddress { + name: string + email: string +} + +interface DKIM { + dkim_domain: string + dkim_selector: string + dkim_private_key: string +} + +export default async (message: string, env: Environment) => { + const postalMime = new PostalMime() + const email = await postalMime.parse(message) + + const dkim: DKIM = { + dkim_domain: env.INTERNAL_RELAY_DKIM_DOMAIN, + dkim_selector: env.INTERNAL_RELAY_DKIM_SELECTOR, + dkim_private_key: env.SECRET_RELAY_DKIM_PRIVATE_KEY, + } + + const recipients = new Array
() + .concat(email.to || []) + .concat(email.cc || []) + .filter((recipient) => + recipient.address.endsWith(`@${env.INTERNAL_RELAY_DKIM_DOMAIN}`) + ) + + for (const recipient of recipients) { + const nss = generateHashedIDRef(EmailAccountType.Mask, recipient.address) + const urn = AccountURNSpace.componentizedUrn(nss) + const node = initAccountNodeByName(urn, env.Account) + + const sourceAccountURN = + await node.storage.get('source-account') + if (!sourceAccountURN) continue + + const sourceAccountNode = initAccountNodeByName( + sourceAccountURN, + env.Account + ) + + const name = (await sourceAccountNode.class.getNickname()) || '' + const address = await sourceAccountNode.class.getAddress() + if (!address) continue + + const from: MailChannelAddress = { + name: email.from.name, + email: recipient.address, + } + + const to: MailChannelAddress[] = [ + { + name, + email: address, + }, + ] + + await send(email, from, to, dkim) + } +} + +const send = async ( + email: Email, + from: MailChannelAddress, + to: MailChannelAddress[], + dkim: DKIM +) => { + const { subject } = email + + const content = [] + if (email.text) + content.push({ + type: 'text/plain', + value: email.text, + }) + if (email.html) { + content.push({ + type: 'text/html', + value: email.html, + }) + } + + const personalizations = [ + { + to, + ...dkim, + }, + ] + + const request = new Request('https://api.mailchannels.net/tx/v1/send', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify( + { + from, + subject, + content, + personalizations, + }, + null, + 2 + ), + }) + + const response = await fetch(request) + if (!response.ok) { + const responseBody = await response.text() + try { + console.error( + 'MailChannels', + JSON.stringify(JSON.parse(responseBody), null, 2) + ) + } catch (err) { + console.error('MailChannels', responseBody) + } + } +} diff --git a/platform/core/src/types.ts b/platform/core/src/types.ts index ff9944051b..0725fbbbbd 100644 --- a/platform/core/src/types.ts +++ b/platform/core/src/types.ts @@ -49,6 +49,10 @@ export interface Environment { INTERNAL_DKIM_SELECTOR: string + INTERNAL_RELAY_DKIM_DOMAIN: string + INTERNAL_RELAY_DKIM_SELECTOR: string + SECRET_RELAY_DKIM_PRIVATE_KEY: string + INTERNAL_CLOUDFLARE_ZONE_ID: string TOKEN_CLOUDFLARE_API: string diff --git a/platform/core/wrangler.current.toml b/platform/core/wrangler.current.toml index 21e82bb78f..a83dbaffd5 100644 --- a/platform/core/wrangler.current.toml +++ b/platform/core/wrangler.current.toml @@ -39,6 +39,9 @@ ENVIRONMENT = "current" INTERNAL_PASSPORT_SERVICE_NAME = "passport-current" +INTERNAL_RELAY_DKIM_DOMAIN = "rollup.email" +INTERNAL_RELAY_DKIM_SELECTOR = "mailchannels" + PASSPORT_URL = "https://passport.rollup.id" MINTPFP_CONTRACT_ADDRESS = "0x3ebfaFE60F3Ac34f476B2f696Fc2779ff1B03193" TTL_IN_MS = 300_000 diff --git a/platform/core/wrangler.dev.toml b/platform/core/wrangler.dev.toml index 12f09466f0..062b0a4352 100644 --- a/platform/core/wrangler.dev.toml +++ b/platform/core/wrangler.dev.toml @@ -39,6 +39,9 @@ ENVIRONMENT = "dev" INTERNAL_PASSPORT_SERVICE_NAME = "passport-dev" +INTERNAL_RELAY_DKIM_DOMAIN = "rollup.email" +INTERNAL_RELAY_DKIM_SELECTOR = "mailchannels" + PASSPORT_URL = "https://passport-dev.rollup.id" MINTPFP_CONTRACT_ADDRESS = "0x028aE75Bb01eef2A581172607b93af8D24F50643" TTL_IN_MS = 25_000 diff --git a/platform/core/wrangler.next.toml b/platform/core/wrangler.next.toml index 11268d1682..af356d4a36 100644 --- a/platform/core/wrangler.next.toml +++ b/platform/core/wrangler.next.toml @@ -39,6 +39,9 @@ ENVIRONMENT = "next" INTERNAL_PASSPORT_SERVICE_NAME = "passport-next" +INTERNAL_RELAY_DKIM_DOMAIN = "rollup.email" +INTERNAL_RELAY_DKIM_SELECTOR = "mailchannels" + PASSPORT_URL = "https://passport-next.rollup.id" MINTPFP_CONTRACT_ADDRESS = "0x028aE75Bb01eef2A581172607b93af8D24F50643" TTL_IN_MS = 300_000 diff --git a/platform/core/wrangler.toml b/platform/core/wrangler.toml index 8337428da4..a681b2ea3e 100644 --- a/platform/core/wrangler.toml +++ b/platform/core/wrangler.toml @@ -35,6 +35,9 @@ migrations_dir = "../edges/migrations" [vars] ENVIRONMENT = "local" +INTERNAL_RELAY_DKIM_DOMAIN = "rollup.email" +INTERNAL_RELAY_DKIM_SELECTOR = "mailchannels" + PASSPORT_URL = "http://localhost:10001" MINTPFP_CONTRACT_ADDRESS = "0x028aE75Bb01eef2A581172607b93af8D24F50643" TTL_IN_MS = 25_000 diff --git a/yarn.lock b/yarn.lock index a7b8309f2e..2144de5025 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6543,6 +6543,8 @@ __metadata: "@proofzero/platform.edges": "workspace:*" "@proofzero/platform.identity": "workspace:*" "@proofzero/platform.starbase": "workspace:*" + "@proofzero/types": "workspace:*" + "@proofzero/urns": "workspace:*" "@trpc/server": 10.8.1 "@types/node": 20.3.1 "@typescript-eslint/eslint-plugin": 5.59.11 @@ -6553,6 +6555,7 @@ __metadata: eslint-config-prettier: 8.8.0 jose: 4.14.4 npm-run-all: 4.1.5 + postal-mime: 1.0.16 prettier: 2.8.8 typescript: 5.1.3 wrangler: 3.2.0 @@ -31285,6 +31288,13 @@ __metadata: languageName: node linkType: hard +"postal-mime@npm:1.0.16": + version: 1.0.16 + resolution: "postal-mime@npm:1.0.16" + checksum: adcfd1432add9601ca68d98a4c54c695bcdf6ad723b1c58ced36f18fc1778f20261c6dbd2c4a9a9c972166b590ab60330ec9fa1fc51ed1252148176a92a95b96 + languageName: node + linkType: hard + "postcss-attribute-case-insensitive@npm:^5.0.2": version: 5.0.2 resolution: "postcss-attribute-case-insensitive@npm:5.0.2"