1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-09 07:25:19 +02:00

noop if no provider or api key

This commit is contained in:
Tyler Myracle 2024-01-20 14:41:41 -06:00
parent 118b2d037e
commit f712d939a4
9 changed files with 41 additions and 27 deletions

View file

@ -44,11 +44,13 @@ NX_TELLER_ENV=sandbox
# EMAIL
########################################################################
# We use Postmark for transactional emails. You can sign up for a free account
# We currently support Postmark for transactional emails. You can sign up for a free account
# and get a free API key at https://postmarkapp.com
NX_POSTMARK_FROM_ADDRESS=account@example.com
NX_POSTMARK_REPLY_TO_ADDRESS=support@example.com
NX_POSTMARK_API_TOKEN=
NX_EMAIL_FROM_ADDRESS=account@example.com
NX_EMAIL_REPLY_TO_ADDRESS=support@example.com
NX_EMAIL_PROVIDER=
NX_EMAIL_PROVIDER_API_TOKEN=
########################################################################

View file

@ -37,7 +37,7 @@ And dozens upon dozens of smaller features.
This is the current state of building the app. We're actively working to make this process much more streamlined!
*You'll need Docker installed to run the app locally.*
_You'll need Docker installed to run the app locally._
[Docker Desktop](https://www.docker.com/products/docker-desktop/) is an easy way to get started.
First, copy the `.env.example` file to `.env`:
@ -48,7 +48,7 @@ cp .env.example .env
Then, create a new secret using `openssl rand -base64 32` and populate `NEXTAUTH_SECRET` in your `.env` file with it.
To enable transactional emails, you'll need to create a [Postmark](https://postmarkapp.com/) account and add your API key to your `.env` file (`NX_POSTMARK_API_TOKEN`). You can also set the from and reply-to email addresses (`NX_POSTMARK_FROM_ADDRESS` and `NX_POSTMARK_REPLY_TO_ADDRESS`). If you want to run the app without email, you can set `NX_POSTMARK_API_TOKEN` to a dummy value.
To enable transactional emails, you'll need to create a [Postmark](https://postmarkapp.com/) account and add your API key to your `.env` file (`NX_EMAIL_PROVIDER_API_TOKEN`) and set `NX_EMAIL_PROVIDER` to `postmark`. You can also set the from and reply-to email addresses (`NX_EMAIL_FROM_ADDRESS` and `NX_EMAIL_REPLY_TO_ADDRESS`). If you want to run the app without email, you can set `NX_EMAIL_PROVIDER_API_TOKEN` to a dummy value.
Maybe uses [Teller](https://teller.io/) for connecting financial accounts. To get started with Teller, you'll need to create an account. Once you've created an account:

View file

@ -2,14 +2,14 @@ import { ServerClient as PostmarkServerClient } from 'postmark'
import env from '../../env'
export function initializeEmailClient() {
switch (process.env.NX_EMAIL_PROVIDER) {
switch (env.NX_EMAIL_PROVIDER) {
case 'postmark':
if (env.NX_EMAIL_PROVIDER_API_TOKEN) {
return new PostmarkServerClient(env.NX_EMAIL_PROVIDER_API_TOKEN)
} else {
throw new Error('Missing Postmark API token')
return undefined
}
default:
throw new Error('Invalid email provider')
return undefined
}
}

View file

@ -259,7 +259,7 @@ router.get(
})
)
// TODO: Implement verification email using Postmark instead of Auth0
// TODO: Implement verification email using internal email service instead of Auth0
router.post(
'/resend-verification-email',
endpoint.create({

View file

@ -68,6 +68,7 @@ const envSchema = z.object({
NX_EMAIL_FROM_ADDRESS: z.string().default('account@maybe.co'),
NX_EMAIL_REPLY_TO_ADDRESS: z.string().default('support@maybe.co'),
NX_EMAIL_PROVIDER: z.string().optional(),
NX_EMAIL_PROVIDER_API_TOKEN: z.string().optional(),
})

View file

@ -2,14 +2,14 @@ import { ServerClient as PostmarkServerClient } from 'postmark'
import env from '../../env'
export function initializeEmailClient() {
switch (process.env.NX_EMAIL_PROVIDER) {
switch (env.NX_EMAIL_PROVIDER) {
case 'postmark':
if (env.NX_EMAIL_PROVIDER_API_TOKEN) {
return new PostmarkServerClient(env.NX_EMAIL_PROVIDER_API_TOKEN)
} else {
throw new Error('Missing Postmark API token')
return undefined
}
default:
throw new Error('Invalid email provider')
return undefined
}
}

View file

@ -23,7 +23,9 @@ const envSchema = z.object({
NX_EMAIL_FROM_ADDRESS: z.string().default('account@maybe.co'),
NX_EMAIL_REPLY_TO_ADDRESS: z.string().default('support@maybe.co'),
NX_EMAIL_PROVIDER: z.string().optional(),
NX_EMAIL_PROVIDER_API_TOKEN: z.string().optional(),
NX_STRIPE_SECRET_KEY: z.string().default('sk_test_REPLACE_THIS'),
NX_CDN_PRIVATE_BUCKET: z.string().default('REPLACE_THIS'),

View file

@ -1,10 +1,8 @@
import type { Logger } from 'winston'
import type { ServerClient as PostmarkServerClient } from 'postmark'
import type { MessageSendingResponse } from 'postmark/dist/client/models'
import { PostmarkEmailProvider } from './providers'
import type { SharedType } from '@maybe-finance/shared'
import { PostmarkEmailProvider } from './providers/postmark.provider'
export interface IEmailProvider {
send(messages: SharedType.PlainEmailMessage): Promise<SharedType.EmailSendingResponse>
send(messages: SharedType.PlainEmailMessage[]): Promise<SharedType.EmailSendingResponse[]>
@ -23,13 +21,13 @@ export interface IEmailProvider {
}
export class EmailService implements IEmailProvider {
private emailProvider: IEmailProvider
private emailProvider: IEmailProvider | undefined
constructor(
private readonly logger: Logger,
private readonly client: PostmarkServerClient | undefined,
private readonly defaultAddresses: { from: string; replyTo?: string }
) {
const provider = process.env.EMAIL_PROVIDER
const provider = process.env.NX_EMAIL_PROVIDER
switch (provider) {
case 'postmark':
@ -40,7 +38,7 @@ export class EmailService implements IEmailProvider {
)
break
default:
throw new Error('Unsupported email provider')
undefined
}
}
@ -49,24 +47,34 @@ export class EmailService implements IEmailProvider {
*
* @returns success boolean(s)
*/
send(messages: SharedType.PlainEmailMessage): Promise<any>
send(messages: SharedType.PlainEmailMessage[]): Promise<any[]>
send(
async send(messages: SharedType.PlainEmailMessage): Promise<SharedType.EmailSendingResponse>
async send(messages: SharedType.PlainEmailMessage[]): Promise<SharedType.EmailSendingResponse[]>
async send(
messages: SharedType.PlainEmailMessage | SharedType.PlainEmailMessage[]
): Promise<any | any[]> {
return this.emailProvider.send(messages)
): Promise<SharedType.EmailSendingResponse | SharedType.EmailSendingResponse[]> {
if (!this.emailProvider || !this.client) {
//no-op
return undefined as unknown as SharedType.EmailSendingResponse
}
return await this.emailProvider.send(messages)
}
/**
* Sends template email(s)
*/
async sendTemplate(messages: SharedType.TemplateEmailMessage): Promise<MessageSendingResponse>
async sendTemplate(
messages: SharedType.TemplateEmailMessage
): Promise<SharedType.EmailSendingResponse>
async sendTemplate(
messages: SharedType.TemplateEmailMessage[]
): Promise<MessageSendingResponse[]>
): Promise<SharedType.EmailSendingResponse[]>
async sendTemplate(
messages: SharedType.TemplateEmailMessage | SharedType.TemplateEmailMessage[]
): Promise<MessageSendingResponse | MessageSendingResponse[]> {
): Promise<SharedType.EmailSendingResponse | SharedType.EmailSendingResponse[]> {
if (!this.emailProvider || !this.client) {
//no-op
return undefined as unknown as SharedType.EmailSendingResponse
}
return this.emailProvider.sendTemplate(messages)
}
}

View file

@ -0,0 +1 @@
export * from './postmark.provider'