diff --git a/.env.sample b/.env.sample index ff28840..ee05944 100644 --- a/.env.sample +++ b/.env.sample @@ -11,3 +11,6 @@ POSTGRESQL_CAFILE="" BREVO_API_KEY="fake" STRIPE_API_KEY="fake" + +# Uncomment this variable to log verification codes instead of emailing them, and create "lifetime" accounts on signup instead of trials +# IS_UNSAFE_SELF_HOSTED="true" # any non-empty value will be considered true diff --git a/lib/data-utils.ts b/lib/data-utils.ts index 5f720c8..90c6b0f 100644 --- a/lib/data-utils.ts +++ b/lib/data-utils.ts @@ -1,6 +1,6 @@ import Database, { sql } from './interfaces/database.ts'; import { Budget, Expense, User, UserSession, VerificationCode } from './types.ts'; -import { generateRandomCode, splitArrayInChunks } from './utils.ts'; +import { generateRandomCode, IS_UNSAFE_SELF_HOSTED, splitArrayInChunks } from './utils.ts'; const db = new Database(); @@ -25,7 +25,7 @@ export async function getUserById(id: string) { } export async function createUser(email: User['email'], encryptedKeyPair: User['encrypted_key_pair']) { - const trialDays = 30; + const trialDays = IS_UNSAFE_SELF_HOSTED ? 30_000 : 30; const now = new Date(); const trialEndDate = new Date(new Date().setUTCDate(new Date().getUTCDate() + trialDays)); @@ -47,7 +47,7 @@ export async function createUser(email: User['email'], encryptedKeyPair: User['e [ email, JSON.stringify(subscription), - 'trial', + IS_UNSAFE_SELF_HOSTED ? 'active' : 'trial', encryptedKeyPair, JSON.stringify({}), ], diff --git a/lib/providers/brevo.ts b/lib/providers/brevo.ts index 318a693..e78952d 100644 --- a/lib/providers/brevo.ts +++ b/lib/providers/brevo.ts @@ -1,6 +1,6 @@ import 'std/dotenv/load.ts'; -import { helpEmail } from '/lib/utils.ts'; +import { helpEmail, IS_UNSAFE_SELF_HOSTED } from '/lib/utils.ts'; const BREVO_API_KEY = Deno.env.get('BREVO_API_KEY') || ''; @@ -62,6 +62,12 @@ async function sendEmailWithTemplate( email.cc = [{ email: cc }]; } + if (IS_UNSAFE_SELF_HOSTED) { + console.log('Email not sent!'); + console.log(JSON.stringify(email, null, 2)); + return; + } + const brevoResponse = await fetch('https://api.brevo.com/v3/smtp/email', { method: 'POST', headers: getApiRequestHeaders(), diff --git a/lib/utils.ts b/lib/utils.ts index 57f5135..ef384b3 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -20,6 +20,7 @@ export const STRIPE_MONTHLY_URL = 'https://buy.stripe.com/eVa01H57C3MB6CQ14s'; export const STRIPE_YEARLY_URL = 'https://buy.stripe.com/28o5m1dE896V0es8wV'; export const STRIPE_CUSTOMER_URL = 'https://billing.stripe.com/p/login/4gw15w3G9bDyfWU6oo'; export const PAYPAL_CUSTOMER_URL = 'https://www.paypal.com'; +export const IS_UNSAFE_SELF_HOSTED = Boolean(Deno.env.get('IS_UNSAFE_SELF_HOSTED') || ''); export interface PageContentResult { htmlContent: string; @@ -186,7 +187,7 @@ export function splitArrayInChunks(array: T[], chunkLength: number) { // Because new URLSearchParams(Object.entries(object)).toString() doesn't work recursively export function jsonToFormUrlEncoded(object: any, key = '', list: string[] = []) { - if (typeof (object) === 'object') { + if (typeof object === 'object') { for (const subKey in object) { jsonToFormUrlEncoded(object[subKey], key ? `${key}[${subKey}]` : subKey, list); } diff --git a/main.ts b/main.ts index b854349..db92aab 100644 --- a/main.ts +++ b/main.ts @@ -1,5 +1,5 @@ -import { serve } from 'std/http/server.ts'; import routes, { Route } from './routes.ts'; +import { IS_UNSAFE_SELF_HOSTED } from './lib/utils.ts'; function handler(request: Request) { const routeKeys = Object.keys(routes); @@ -22,4 +22,8 @@ export const abortController = new AbortController(); const PORT = Deno.env.get('PORT') || 8000; -serve(handler, { port: PORT as number, signal: abortController.signal }); +if (IS_UNSAFE_SELF_HOSTED) { + console.log('IS_UNSAFE_SELF_HOSTED enabled! No emails will be sent and all signups will be forever.'); +} + +Deno.serve({ port: PORT as number, signal: abortController.signal }, handler);