feat: added cookies to use subdomains
All checks were successful
Update changelog / changelog (push) Successful in 27s
All checks were successful
Update changelog / changelog (push) Successful in 27s
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import { useState, useCallback, type ReactNode } from 'react';
|
||||
import Cookies from 'js-cookie'; // Importujemy bibliotekę do ciasteczek
|
||||
import { AuthContext } from './AuthContext';
|
||||
import { sha512 } from '../utils/crypto';
|
||||
import type { AuthResponse } from '../types/auth';
|
||||
|
||||
const TOKEN_KEY = 'ktty_shared_token';
|
||||
const PARENT_DOMAIN = '.ktty.is'; // Kropka na początku pozwala na dostęp ze wszystkich subdomen
|
||||
|
||||
const getSubdomain = (): string | null => {
|
||||
const hostname = window.location.hostname;
|
||||
const parts = hostname.split('.');
|
||||
@@ -12,9 +16,9 @@ const getSubdomain = (): string | null => {
|
||||
|
||||
export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const subdomain = getSubdomain();
|
||||
const storageKey = subdomain ? `ktty_token_${subdomain}` : 'ktty_token';
|
||||
|
||||
const [token, setToken] = useState<string | null>(sessionStorage.getItem(storageKey));
|
||||
// Pobieramy token z ciasteczka zamiast z sessionStorage
|
||||
const [token, setToken] = useState<string | null>(Cookies.get(TOKEN_KEY) || null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -24,9 +28,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
try {
|
||||
const hashedPassword = await sha512(pass);
|
||||
|
||||
// POPRAWKA: Ścieżka URL jest stała, zgodna z Twoim API.
|
||||
// Vite Proxy przechwyci '/api' i skieruje to na https://www.ktty.is
|
||||
const fullUrl = `/api/v1/user/${endpoint}`;
|
||||
|
||||
const response = await fetch(fullUrl, {
|
||||
@@ -34,7 +35,6 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
// Subdomenę przekazujemy w nagłówku, aby backend wiedział, który to klient
|
||||
'X-Subdomain': subdomain || '',
|
||||
},
|
||||
body: JSON.stringify({ name, password: hashedPassword, ttl: 86400 }),
|
||||
@@ -43,12 +43,17 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const data: AuthResponse = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
const errorMsg = data?.error || data?.message || `Błąd serwera: ${response.status}`;
|
||||
throw new Error(errorMsg);
|
||||
throw new Error(data?.error || data?.message || 'Błąd logowania');
|
||||
}
|
||||
|
||||
if (data?.token) {
|
||||
sessionStorage.setItem(storageKey, data.token);
|
||||
// ZAPISYWANIE CIASTECZKA DLA WSZYSTKICH SUBDOMEN
|
||||
Cookies.set(TOKEN_KEY, data.token, {
|
||||
domain: PARENT_DOMAIN,
|
||||
expires: 1, // 1 dzień
|
||||
secure: true, // Wymagane dla HTTPS
|
||||
sameSite: 'lax'
|
||||
});
|
||||
setToken(data.token);
|
||||
}
|
||||
return data;
|
||||
@@ -60,12 +65,13 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [subdomain, storageKey]);
|
||||
}, [subdomain]);
|
||||
|
||||
const logout = useCallback(() => {
|
||||
sessionStorage.removeItem(storageKey);
|
||||
// Usuwamy ciasteczko z domeny nadrzędnej
|
||||
Cookies.remove(TOKEN_KEY, { domain: PARENT_DOMAIN });
|
||||
setToken(null);
|
||||
}, [storageKey]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{
|
||||
|
||||
Reference in New Issue
Block a user