Skip to content

Commit

Permalink
chore(platform): Extract relay into separate services (#2823)
Browse files Browse the repository at this point in the history
* Split relay into multiple services - no GHA workflows yet

* lint errors

* Fixes and GHA workflows

* Corrects old masked email pattern

* Error, check utils, source account retrieval tweaks and worker renames

* Add missing lock file from renames in prev commit

* Cleanup of types and added eslint

* yarn :/

* More eslint

* Rename workflow and env vars from relay to email.
  • Loading branch information
betimshahini committed Jan 28, 2024
1 parent d7fb632 commit 5ca7b8c
Show file tree
Hide file tree
Showing 43 changed files with 964 additions and 96 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/main-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
SECRET_JWKS
INTERNAL_DKIM_SELECTOR
INTERNAL_EMAIL_DISTRIBUTION_KEY
SECRET_RELAY_DKIM_PRIVATE_KEY
INTERNAL_GOOGLE_OAUTH_CLIENT_ID
Expand Down Expand Up @@ -94,6 +94,7 @@ jobs:

INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }}

INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_DEV}}
SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }}

INTERNAL_GOOGLE_OAUTH_CLIENT_ID: ${{ vars.INTERNAL_GOOGLE_OAUTH_CLIENT_ID_DEV }}
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/main-emaildistributor.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Singleton Email distributor

on:
push:
branches:
- main

defaults:
run:
working-directory: platform/emaildistributor

jobs:
deploy:
runs-on: ubuntu-latest
environment: dev
steps:
- uses: actions/checkout@v3

- uses: cachix/install-nix-action@v18
with:
nix_path: nixpkgs=channel:nixos-unstable

- run: nix-build ../platform.nix

- name: Cache Dependencies
id: cache-modules
uses: actions/cache@v3
with:
path: |
node_modules
.yarn
key: ${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }}

- name: Install Dependencies
run: yarn install

- name: Test
run: yarn run test

- name: Deploy
uses: cloudflare/wrangler-action@2.0.0
with:
wranglerVersion: '3.19.0'
apiToken: ${{ secrets.TOKEN_CLOUDFLARE_API }}
accountId: ${{ secrets.INTERNAL_CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: platform/emaildistributor
command: publish
secrets: |
SECRET_EMAIL_DISTRIBUTION_MAP
env:
SECRET_EMAIL_DISTRIBUTION_MAP: ${{ secrets.SECRET_EMAIL_DISTRIBUTION_MAP }}
53 changes: 53 additions & 0 deletions .github/workflows/main-emailinbounder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Mail Email inbounder

on:
push:
branches:
- main

defaults:
run:
working-directory: platform/emailinbounder

jobs:
deploy:
runs-on: ubuntu-latest
environment: dev
steps:
- uses: actions/checkout@v3

- uses: cachix/install-nix-action@v18
with:
nix_path: nixpkgs=channel:nixos-unstable

- run: nix-build ../platform.nix

- name: Cache Dependencies
id: cache-modules
uses: actions/cache@v3
with:
path: |
node_modules
.yarn
key: ${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }}

- name: Install Dependencies
run: yarn install

- name: Test
run: yarn run test

- name: Deploy
uses: cloudflare/wrangler-action@2.0.0
with:
wranglerVersion: '3.19.0'
apiToken: ${{ secrets.TOKEN_CLOUDFLARE_API }}
accountId: ${{ secrets.INTERNAL_CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: platform/emailinbounder
command: publish
secrets: |
SECRET_EMAIL_DISTRIBUTION_MAP
INTERNAL_EMAIL_DISTRIBUTION_KEY
env:
SECRET_EMAIL_DISTRIBUTION_MAP: ${{ secrets.SECRET_EMAIL_DISTRIBUTION_MAP }}
INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_DEV }}
3 changes: 2 additions & 1 deletion .github/workflows/next-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
SECRET_JWKS
INTERNAL_DKIM_SELECTOR
INTERNAL_EMAIL_DISTRIBUTION_KEY
SECRET_RELAY_DKIM_PRIVATE_KEY
INTERNAL_GOOGLE_OAUTH_CLIENT_ID
Expand Down Expand Up @@ -93,6 +93,7 @@ jobs:
SECRET_JWKS: ${{ secrets.SECRET_JWKS_TEST }}

INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }}
INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_TEST }}

SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }}

Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/next-emailinbounder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Next Email inbounder

on:
push:
tags:
- '*'

defaults:
run:
working-directory: platform/emailinbounder

jobs:
deploy:
runs-on: ubuntu-latest
environment: next
steps:
- uses: actions/checkout@v3

- uses: cachix/install-nix-action@v18
with:
nix_path: nixpkgs=channel:nixos-unstable

- run: nix-build ../platform.nix

- name: Cache Dependencies
id: cache-modules
uses: actions/cache@v3
with:
path: |
node_modules
.yarn
key: ${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }}

- name: Install Dependencies
run: yarn install

- name: Test
run: yarn run test

- name: Deploy
uses: cloudflare/wrangler-action@2.0.0
with:
wranglerVersion: '3.19.0'
apiToken: ${{ secrets.TOKEN_CLOUDFLARE_API }}
accountId: ${{ secrets.INTERNAL_CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: platform/emailinbounder
command: publish --config wrangler.next.toml --env next
environment: 'next'
secrets: |
SECRET_EMAIL_DISTRIBUTION_MAP
INTERNAL_EMAIL_DISTRIBUTION_KEY
env:
SECRET_EMAIL_DISTRIBUTION_MAP: ${{ secrets.SECRET_EMAIL_DISTRIBUTION_MAP }}
INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_TEST }}
3 changes: 2 additions & 1 deletion .github/workflows/release-core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
SECRET_JWKS
INTERNAL_DKIM_SELECTOR
INTERNAL_EMAIL_DISTRIBUTION_KEY
SECRET_RELAY_DKIM_PRIVATE_KEY
INTERNAL_GOOGLE_OAUTH_CLIENT_ID
Expand Down Expand Up @@ -92,6 +92,7 @@ jobs:
SECRET_JWKS: ${{ secrets.SECRET_JWKS_PROD }}

INTERNAL_DKIM_SELECTOR: ${{ secrets.INTERNAL_DKIM_SELECTOR }}
INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_PROD }}

SECRET_RELAY_DKIM_PRIVATE_KEY: ${{ secrets.SECRET_RELAY_DKIM_PRIVATE_KEY }}

Expand Down
54 changes: 54 additions & 0 deletions .github/workflows/release-emailinbounder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Release Email inbounder

on:
release:
types: [published]

defaults:
run:
working-directory: platform/emailinbounder

jobs:
deploy:
runs-on: ubuntu-latest
environment: prod
steps:
- uses: actions/checkout@v3

- uses: cachix/install-nix-action@v18
with:
nix_path: nixpkgs=channel:nixos-unstable

- run: nix-build ../platform.nix

- name: Cache Dependencies
id: cache-modules
uses: actions/cache@v3
with:
path: |
node_modules
.yarn
key: ${{ runner.os }}-node_modules-${{ hashFiles('yarn.lock') }}

- name: Install Dependencies
run: yarn install

- name: Test
run: yarn run test

- name: Deploy
uses: cloudflare/wrangler-action@2.0.0
with:
wranglerVersion: '3.19.0'
apiToken: ${{ secrets.TOKEN_CLOUDFLARE_API }}
accountId: ${{ secrets.INTERNAL_CLOUDFLARE_ACCOUNT_ID }}
workingDirectory: platform/emailinbounder
command: publish --config wrangler.current.toml --env current
environment: 'current'
secrets: |
SECRET_EMAIL_DISTRIBUTION_MAP
INTERNAL_EMAIL_DISTRIBUTION_KEY
env:
SECRET_EMAIL_DISTRIBUTION_MAP: ${{ secrets.SECRET_EMAIL_DISTRIBUTION_MAP }}
INTERNAL_EMAIL_DISTRIBUTION_KEY: ${{secrets.INTERNAL_EMAIL_DISTRIBUTION_KEY_PROD }}
Binary file not shown.
12 changes: 12 additions & 0 deletions packages/types/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,15 @@ export enum ReconciliationNotificationType {
Billing = 'BILLING',
Dev = 'DEV',
}

/** CF EmailMessage type; not provided in CF types lib */
export interface CloudflareEmailMessage {
readonly from: string
readonly to: string
readonly headers: Headers
readonly raw: ReadableStream
readonly rawSize: number

setReject(reason: string): void
forward(rcptTo: string, headers?: Headers): Promise<void>
}
6 changes: 5 additions & 1 deletion platform/account/src/jsonrpc/methods/getMaskedAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,9 @@ export const getMaskedAddressMethod: GetMaskedAddressMethod = async ({
}

const node = new EmailAccount(ctx.account, ctx.env)
return node.getMaskedAddress(input.clientId)
return node.getMaskedAddress(
input.clientId,
ctx.env.INTERNAL_EMAIL_DISTRIBUTION_KEY,
ctx.env.INTERNAL_RELAY_DKIM_DOMAIN
)
}
63 changes: 63 additions & 0 deletions platform/account/src/jsonrpc/methods/getSourceFromMaskedAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { z } from 'zod'
import { router } from '@proofzero/platform.core'
import { EDGE_ACCOUNT } from '@proofzero/platform.account/src/constants'
import { Context } from '../../context'
import { EmailAccountType } from '@proofzero/types/account'
import { AccountURN, AccountURNSpace } from '@proofzero/urns/account'
import {
BadRequestError,
InternalServerError,
NotFoundError,
} from '@proofzero/errors'
import { generateHashedIDRef } from '@proofzero/packages/urns/idref'
import { EmailAccount, initAccountNodeByName } from '../../nodes'

export const GetSourceByMaskedAddressInput = z.object({
maskedEmail: z.string(),
})

export const GetSourceByMaskedAddressOutput = z.object({
nickname: z.string(),
sourceEmail: z.string(),
})

type GetSourceByMaskedAddressParams = z.infer<
typeof GetSourceByMaskedAddressInput
>
type GetSourceByMaskedAddressResult = z.infer<
typeof GetSourceByMaskedAddressOutput
>

export const getSourceFromMaskedAddressMethod = async ({
input,
ctx,
}: {
input: GetSourceByMaskedAddressParams
ctx: Context
}): Promise<GetSourceByMaskedAddressResult> => {
const nss = generateHashedIDRef(EmailAccountType.Mask, input.maskedEmail)
const urn = AccountURNSpace.componentizedUrn(nss)
const node = initAccountNodeByName(urn, ctx.env.Account)

const emailNode = new EmailAccount(node, ctx.env)
const sourceAccountURN = await emailNode.getSourceAccount()
if (!sourceAccountURN)
throw new NotFoundError({
message: `Could not find hidden address ${input.maskedEmail}`,
})

const sourceAccountNode = initAccountNodeByName(
sourceAccountURN,
ctx.env.Account
)

const name = (await sourceAccountNode.class.getNickname()) || ''
const address = await sourceAccountNode.class.getAddress()

if (!address)
throw new InternalServerError({
message: `Could not find source address for masked email ${input.maskedEmail}`,
})

return { sourceEmail: address, nickname: name }
}
11 changes: 11 additions & 0 deletions platform/account/src/jsonrpc/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ import {
SetSourceAccountInput,
SetSourceAccountOutput,
} from './methods/setSourceAccount'
import {
GetSourceByMaskedAddressInput,
GetSourceByMaskedAddressOutput,
getSourceFromMaskedAddressMethod,
} from './methods/getSourceFromMaskedAddress'

const t = initTRPC.context<Context>().create({ errorFormatter })

Expand Down Expand Up @@ -403,4 +408,10 @@ export const appRouter = t.router({
.input(SetSourceAccountInput)
.output(SetSourceAccountOutput)
.mutation(setSourceAccountMethod),
getSourceFromMaskedAddress: t.procedure
.use(LogUsage)
.use(Analytics)
.input(GetSourceByMaskedAddressInput)
.output(GetSourceByMaskedAddressOutput)
.query(getSourceFromMaskedAddressMethod),
})
Loading

0 comments on commit 5ca7b8c

Please sign in to comment.