diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 8904b795d..ceb14ebe6 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -9,6 +9,12 @@ jobs: name: ĘŚ TypeScript timeout-minutes: 8 runs-on: ubuntu-latest + env: + SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} + SUPABASE_DB_WEBHOOK_SECRET: ${{ secrets.SUPABASE_DB_WEBHOOK_SECRET }} + STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} + STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }} + steps: - uses: actions/checkout@v4 with: diff --git a/apps/web/app/api/db/webhook/route.ts b/apps/web/app/api/db/webhook/route.ts index 21967e4cf..c1ad71794 100644 --- a/apps/web/app/api/db/webhook/route.ts +++ b/apps/web/app/api/db/webhook/route.ts @@ -5,6 +5,7 @@ import { DatabaseWebhookHandlerService } from '@kit/database-webhooks'; const webhooksSecret = z .string({ description: `The secret used to verify the webhook signature`, + required_error: `Provide the variable SUPABASE_DB_WEBHOOK_SECRET. This is used to authenticate the webhook event from Supabase.`, }) .min(1) .parse(process.env.SUPABASE_DB_WEBHOOK_SECRET); diff --git a/apps/web/config/app.config.ts b/apps/web/config/app.config.ts index 36718223f..15057a1db 100644 --- a/apps/web/config/app.config.ts +++ b/apps/web/config/app.config.ts @@ -7,22 +7,30 @@ const AppConfigSchema = z name: z .string({ description: `This is the name of your SaaS. Ex. "Makerkit"`, + required_error: `Please provide the variable NEXT_PUBLIC_PRODUCT_NAME`, }) .min(1), title: z .string({ description: `This is the default title tag of your SaaS.`, + required_error: `Please provide the variable NEXT_PUBLIC_SITE_TITLE`, }) .min(1), description: z.string({ description: `This is the default description of your SaaS.`, + required_error: `Please provide the variable NEXT_PUBLIC_SITE_DESCRIPTION`, }), - url: z.string().url({ - message: `Please provide a valid URL. Example: 'https://example.com'`, - }), + url: z + .string({ + required_error: `Please provide the variable NEXT_PUBLIC_SITE_URL`, + }) + .url({ + message: `Please provide a valid URL. Example: 'https://example.com'`, + }), locale: z .string({ description: `This is the default locale of your SaaS.`, + required_error: `Please provide the variable NEXT_PUBLIC_DEFAULT_LOCALE`, }) .default('en'), theme: z.enum(['light', 'dark', 'system']), diff --git a/apps/web/config/feature-flags.config.ts b/apps/web/config/feature-flags.config.ts index bc2bc2acd..544632888 100644 --- a/apps/web/config/feature-flags.config.ts +++ b/apps/web/config/feature-flags.config.ts @@ -1,17 +1,43 @@ import { z } from 'zod'; const FeatureFlagsSchema = z.object({ - enableThemeToggle: z.boolean(), - enableAccountDeletion: z.boolean(), - enableTeamDeletion: z.boolean(), - enableTeamAccounts: z.boolean(), - enableTeamCreation: z.boolean(), - enablePersonalAccountBilling: z.boolean(), - enableTeamAccountBilling: z.boolean(), + enableThemeToggle: z.boolean({ + description: 'Enable theme toggle in the user interface.', + required_error: 'Provide the variable NEXT_PUBLIC_ENABLE_THEME_TOGGLE', + }), + enableAccountDeletion: z.boolean({ + description: 'Enable account deletion.', + required_error: 'Provide the variable NEXT_PUBLIC_ENABLE_ACCOUNT_DELETION', + }), + enableTeamDeletion: z.boolean({ + description: 'Enable team deletion.', + required_error: 'Provide the variable NEXT_PUBLIC_ENABLE_TEAM_DELETION', + }), + enableTeamAccounts: z.boolean({ + description: 'Enable team accounts.', + required_error: 'Provide the variable NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS', + }), + enableTeamCreation: z.boolean({ + description: 'Enable team creation.', + required_error: 'Provide the variable NEXT_PUBLIC_ENABLE_TEAMS_CREATION', + }), + enablePersonalAccountBilling: z.boolean({ + description: 'Enable personal account billing.', + required_error: + 'Provide the variable NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING', + }), + enableTeamAccountBilling: z.boolean({ + description: 'Enable team account billing.', + required_error: + 'Provide the variable NEXT_PUBLIC_ENABLE_ORGANIZATION_BILLING', + }), }); const featuresFlagConfig = FeatureFlagsSchema.parse({ - enableThemeToggle: true, + enableThemeToggle: getBoolean( + process.env.NEXT_PUBLIC_ENABLE_THEME_TOGGLE, + true, + ), enableAccountDeletion: getBoolean( process.env.NEXT_PUBLIC_ENABLE_ACCOUNT_DELETION, false, diff --git a/packages/billing/stripe/src/schema/stripe-server-env.schema.ts b/packages/billing/stripe/src/schema/stripe-server-env.schema.ts index d5e2d4d1f..274cec468 100644 --- a/packages/billing/stripe/src/schema/stripe-server-env.schema.ts +++ b/packages/billing/stripe/src/schema/stripe-server-env.schema.ts @@ -2,8 +2,16 @@ import { z } from 'zod'; export const StripeServerEnvSchema = z .object({ - secretKey: z.string().min(1), - webhooksSecret: z.string().min(1), + secretKey: z + .string({ + required_error: `Please provide the variable STRIPE_SECRET_KEY`, + }) + .min(1), + webhooksSecret: z + .string({ + required_error: `Please provide the variable STRIPE_WEBHOOK_SECRET`, + }) + .min(1), }) .refine( (schema) => { diff --git a/packages/features/accounts/src/server/personal-accounts-server-actions.ts b/packages/features/accounts/src/server/personal-accounts-server-actions.ts index 5a6523429..81dded878 100644 --- a/packages/features/accounts/src/server/personal-accounts-server-actions.ts +++ b/packages/features/accounts/src/server/personal-accounts-server-actions.ts @@ -76,8 +76,16 @@ export async function deletePersonalAccountAction(formData: FormData) { function getEmailSettingsFromEnvironment() { return z .object({ - fromEmail: z.string().email(), - productName: z.string().min(1), + fromEmail: z + .string({ + required_error: 'Provide the variable EMAIL_SENDER', + }) + .email(), + productName: z + .string({ + required_error: 'Provide the variable NEXT_PUBLIC_PRODUCT_NAME', + }) + .min(1), }) .parse({ fromEmail: process.env.EMAIL_SENDER, diff --git a/packages/mailers/src/schema/smtp-config.schema.ts b/packages/mailers/src/schema/smtp-config.schema.ts index 55a97aeb9..9a5094972 100644 --- a/packages/mailers/src/schema/smtp-config.schema.ts +++ b/packages/mailers/src/schema/smtp-config.schema.ts @@ -1,49 +1,28 @@ +import 'server-only'; + import { z } from 'zod'; -/* -const user = process.env.EMAIL_USER; - const pass = process.env.EMAIL_PASSWORD; - const host = process.env.EMAIL_HOST; - const port = Number(process.env.EMAIL_PORT); - const secure = process.env.EMAIL_TLS !== 'false'; - - // validate that we have all the required appConfig - if (!user || !pass || !host || !port) { - throw new Error( - `Missing email configuration. Please add the following environment variables: - EMAIL_USER - EMAIL_PASSWORD - EMAIL_HOST - EMAIL_PORT - `, - ); - } - - return { - host, - port, - secure, - auth: { - user, - pass, - }, - }; - */ - export const SmtpConfigSchema = z.object({ user: z.string({ description: 'This is the email account to send emails from. This is specific to the email provider.', + required_error: `Please provide the variable EMAIL_USER`, }), pass: z.string({ description: 'This is the password for the email account', + required_error: `Please provide the variable EMAIL_PASSWORD`, }), host: z.string({ description: 'This is the SMTP host for the email provider', + required_error: `Please provide the variable EMAIL_HOST`, }), port: z.number({ description: 'This is the port for the email provider. Normally 587 or 465.', + required_error: `Please provide the variable EMAIL_PORT`, + }), + secure: z.boolean({ + description: 'This is whether the connection is secure or not', + required_error: `Please provide the variable EMAIL_TLS`, }), - secure: z.boolean(), });