refactoring
This commit is contained in:
158
src/hooks/useSessionManager.js
Normal file
158
src/hooks/useSessionManager.js
Normal file
@@ -0,0 +1,158 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
const TOKEN_STORAGE_KEY = 'pickupConfigToken';
|
||||
|
||||
const useSessionManager = ({
|
||||
normalizeConfigEntries,
|
||||
normalizeAdminSettings,
|
||||
onUnauthorized,
|
||||
setError,
|
||||
setLoading
|
||||
}) => {
|
||||
const [session, setSession] = useState(null);
|
||||
const unauthorizedRef = useRef(onUnauthorized || (() => {}));
|
||||
|
||||
useEffect(() => {
|
||||
unauthorizedRef.current = onUnauthorized || (() => {});
|
||||
}, [onUnauthorized]);
|
||||
|
||||
const handleUnauthorized = useCallback(() => {
|
||||
setSession(null);
|
||||
try {
|
||||
localStorage.removeItem(TOKEN_STORAGE_KEY);
|
||||
} catch (storageError) {
|
||||
console.warn('Konnte Token nicht aus dem Speicher entfernen:', storageError);
|
||||
}
|
||||
unauthorizedRef.current();
|
||||
}, []);
|
||||
|
||||
const handleUnauthorizedRef = useRef(() => {});
|
||||
useEffect(() => {
|
||||
handleUnauthorizedRef.current = handleUnauthorized;
|
||||
}, [handleUnauthorized]);
|
||||
|
||||
const authorizedFetch = useCallback(
|
||||
async (url, options = {}, tokenOverride) => {
|
||||
const activeToken = tokenOverride || session?.token;
|
||||
if (!activeToken) {
|
||||
throw new Error('Keine aktive Session');
|
||||
}
|
||||
const headers = {
|
||||
Authorization: `Bearer ${activeToken}`,
|
||||
...(options.headers || {})
|
||||
};
|
||||
const response = await fetch(url, { ...options, headers });
|
||||
if (response.status === 401) {
|
||||
handleUnauthorizedRef.current();
|
||||
throw new Error('Nicht autorisiert');
|
||||
}
|
||||
return response;
|
||||
},
|
||||
[session?.token]
|
||||
);
|
||||
|
||||
const storeToken = useCallback((token) => {
|
||||
if (!token) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
localStorage.setItem(TOKEN_STORAGE_KEY, token);
|
||||
} catch (storageError) {
|
||||
console.warn('Konnte Token nicht speichern:', storageError);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const getStoredToken = useCallback(() => {
|
||||
try {
|
||||
return localStorage.getItem(TOKEN_STORAGE_KEY);
|
||||
} catch (storageError) {
|
||||
console.warn('Konnte gespeicherten Token nicht lesen:', storageError);
|
||||
return null;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const bootstrapSession = useCallback(
|
||||
async (token, { progress } = {}) => {
|
||||
if (!token) {
|
||||
return {};
|
||||
}
|
||||
setLoading(true);
|
||||
setError('');
|
||||
progress?.update?.('Session wird aufgebaut...', 20);
|
||||
try {
|
||||
const response = await fetch('/api/auth/session', {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
if (response.status === 401) {
|
||||
handleUnauthorized();
|
||||
return {};
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
const sessionData = { token, profile: data.profile, isAdmin: data.isAdmin };
|
||||
setSession(sessionData);
|
||||
progress?.update?.('Betriebe werden geprüft...', 45);
|
||||
const stores = Array.isArray(data.stores) ? data.stores : [];
|
||||
const adminSettings = data.isAdmin ? normalizeAdminSettings(data.adminSettings) : null;
|
||||
|
||||
const configResponse = await fetch('/api/config', {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
});
|
||||
if (configResponse.status === 401) {
|
||||
handleUnauthorized();
|
||||
return {};
|
||||
}
|
||||
if (!configResponse.ok) {
|
||||
throw new Error(`HTTP ${configResponse.status}`);
|
||||
}
|
||||
const configData = await configResponse.json();
|
||||
progress?.update?.('Konfiguration wird geladen...', 75);
|
||||
const config = normalizeConfigEntries(Array.isArray(configData) ? configData : []);
|
||||
progress?.update?.('Synchronisierung abgeschlossen', 95);
|
||||
|
||||
return {
|
||||
session: sessionData,
|
||||
stores,
|
||||
adminSettings,
|
||||
config,
|
||||
storeRefreshJob: data.storeRefreshJob,
|
||||
storesFresh: data.storesFresh
|
||||
};
|
||||
} catch (error) {
|
||||
setError(`Session konnte nicht wiederhergestellt werden: ${error.message}`);
|
||||
return {};
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[normalizeAdminSettings, normalizeConfigEntries, handleUnauthorized, setError, setLoading]
|
||||
);
|
||||
|
||||
const performLogout = useCallback(async () => {
|
||||
if (!session?.token) {
|
||||
handleUnauthorized();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await authorizedFetch('/api/auth/logout', { method: 'POST' });
|
||||
} catch (err) {
|
||||
console.warn('Logout fehlgeschlagen:', err);
|
||||
} finally {
|
||||
handleUnauthorized();
|
||||
}
|
||||
}, [session?.token, authorizedFetch, handleUnauthorized]);
|
||||
|
||||
return {
|
||||
session,
|
||||
authorizedFetch,
|
||||
bootstrapSession,
|
||||
performLogout,
|
||||
handleUnauthorized,
|
||||
storeToken,
|
||||
getStoredToken
|
||||
};
|
||||
};
|
||||
|
||||
export default useSessionManager;
|
||||
Reference in New Issue
Block a user