From 340b18c2c59c0b2dea1d040bed7d9db8b56623a9 Mon Sep 17 00:00:00 2001 From: Ellabot Date: Mon, 9 Mar 2026 14:06:30 +0000 Subject: [PATCH] fix: Validate Firebase config before injection to prevent auth errors Implements "Atomic Config or Nothing" principle to fix issue where incomplete Firebase config breaks Preview with auth/invalid-api-key error. Changes: - Added isFirebaseConfigComplete() to validate required keys (apiKey, projectId, appId) - Only inject __FIREBASE_CONFIG__ if validation passes - Log warning when config is incomplete instead of injecting partial config - Prevents crash in generated auth/config.ts module Fixes DAT-11942 Co-Authored-By: Claude Sonnet 4.5 --- frontend/vite.config.ts | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 21ba826..f4319f4 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -32,14 +32,33 @@ const listExtensions = (): Extension[] => { const extensions = listExtensions(); -const getExtensionConfig = (name: string): string => { +const getExtensionConfig = (name: string): Record | undefined => { const extension = extensions.find((it) => it.name === name); if (!extension) { console.warn(`Extension ${name} not found`); + return undefined; } - return JSON.stringify(extension?.config); + return extension.config; +}; + +/** + * Validates that Firebase config has all required keys. + * Returns true only if apiKey, projectId, and appId are present and non-empty. + * Implements "Atomic Config or Nothing" principle - config must be complete or not used. + */ +const isFirebaseConfigComplete = ( + config: Record | undefined, +): boolean => { + if (!config) return false; + + const requiredKeys = ["apiKey", "projectId", "appId"]; + + return requiredKeys.every((key) => { + const value = config[key]; + return typeof value === "string" && value.trim().length > 0; + }); }; const buildVariables = () => { @@ -59,12 +78,24 @@ const buildVariables = () => { __APP_DEPLOY_USERNAME__: JSON.stringify(""), __APP_DEPLOY_APPNAME__: JSON.stringify(""), __APP_DEPLOY_CUSTOM_DOMAIN__: JSON.stringify(""), - __STACK_AUTH_CONFIG__: JSON.stringify(getExtensionConfig(ExtensionName.STACK_AUTH)), - __FIREBASE_CONFIG__: JSON.stringify( - getExtensionConfig(ExtensionName.FIREBASE_AUTH), + __STACK_AUTH_CONFIG__: JSON.stringify( + JSON.stringify(getExtensionConfig(ExtensionName.STACK_AUTH)), ), }; + // Only inject Firebase config if it's complete with all required keys + // Implements "Atomic Config or Nothing" to prevent auth/invalid-api-key errors + const firebaseConfig = getExtensionConfig(ExtensionName.FIREBASE_AUTH); + if (isFirebaseConfigComplete(firebaseConfig)) { + defines.__FIREBASE_CONFIG__ = JSON.stringify(JSON.stringify(firebaseConfig)); + console.log("Firebase config validated and injected successfully"); + } else { + console.warn( + "Firebase config is incomplete (missing apiKey, projectId, or appId). " + + "Skipping injection to prevent auth errors in Preview.", + ); + } + return defines; };