diff --git a/apps/editor/lib/auth.ts b/apps/editor/lib/auth.ts index 3160d53b..5cf5a59b 100644 --- a/apps/editor/lib/auth.ts +++ b/apps/editor/lib/auth.ts @@ -1,14 +1,25 @@ import { createAuth } from '@pascal-app/auth/server' import { db } from '@pascal-app/db' import { Resend } from 'resend' +import { BASE_URL } from './utils' -const resend = process.env.RESEND_API_KEY ? new Resend(process.env.RESEND_API_KEY) : null +// Initialize Resend only if API key is available +const resendApiKey = process.env.RESEND_API_KEY +const resend = resendApiKey && resendApiKey.trim() !== '' ? new Resend(resendApiKey) : null + +// Better Auth secret is required +const betterAuthSecret = process.env.BETTER_AUTH_SECRET +if (!betterAuthSecret) { + throw new Error( + 'Missing BETTER_AUTH_SECRET environment variable. Generate one with: openssl rand -base64 32', + ) +} export const auth = createAuth({ db, appName: 'Pascal Editor', - baseURL: process.env.BETTER_AUTH_URL!, - secret: process.env.BETTER_AUTH_SECRET!, + baseURL: BASE_URL, + secret: betterAuthSecret, sendMagicLink: async ({ email, url }) => { if (!resend) { console.log(`[DEV] Magic link for ${email}: ${url}`) diff --git a/apps/editor/lib/utils.ts b/apps/editor/lib/utils.ts index d32b0fe6..44aa86a2 100644 --- a/apps/editor/lib/utils.ts +++ b/apps/editor/lib/utils.ts @@ -4,3 +4,41 @@ import { twMerge } from 'tailwind-merge' export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } + +export const isDevelopment = + process.env.NODE_ENV === 'development' || + process.env.NEXT_PUBLIC_VERCEL_ENV === 'development' + +export const isProduction = + process.env.NODE_ENV === 'production' || process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' + +export const isPreview = process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' + +/** + * Base URL for the application + * Uses NEXT_PUBLIC_* variables which are available at build time + */ +export const BASE_URL = (() => { + // Development: localhost + if (isDevelopment) { + return process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3000}` + } + + // Preview deployments: use Vercel branch URL + if (isPreview && process.env.NEXT_PUBLIC_VERCEL_URL) { + return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + } + + // Production: use custom domain or Vercel production URL + if (isProduction) { + return ( + process.env.NEXT_PUBLIC_APP_URL || + (process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}` + : 'https://editor.pascal.app') + ) + } + + // Fallback (should never reach here in normal operation) + return process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000' +})()