diff --git a/kittyurl-frontend/src/context/AuthProvider.tsx b/kittyurl-frontend/src/context/AuthProvider.tsx index 4342c3f..061204f 100644 --- a/kittyurl-frontend/src/context/AuthProvider.tsx +++ b/kittyurl-frontend/src/context/AuthProvider.tsx @@ -3,37 +3,61 @@ import { AuthContext } from './AuthContext'; import { sha512 } from '../utils/crypto'; import type { AuthResponse } from '../types/auth'; -// Pobieramy bazowy adres i usuwamy ewentualny ukośnik na końcu -// Używamy import.meta.env, który jest dostępny wewnątrz kodu React +// 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 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 }) { - const [token, setToken] = useState(sessionStorage.getItem('ktty_token')); + // 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'; + + const [token, setToken] = useState(sessionStorage.getItem(storageKey)); const [loading, setLoading] = useState(false); 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. Sprawdź plik .env i restartuj serwer."; + const msg = "Błąd konfiguracji: VITE_API_TARGET jest pusty."; setError(msg); return null; } setLoading(true); setError(null); + try { const hashedPassword = await sha512(pass); - const fullUrl = `${API_BASE_URL}/api/v1/user/${endpoint}`; - + // 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}`; 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 }), }); @@ -51,7 +75,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { } if (data && data.token) { - sessionStorage.setItem('ktty_token', data.token); + sessionStorage.setItem(storageKey, data.token); setToken(data.token); } return data; @@ -62,12 +86,12 @@ export function AuthProvider({ children }: { children: ReactNode }) { } finally { setLoading(false); } - }, []); + }, [subdomain, storageKey]); const logout = useCallback(() => { - sessionStorage.removeItem('ktty_token'); + sessionStorage.removeItem(storageKey); setToken(null); - }, []); + }, [storageKey]); return ( ({ - name: 'domain-redirect', - configureServer(server) { - server.middlewares.use((req, res, next) => { - const host = req.headers.host; // np. "ssss.localhost:6568" - if (!host) return next(); - - const hostname = host.split(':')[0]; // usuwamy port, zostaje "ssss.localhost" - const targetHost = new URL(targetUrl).hostname; - - // LOGIKA TESTOWA DLA LOCALHOST: - // Jeśli host to np. ssss.localhost, a nie czysty localhost: - const isSubdomainOfLocalhost = hostname.endsWith('.localhost'); - const isPureLocalhost = hostname === 'localhost' || hostname === '127.0.0.1'; - - if (debug) { - console.log(`[Debug] Host: ${hostname}, SubOfLocal: ${isSubdomainOfLocalhost}, Pure: ${isPureLocalhost}`); - } - - // Przekieruj jeśli: - // 1. To subdomena localhosta (do testów) - // 2. LUB to subdomena ktty.is, a subdomeny są wyłączone - if ((isSubdomainOfLocalhost && hostname !== 'localhost') || (useSubdomains && hostname !== targetHost && !isPureLocalhost)) { - if (debug) console.log(`[Redirect] Z ${hostname} na ${targetUrl}`); - - res.writeHead(301, { Location: `${targetUrl}${req.url}` }); - return res.end(); - } - - next(); - }); - } -}); - 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, ''); - // Twoje zmienne z .env - const publicUrl = env.PUBLIC_URL; - const useSubdomains = env.USE_SUBDOMAINS === 'true'; - const isDebug = env.DEBUG === 'true'; - return { + envDir: envDirectory, + plugins: [ react(), tailwindcss(), - domainRedirectPlugin(publicUrl, useSubdomains, isDebug) ], server: { port: 6568, - host: true, }, preview: { port: 6568, - - allowedHosts: [env.VITE_ALLOWED_HOST , 'localhost'], + allowedHosts: [env.VITE_ALLOWED_HOST], }, } }) \ No newline at end of file