feat: enhance session management and authentication logging

This commit is contained in:
ethanf 2025-08-14 14:28:09 -05:00
parent 20d1d3b544
commit 6fb68fded9
4 changed files with 69 additions and 104 deletions

View File

@ -57,8 +57,11 @@ app.use(session({
cookie: {
secure: process.env.NODE_ENV === 'production', // HTTPS in production
maxAge: 24 * 60 * 60 * 1000,
httpOnly: true
}
httpOnly: true,
sameSite: process.env.NODE_ENV === 'production' ? 'lax' : 'lax', // Important for cross-site cookies
domain: process.env.NODE_ENV === 'production' ? '.ethanf.gg' : undefined
},
name: 's22poll.sid' // Custom session name
}));
app.use(passport.initialize());
@ -104,8 +107,10 @@ app.get('/auth/steam', passport.authenticate('steam'));
app.get('/auth/steam/return',
passport.authenticate('steam', { failureRedirect: `${FRONTEND_URL}` }),
(req, res) => {
console.log('Steam authentication callback received');
console.log('User authenticated:', req.user?.displayName);
// Successful authentication, redirect to frontend
res.redirect(`${FRONTEND_URL}?auth=success`);
res.redirect('/?auth=success');
}
);

View File

@ -1,38 +1,42 @@
import { useState, useEffect } from "react";
import type { SteamUser } from "../types";
import { authService } from "../services/api";
import { useState, useEffect } from 'react';
import type { SteamUser } from '../types';
import { authService } from '../services/api';
export function useAuth() {
export const useAuth = () => {
const [user, setUser] = useState<SteamUser | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
checkAuthStatus();
// Check for auth success in URL (after Steam redirect)
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("auth") === "success") {
// Remove the auth parameter from URL
window.history.replaceState({}, document.title, window.location.pathname);
checkAuthStatus();
}
}, []);
const checkAuthStatus = async () => {
try {
const data = await authService.checkUser();
if (data) {
setUser(data.user);
}
console.log('Checking authentication status...');
const response = await authService.getCurrentUser();
console.log('Auth check response:', response);
setUser(response.user);
} catch (error) {
console.error("Auth check failed:", error);
console.log('User not authenticated:', error);
setUser(null);
} finally {
setLoading(false);
}
};
checkAuthStatus();
// Check for auth success parameter
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('auth') === 'success') {
console.log('Auth success detected, rechecking user status...');
// Remove the auth parameter from URL
window.history.replaceState({}, document.title, window.location.pathname);
// Recheck auth status
setTimeout(checkAuthStatus, 1000);
}
}, []);
const handleLogin = () => {
window.location.href = authService.getSteamLoginUrl();
console.log('Initiating login...');
window.location.href = `${import.meta.env.PROD ? 'https://s22.ethanf.gg' : 'http://localhost:3001'}/auth/steam`;
};
const handleLogout = async () => {
@ -40,14 +44,9 @@ export function useAuth() {
await authService.logout();
setUser(null);
} catch (error) {
console.error("Logout failed:", error);
console.error('Logout failed:', error);
}
};
return {
user,
loading,
handleLogin,
handleLogout,
return { user, loading, handleLogin, handleLogout };
};
}

View File

@ -20,7 +20,7 @@ export function useVoteLogic() {
const checkVoteStatus = async () => {
try {
const data = await voteService.checkVoteStatus();
const data = await voteService.getVoteStatus();
setPollEnded(data.isPollEnded);
if (data.hasVoted && data.vote) {

View File

@ -1,76 +1,37 @@
import { API_BASE_URL } from "../constants";
import type { SteamUser, VoteStatusResponse, MapOption } from "../types";
import type { MapOption } from "../types";
const API_BASE_URL = import.meta.env.PROD
? 'https://s22.ethanf.gg'
: 'http://localhost:3001';
const apiCall = async (endpoint: string, options: RequestInit = {}) => {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
...options,
credentials: 'include', // Always include cookies
headers: {
'Content-Type': 'application/json',
...options.headers,
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const authService = {
async checkUser(): Promise<{ user: SteamUser } | null> {
try {
const response = await fetch(`${API_BASE_URL}/auth/user`, {
credentials: "include",
});
if (response.ok) {
return await response.json();
}
return null;
} catch (error) {
console.error("Auth check failed:", error);
return null;
}
},
async logout(): Promise<void> {
try {
await fetch(`${API_BASE_URL}/auth/logout`, {
credentials: "include",
});
} catch (error) {
console.error("Logout failed:", error);
throw error;
}
},
getSteamLoginUrl(): string {
return `${API_BASE_URL}/auth/steam`;
}
getCurrentUser: () => apiCall('/auth/user'),
logout: () => apiCall('/auth/logout', { method: 'POST' }),
};
export const voteService = {
async checkVoteStatus(): Promise<VoteStatusResponse> {
try {
const response = await fetch(`${API_BASE_URL}/api/vote-status`, {
credentials: "include",
});
if (response.ok) {
return await response.json();
}
throw new Error("Failed to check vote status");
} catch (error) {
console.error("Failed to check vote status:", error);
throw error;
}
},
async submitVote(vote: MapOption[]): Promise<{ success: boolean; message: string; user: string }> {
try {
const response = await fetch(`${API_BASE_URL}/api/submit-vote`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
submitVote: (vote: MapOption[]) =>
apiCall('/api/submit-vote', {
method: 'POST',
body: JSON.stringify({ vote }),
});
if (response.ok) {
return await response.json();
} else {
const error = await response.json();
throw new Error(error.error);
}
} catch (error) {
console.error("Failed to submit vote:", error);
throw error;
}
}
}),
getVoteStatus: () => apiCall('/api/vote-status'),
getResults: () => apiCall('/api/results'),
};