diff --git a/.env.example b/.env.example index ed77d048a2..b2dfb08056 100644 --- a/.env.example +++ b/.env.example @@ -27,6 +27,8 @@ NEXT_PRIVATE_OIDC_SKIP_VERIFY="" # [[URLS]] NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000" NEXT_PUBLIC_MARKETING_URL="http://localhost:3001" +# URL used by the web app to request itself (e.g. local background jobs) +NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000" # [[DATABASE]] NEXT_PRIVATE_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso" diff --git a/apps/marketing/process-env.d.ts b/apps/marketing/process-env.d.ts index 207bacef5b..fabe9b2432 100644 --- a/apps/marketing/process-env.d.ts +++ b/apps/marketing/process-env.d.ts @@ -2,7 +2,8 @@ declare namespace NodeJS { export interface ProcessEnv { NEXT_PUBLIC_WEBAPP_URL?: string; NEXT_PUBLIC_MARKETING_URL?: string; - + NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string; + NEXT_PRIVATE_DATABASE_URL: string; NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID: string; diff --git a/apps/web/process-env.d.ts b/apps/web/process-env.d.ts index 8bdfa41f96..ae9995df77 100644 --- a/apps/web/process-env.d.ts +++ b/apps/web/process-env.d.ts @@ -2,6 +2,7 @@ declare namespace NodeJS { export interface ProcessEnv { NEXT_PUBLIC_WEBAPP_URL?: string; NEXT_PUBLIC_MARKETING_URL?: string; + NEXT_PRIVATE_INTERNAL_WEBAPP_URL?:string; NEXT_PRIVATE_DATABASE_URL: string; diff --git a/docker/README.md b/docker/README.md index f3b3abd904..780d116feb 100644 --- a/docker/README.md +++ b/docker/README.md @@ -74,6 +74,7 @@ docker run -d \ -e NEXT_PRIVATE_ENCRYPTION_KEY="" -e NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="" -e NEXT_PUBLIC_WEBAPP_URL="" + -e NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000" -e NEXT_PRIVATE_DATABASE_URL="" -e NEXT_PRIVATE_DIRECT_DATABASE_URL="" -e NEXT_PRIVATE_SMTP_TRANSPORT="" diff --git a/docker/production/compose.yml b/docker/production/compose.yml index 36682ee42a..bd2b9597e6 100644 --- a/docker/production/compose.yml +++ b/docker/production/compose.yml @@ -29,6 +29,7 @@ services: - NEXT_PRIVATE_GOOGLE_CLIENT_ID=${NEXT_PRIVATE_GOOGLE_CLIENT_ID} - NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=${NEXT_PRIVATE_GOOGLE_CLIENT_SECRET} - NEXT_PUBLIC_WEBAPP_URL=${NEXT_PUBLIC_WEBAPP_URL:?err} + - NEXT_PRIVATE_INTERNAL_WEBAPP_URL=${NEXT_PRIVATE_INTERNAL_WEBAPP_URL:-http://localhost:$PORT} - NEXT_PUBLIC_MARKETING_URL=${NEXT_PUBLIC_MARKETING_URL:-https://documenso.com} - NEXT_PRIVATE_DATABASE_URL=${NEXT_PRIVATE_DATABASE_URL:?err} - NEXT_PRIVATE_DIRECT_DATABASE_URL=${NEXT_PRIVATE_DIRECT_DATABASE_URL:-${NEXT_PRIVATE_DATABASE_URL}} diff --git a/packages/lib/constants/app.ts b/packages/lib/constants/app.ts index 622878fdff..789bdd44ff 100644 --- a/packages/lib/constants/app.ts +++ b/packages/lib/constants/app.ts @@ -6,6 +6,7 @@ export const APP_DOCUMENT_UPLOAD_SIZE_LIMIT = export const NEXT_PUBLIC_WEBAPP_URL = () => env('NEXT_PUBLIC_WEBAPP_URL'); export const NEXT_PUBLIC_MARKETING_URL = () => env('NEXT_PUBLIC_MARKETING_URL'); +export const NEXT_PRIVATE_INTERNAL_WEBAPP_URL = process.env.NEXT_PRIVATE_INTERNAL_WEBAPP_URL ?? NEXT_PUBLIC_WEBAPP_URL(); export const IS_APP_MARKETING = process.env.NEXT_PUBLIC_PROJECT === 'marketing'; export const IS_APP_WEB = process.env.NEXT_PUBLIC_PROJECT === 'web'; diff --git a/packages/lib/jobs/client/local.ts b/packages/lib/jobs/client/local.ts index 8a307f0826..a0405dbf14 100644 --- a/packages/lib/jobs/client/local.ts +++ b/packages/lib/jobs/client/local.ts @@ -6,7 +6,7 @@ import { json } from 'micro'; import { prisma } from '@documenso/prisma'; import { BackgroundJobStatus, Prisma } from '@documenso/prisma/client'; -import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app'; +import { NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app'; import { sign } from '../../server-only/crypto/sign'; import { verify } from '../../server-only/crypto/verify'; import { @@ -229,7 +229,7 @@ export class LocalJobProvider extends BaseJobProvider { }) { const { jobId, jobDefinitionId, data, isRetry } = options; - const endpoint = `${NEXT_PUBLIC_WEBAPP_URL()}/api/jobs/${jobDefinitionId}/${jobId}`; + const endpoint = `${NEXT_PRIVATE_INTERNAL_WEBAPP_URL}/api/jobs/${jobDefinitionId}/${jobId}`; const signature = sign(data); const headers: Record = { diff --git a/packages/lib/server-only/feature-flags/all.ts b/packages/lib/server-only/feature-flags/all.ts index 71efd54251..05163b356d 100644 --- a/packages/lib/server-only/feature-flags/all.ts +++ b/packages/lib/server-only/feature-flags/all.ts @@ -5,7 +5,7 @@ import { getToken } from 'next-auth/jwt'; import { LOCAL_FEATURE_FLAGS } from '@documenso/lib/constants/feature-flags'; import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client'; -import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app'; +import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app'; import { extractDistinctUserId, mapJwtToFlagProperties } from './get'; /** @@ -46,6 +46,10 @@ export default async function handlerFeatureFlagAll(req: Request) { if (origin.startsWith(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3001')) { res.headers.set('Access-Control-Allow-Origin', origin); } + + if (origin.startsWith(NEXT_PRIVATE_INTERNAL_WEBAPP_URL ?? 'http://localhost:3000')) { + res.headers.set('Access-Control-Allow-Origin', origin); + } } return res; diff --git a/packages/lib/server-only/feature-flags/get.ts b/packages/lib/server-only/feature-flags/get.ts index 5b2b3b7fd5..46a223d14c 100644 --- a/packages/lib/server-only/feature-flags/get.ts +++ b/packages/lib/server-only/feature-flags/get.ts @@ -7,7 +7,7 @@ import { getToken } from 'next-auth/jwt'; import { LOCAL_FEATURE_FLAGS, extractPostHogConfig } from '@documenso/lib/constants/feature-flags'; import PostHogServerClient from '@documenso/lib/server-only/feature-flags/get-post-hog-server-client'; -import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app'; +import { NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_WEBAPP_URL, NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../constants/app'; /** * Evaluate a single feature flag based on the current user if possible. @@ -67,6 +67,10 @@ export default async function handleFeatureFlagGet(req: Request) { if (origin.startsWith(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3001')) { res.headers.set('Access-Control-Allow-Origin', origin); } + + if (origin.startsWith(NEXT_PRIVATE_INTERNAL_WEBAPP_URL ?? 'http://localhost:3000')) { + res.headers.set('Access-Control-Allow-Origin', origin); + } } return res; diff --git a/packages/lib/server-only/webhooks/trigger/trigger-webhook.ts b/packages/lib/server-only/webhooks/trigger/trigger-webhook.ts index e0a5eaaaf5..e226c808dc 100644 --- a/packages/lib/server-only/webhooks/trigger/trigger-webhook.ts +++ b/packages/lib/server-only/webhooks/trigger/trigger-webhook.ts @@ -1,6 +1,6 @@ import type { WebhookTriggerEvents } from '@documenso/prisma/client'; -import { NEXT_PUBLIC_WEBAPP_URL } from '../../../constants/app'; +import { NEXT_PRIVATE_INTERNAL_WEBAPP_URL } from '../../../constants/app'; import { sign } from '../../crypto/sign'; import { getAllWebhooksByEventTrigger } from '../get-all-webhooks-by-event-trigger'; @@ -29,7 +29,7 @@ export const triggerWebhook = async ({ event, data, userId, teamId }: TriggerWeb const signature = sign(body); await Promise.race([ - fetch(`${NEXT_PUBLIC_WEBAPP_URL()}/api/webhook/trigger`, { + fetch(`${NEXT_PRIVATE_INTERNAL_WEBAPP_URL}/api/webhook/trigger`, { method: 'POST', headers: { 'content-type': 'application/json', diff --git a/render.yaml b/render.yaml index 9e1565621d..5a6bbb9548 100644 --- a/render.yaml +++ b/render.yaml @@ -43,6 +43,8 @@ services: envVarKey: RENDER_EXTERNAL_URL - key: NEXT_PUBLIC_MARKETING_URL value: 'http://localhost:3001' + - key: NEXT_PRIVATE_INTERNAL_WEBAPP_URL + value: 'http://localhost:10000' # SMTP - key: NEXT_PRIVATE_SMTP_TRANSPORT diff --git a/turbo.json b/turbo.json index 66b9bf696b..44bf77b625 100644 --- a/turbo.json +++ b/turbo.json @@ -48,6 +48,7 @@ "NEXT_PUBLIC_PROJECT", "NEXT_PUBLIC_WEBAPP_URL", "NEXT_PUBLIC_MARKETING_URL", + "NEXT_PRIVATE_INTERNAL_WEBAPP_URL", "NEXT_PUBLIC_POSTHOG_KEY", "NEXT_PUBLIC_FEATURE_BILLING_ENABLED", "NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID",