From 78a34498d0e7c7dcca415f937d49906b61896449 Mon Sep 17 00:00:00 2001 From: Arek Bykowski Date: Sun, 15 Feb 2026 18:11:54 +0100 Subject: [PATCH] =?UTF-8?q?zmiany=20w=20obs=C5=82udze=20kluczy=20api=20i?= =?UTF-8?q?=20zabezpiecze=C5=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 6148 bytes App.tsx | 164 +++++++++++-------------------------- components/StepDetails.tsx | 63 ++++---------- components/TripMap.tsx | 97 ++++------------------ utils/envUtils.ts | 17 ++-- 5 files changed, 87 insertions(+), 254 deletions(-) diff --git a/.DS_Store b/.DS_Store index 18829a8d992b8b52b1d4cc0c72654cbb0529fc61..b9b53951f20f983c7fc104acc4e7c5f7fb4f4f2c 100644 GIT binary patch delta 167 zcmZoMXffEJ%ff2Uz`$TW*@(rEbv>As!J^M94`$5)viiZS3oN=|b;~C+v1)_WEuU<} zY6@1jd~yz}F<9O5$xB!@LFyRACtqUK1*rqFSlF~d>VPa0HdBx~AS(|j22$5Pc^;cF aSY7+%Yiz1ub?uYb&B4mrH`}nE5C8x-*CMX~ delta 167 zcmZoMXffEJ%fjl!z`&q4*@(rEbrYDC!J^Nq1ZK?vvL=C97g%(`>eftVV$}w#TQk{+ z)fB95&Ey void }> = ({ onLogin }) => { const [input, setInput] = useState(''); const [error, setError] = useState(false); - const [showDebug, setShowDebug] = useState(false); - - // DEBUGGING: Log to console on mount - useEffect(() => { - console.group("--- DEBUG PASSWORD SYSTEM ---"); - console.log("1. Detected ENV Variable:", ENV_PASSWORD ? "****" : "(empty)"); - console.log("2. Final Password Source:", IS_USING_FALLBACK ? "FALLBACK (Code)" : ".ENV FILE"); - console.log("3. Active Password Length:", APP_PASSWORD.length); - console.groupEnd(); - }, []); + + // Check if password is misconfigured (empty) + const isConfigMissing = !APP_PASSWORD; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - // Trim input to avoid accidental spaces from copy-paste if (input.trim() === APP_PASSWORD) { onLogin(true); } else { - console.log(`Failed Login. Input: "${input}" vs Expected: "${APP_PASSWORD}"`); setError(true); setInput(''); } }; + if (isConfigMissing) { + return ( +
+
+ +

Błąd Konfiguracji

+

+ Aplikacja nie wykryła hasła w zmiennych środowiskowych. +

+
+

Brakuje zmiennej: VITE_APP_PASSWORD

+

Jeśli używasz Coolify/Vercel:

+

1. Dodaj zmienną w panelu.

+

2. Przebuduj projekt (Re-deploy).

+
+
+
+ ); + } + return (
- {/* Debug Toggle (Hidden in corner) */} - -
@@ -97,7 +94,7 @@ const LoginScreen: React.FC<{ onLogin: (success: boolean) => void }> = ({ onLogi

Dostęp Chroniony

-

Wprowadź hasło, aby uzyskać dostęp do kreatora PromptStory.

+

Wprowadź hasło, aby uzyskać dostęp.

@@ -134,32 +131,9 @@ const LoginScreen: React.FC<{ onLogin: (success: boolean) => void }> = ({ onLogi - - {/* DEBUG PANEL */} - {showDebug && ( -
-

DEBUG STATUS:

- -
- SOURCE: - - {IS_USING_FALLBACK ? "FALLBACK (Code)" : ".ENV FILE"} - - - ACTIVE PASS: - {APP_PASSWORD.substring(0, 4)}... (len: {APP_PASSWORD.length}) -
- - {IS_USING_FALLBACK && ( -
-

System używa hasła awaryjnego zdefiniowanego w kodzie.

-
- )} -
- )} - +

- PromptStory v1.0 • Private Instance + PromptStory v1.2 • Secure Production Build

@@ -210,19 +184,11 @@ const App: React.FC = () => { if (saved) { try { const parsed = JSON.parse(saved); - // Reset files because File objects cannot be serialized to local storage - parsed.files = []; + parsed.files = []; // Reset files - // Ensure new fields exist if loading from old state if (!parsed.stats) parsed.stats = { distance: '', duration: '', elevation: '' }; if (!parsed.waypoints) parsed.waypoints = []; - - // Ensure tripData exists - if (!parsed.tripData) { - parsed.tripData = { ...INITIAL_STATE.tripData }; - } - - // Defaults for new fields if migrating + if (!parsed.tripData) parsed.tripData = { ...INITIAL_STATE.tripData }; if (!parsed.tone) parsed.tone = null; if (!parsed.goal) parsed.goal = null; if (!parsed.storyStyle) parsed.storyStyle = null; @@ -237,13 +203,11 @@ const App: React.FC = () => { useEffect(() => { if (isLoaded) { - // Exclude files from persistence to avoid quota issues and serialization errors const stateToSave = { ...data, files: [] }; localStorage.setItem(STORAGE_KEY, JSON.stringify(stateToSave)); } }, [data, isLoaded]); - // UPDATED: Now supports functional updates to prevent stale state issues const updateData = (updates: Partial | ((prev: WizardState) => Partial)) => { setData(prev => { const newValues = typeof updates === 'function' ? updates(prev) : updates; @@ -266,19 +230,23 @@ const App: React.FC = () => { const handleGenerate = async () => { setIsGenerating(true); setErrorMessage(null); + + // STRICT MODE: Use VITE_API_KEY + const apiKey = getEnvVar('VITE_API_KEY'); + + if (!apiKey) { + setErrorMessage("BŁĄD KRYTYCZNY: Brak klucza API (VITE_API_KEY). Skonfiguruj zmienne w panelu Coolify."); + setIsGenerating(false); + return; + } + try { - // SAFE ENV ACCESS - const apiKey = getEnvVar('API_KEY'); - const content = await generateStoryContent( - data, - apiKey || '' - ); - + const content = await generateStoryContent(data, apiKey); setGeneratedContent(content); updateData({ step: Step.RESULT }); } catch (error: any) { console.error("Generowanie nie powiodło się:", error); - setErrorMessage("Błąd generowania. Sprawdź poprawność klucza API w pliku .env oraz połączenie z siecią. " + (error.message || '')); + setErrorMessage("Błąd generowania: " + (error.message || 'Sprawdź konsolę')); } finally { setIsGenerating(false); } @@ -287,15 +255,11 @@ const App: React.FC = () => { const handleRegenerate = async (slideCount: number, feedback: string) => { setIsGenerating(true); setErrorMessage(null); + + const apiKey = getEnvVar('VITE_API_KEY'); + try { - // SAFE ENV ACCESS - const apiKey = getEnvVar('API_KEY'); - const content = await generateStoryContent( - data, - apiKey || '', - { slideCount, feedback } - ); - + const content = await generateStoryContent(data, apiKey || '', { slideCount, feedback }); setGeneratedContent(content); } catch (error: any) { console.error("Regenerowanie nie powiodło się:", error); @@ -309,24 +273,19 @@ const App: React.FC = () => { setData({ ...INITIAL_STATE }); setGeneratedContent(null); localStorage.removeItem(STORAGE_KEY); - // Force reload to clear any hung states window.location.reload(); }; - // --- RENDER LOGIC --- - - if (isAuthChecking || !isLoaded) return null; // Loading state + if (isAuthChecking || !isLoaded) return null; if (!isAuthenticated) { return ; } - // Step Labels for Progress Bar (Order Changed) const stepsLabels = ['Kontekst', 'Typ', 'Platforma', 'Vibe & Cel', 'Szczegóły']; return (
- {/* Header */}
@@ -357,8 +316,6 @@ const App: React.FC = () => {
- - {/* Progress Bar */} {data.step !== Step.RESULT && (
@@ -377,21 +334,11 @@ const App: React.FC = () => {
)} - {/* Dynamic Content Container */}
- {/* STEP 1: CONTEXT */} {data.step === Step.CONTEXT && } - - {/* STEP 2: EVENT TYPE (Moved UP) */} {data.step === Step.EVENT_TYPE && } - - {/* STEP 3: PLATFORM (Moved DOWN) */} {data.step === Step.PLATFORM && } - - {/* STEP 4: TONE & GOAL (NEW) */} {data.step === Step.TONE_GOAL && } - - {/* STEP 5: DETAILS */} {data.step === Step.DETAILS && ( { isGenerating={isGenerating} /> )} - - {/* STEP 6: RESULT */} {data.step === Step.RESULT && generatedContent && ( { /> )} - {/* Error Message */} {errorMessage && (
{errorMessage} @@ -419,7 +363,6 @@ const App: React.FC = () => { )}
- {/* Navigation Controls (Back Only) */} {data.step > Step.CONTEXT && data.step < Step.RESULT && (
@@ -436,11 +379,9 @@ const App: React.FC = () => { )}
- {/* Footer / Author Info */}