diff --git a/kittyurl-frontend/src/context/AuthProvider.tsx b/kittyurl-frontend/src/context/AuthProvider.tsx index 061204f..b6a0204 100644 --- a/kittyurl-frontend/src/context/AuthProvider.tsx +++ b/kittyurl-frontend/src/context/AuthProvider.tsx @@ -3,26 +3,17 @@ import { AuthContext } from './AuthContext'; import { sha512 } from '../utils/crypto'; import type { AuthResponse } from '../types/auth'; -// Bazowy URL z .env (np. "https://api.moja-aplikacja.pl") -const API_BASE_URL = (import.meta.env.VITE_API_TARGET || '').replace(/\/$/, ''); - /** * Funkcja pomocnicza do pobierania subdomeny. - * Przykład: 'klient1.aplikacja.pl' -> 'klient1' */ -const getSubdomain = () => { +const getSubdomain = (): string | null => { const hostname = window.location.hostname; const parts = hostname.split('.'); - - // Obsługa localhost i prostych domen (np. localhost lub moja-strona.pl) if (parts.length <= 2) return null; - - // Zwraca pierwszy człon (subdomenę) return parts[0]; }; export function AuthProvider({ children }: { children: ReactNode }) { - // Klucz tokena może być specyficzny dla subdomeny, aby sesje się nie mieszały const subdomain = getSubdomain(); const storageKey = subdomain ? `ktty_token_${subdomain}` : 'ktty_token'; @@ -31,57 +22,51 @@ export function AuthProvider({ children }: { children: ReactNode }) { const [error, setError] = useState(null); const authRequest = useCallback(async (endpoint: 'signUp' | 'signIn', name: string, pass: string) => { - if (!API_BASE_URL) { - const msg = "Błąd konfiguracji: VITE_API_TARGET jest pusty."; - setError(msg); - return null; - } - setLoading(true); setError(null); try { const hashedPassword = await sha512(pass); - // DYNAMICZNY URL: - // Możesz wstawić subdomenę jako część ścieżki lub jako subdomenę API - // Opcja A (ścieżka): `${API_BASE_URL}/${subdomain}/api/v1/...` - // Opcja B (subdomena): `https://${subdomain}.api.twoja-domena.pl/...` - - const urlPrefix = subdomain ? `${API_BASE_URL}/${subdomain}` : API_BASE_URL; - const fullUrl = `${urlPrefix}/api/v1/user/${endpoint}`; + // Korzystamy z relatywnej ścieżki /api, którą Vite Proxy przekaże dalej. + // Usuwamy API_BASE_URL, aby uniknąć błędów o nieużywanej zmiennej. + const pathPrefix = subdomain ? `/api/${subdomain}` : '/api'; + const fullUrl = `${pathPrefix}/v1/user/${endpoint}`; const response = await fetch(fullUrl, { method: 'POST', headers: { 'accept': 'application/json', 'Content-Type': 'application/json', - // Opcjonalnie: przesyłanie subdomeny w nagłówku, jeśli API tego wymaga 'X-Subdomain': subdomain || '', }, body: JSON.stringify({ name, password: hashedPassword, ttl: 86400 }), }); - const contentType = response.headers.get("content-type"); - let data: AuthResponse | null = null; - - if (contentType && contentType.includes("application/json")) { - data = await response.json(); - } + // Rozwiązanie błędu "Unexpected any": definiujemy typ danych przed użyciem + const data: AuthResponse = await response.json(); if (!response.ok) { const errorMsg = data?.error || data?.message || `Błąd serwera: ${response.status}`; throw new Error(errorMsg); } - if (data && data.token) { + if (data?.token) { sessionStorage.setItem(storageKey, data.token); setToken(data.token); } return data; } catch (err: unknown) { - const message = err instanceof Error ? err.message : 'Unknown error'; - setError(message); + // Rozwiązanie błędu "Unexpected any" w bloku catch: + let errorMessage = 'Wystąpił nieoczekiwany błąd'; + + if (err instanceof Error) { + errorMessage = err.message; + } else if (typeof err === 'string') { + errorMessage = err; + } + + setError(errorMessage); return null; } finally { setLoading(false); diff --git a/kittyurl-frontend/vite.config.ts b/kittyurl-frontend/vite.config.ts index 88c002f..fbc457e 100644 --- a/kittyurl-frontend/vite.config.ts +++ b/kittyurl-frontend/vite.config.ts @@ -1,29 +1,39 @@ -import { defineConfig, loadEnv } from 'vite' +import { defineConfig, loadEnv, type PluginOption } from 'vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' import path from 'path' +import { fileURLToPath } from 'url' + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export default defineConfig(({ mode }) => { - // Ścieżka do folderu nadrzędnego const envDirectory = path.resolve(__dirname, '..'); - - // Wczytujemy zmienne do użytku const env = loadEnv(mode, envDirectory, ''); + const backendTarget = env.VITE_API_TARGET; + return { - - envDir: envDirectory, - + envDir: envDirectory, plugins: [ - react(), - tailwindcss(), + react() as PluginOption, + tailwindcss() as PluginOption, ], server: { port: 6568, + host: true, + proxy: { + '/api': { + target: backendTarget, + changeOrigin: true, + secure: false, + + }, + }, }, preview: { - port: 6568, - allowedHosts: [env.VITE_ALLOWED_HOST], + port: 6568, + allowedHosts: true, }, } }) \ No newline at end of file