Enhance session management and player data handling
- Updated `requireSession.js` to ensure `req.body` and `req.query` are always objects before access, improving robustness against malformed requests. - Changed API endpoint for login from `/api/sessions/login` to `/api/players/login` in `App.js`, updating related logging and state management to reflect the new structure. - Enhanced player fetching logic in `PlayerTab.jsx` to handle cases where GM is logged in, ensuring all players are fetched from the API. Added debug logging for better traceability. - Implemented fallback to stored player data if API fetch fails, ensuring a smoother user experience for regular players. - Updated local storage handling to accommodate changes in player data structure.
This commit is contained in:
+10
-9
@@ -76,19 +76,20 @@ function App() {
|
||||
const handleLogin = async () => {
|
||||
try {
|
||||
logUserAction('user', 'Login attempt', { username: loginName });
|
||||
const response = await axios.post('/api/sessions/login', {
|
||||
username: loginName,
|
||||
const response = await axios.post('/api/players/login', {
|
||||
name: loginName,
|
||||
password: loginPw
|
||||
});
|
||||
|
||||
logApiCall('POST', '/api/sessions/login', { username: loginName }, response.status);
|
||||
logApiCall('POST', '/api/players/login', { name: loginName }, response.status);
|
||||
|
||||
if (response.data.success) {
|
||||
// Update global state with session info
|
||||
setAuthedPlayer(response.data.playerName);
|
||||
if (response.data.sessionId && response.data.player) {
|
||||
// Update global state with session info and player data
|
||||
setAuthedPlayer(response.data.player.name);
|
||||
setSessionId(response.data.sessionId);
|
||||
localStorage.setItem('dw:shop:authedPlayer', JSON.stringify(response.data.playerName));
|
||||
localStorage.setItem('dw:shop:authedPlayer', JSON.stringify(response.data.player.name));
|
||||
localStorage.setItem('dw:shop:sessionId', JSON.stringify(response.data.sessionId));
|
||||
localStorage.setItem('dw:shop:playerData', JSON.stringify(response.data.player));
|
||||
|
||||
info(`Login successful for user: ${loginName}`, 'auth');
|
||||
logUserAction('user', 'Login successful', { username: loginName });
|
||||
@@ -99,14 +100,14 @@ function App() {
|
||||
// Clear success message after 3 seconds
|
||||
setTimeout(() => setLoginMsg(''), 3000);
|
||||
} else {
|
||||
warn(`Login failed for user: ${loginName} - ${response.data.message}`, 'auth');
|
||||
warn(`Login failed for user: ${loginName} - ${response.data.message || 'Unknown error'}`, 'auth');
|
||||
setLoginMsg(response.data.message || 'Login failed');
|
||||
|
||||
// Clear error message after 5 seconds
|
||||
setTimeout(() => setLoginMsg(''), 5000);
|
||||
}
|
||||
} catch (err) {
|
||||
logApiError('POST', '/api/sessions/login', err);
|
||||
logApiError('POST', '/api/players/login', err);
|
||||
error(`Login error for user: ${loginName} - ${err.message}`, 'auth');
|
||||
setLoginMsg('Login failed. Please check your credentials and try again.');
|
||||
|
||||
|
||||
@@ -233,6 +233,37 @@ function PlayerTab({
|
||||
useEffect(() => {
|
||||
async function fetchPlayers() {
|
||||
try {
|
||||
console.log('DEBUG: fetchPlayers called, isGMLoggedIn():', isGMLoggedIn(), 'authedPlayer:', authedPlayer);
|
||||
|
||||
// If GM is logged in, always fetch all players from API
|
||||
if (isGMLoggedIn()) {
|
||||
console.log('DEBUG: GM is logged in, fetching all players from API');
|
||||
logApiCall('PlayerTab', 'GET', '/api/players');
|
||||
const response = await axios.get('/api/players', { headers: buildHeaders() });
|
||||
const data = response.data;
|
||||
console.log('DEBUG: GM API response:', data.length, 'players');
|
||||
if (!Array.isArray(data)) {
|
||||
warn('PlayerTab', '/api/players did not return an array', data);
|
||||
setPlayers([]);
|
||||
} else {
|
||||
info('PlayerTab', `Fetched ${data.length} players`);
|
||||
setPlayers(data);
|
||||
safeSet(STORAGE_SHOP_PLAYERS, data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('DEBUG: Not GM, checking stored data');
|
||||
// For regular players, try to get stored player data from login first
|
||||
const storedPlayerData = safeGet('dw:shop:playerData');
|
||||
if (storedPlayerData && authedPlayer) {
|
||||
console.log('DEBUG: Using stored player data for regular user');
|
||||
// If we have stored player data and user is logged in, use it
|
||||
setPlayers([storedPlayerData]);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('DEBUG: Fetching from API for regular user');
|
||||
logApiCall('PlayerTab', 'GET', '/api/players');
|
||||
const response = await axios.get('/api/players', { headers: buildHeaders() });
|
||||
const data = response.data;
|
||||
@@ -245,14 +276,21 @@ function PlayerTab({
|
||||
safeSet(STORAGE_SHOP_PLAYERS, data);
|
||||
}
|
||||
} catch (apiError) {
|
||||
console.log('DEBUG: API error:', apiError);
|
||||
logApiError('PlayerTab', 'GET', '/api/players', apiError);
|
||||
setPlayers([]);
|
||||
// If API fails but we have stored player data, use that
|
||||
const storedPlayerData = safeGet('dw:shop:playerData');
|
||||
if (storedPlayerData && authedPlayer) {
|
||||
setPlayers([storedPlayerData]);
|
||||
} else {
|
||||
setPlayers([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
fetchPlayers();
|
||||
// Add buildHeaders to dependencies since it's used in fetchPlayers
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [sessionId, gmOpen]);
|
||||
}, [sessionId, gmOpen, authedPlayer]);
|
||||
|
||||
// Update player data in the database
|
||||
async function updatePlayerData(updatedPlayer) {
|
||||
|
||||
Reference in New Issue
Block a user