fix: Implement gallery-specific authentication tokens
- Fix issue where different galleries shared authentication - Store gallery tokens with slug-specific keys in localStorage - Remove global gallery_token cookie approach - Each gallery now maintains its own authentication state - Add cleanup for legacy authentication data This ensures that accessing different galleries requires separate authentication and prevents cross-gallery authentication leakage. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { createContext, useContext, useState, useEffect } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { getAuthToken } from '../config/api';
|
||||
import { authService } from '../services';
|
||||
import { cleanupOldGalleryAuth } from '../utils/cleanupGalleryAuth';
|
||||
|
||||
interface GalleryEvent {
|
||||
id: number;
|
||||
@@ -42,20 +42,42 @@ export const GalleryAuthProvider: React.FC<GalleryAuthProviderProps> = ({ childr
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Get current gallery slug from URL
|
||||
const getCurrentGallerySlug = () => {
|
||||
const pathParts = window.location.pathname.split('/');
|
||||
if (pathParts[1] === 'gallery' && pathParts[2]) {
|
||||
return pathParts[2];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Clean up old authentication data on mount
|
||||
cleanupOldGalleryAuth();
|
||||
|
||||
// Check if user has a valid token on mount
|
||||
const token = getAuthToken(false);
|
||||
if (token) {
|
||||
// Try to restore event data from localStorage
|
||||
const storedEvent = localStorage.getItem('gallery_event');
|
||||
if (storedEvent) {
|
||||
const currentSlug = getCurrentGallerySlug();
|
||||
if (currentSlug) {
|
||||
// Try to restore event data from localStorage with slug-specific key
|
||||
const storedEvent = localStorage.getItem(`gallery_event_${currentSlug}`);
|
||||
const storedToken = localStorage.getItem(`gallery_token_${currentSlug}`);
|
||||
|
||||
if (storedEvent && storedToken) {
|
||||
try {
|
||||
const eventData = JSON.parse(storedEvent);
|
||||
setEvent(eventData);
|
||||
setIsAuthenticated(true);
|
||||
// Verify the stored event matches the current gallery slug
|
||||
if (eventData && eventData.id) {
|
||||
setEvent(eventData);
|
||||
setIsAuthenticated(true);
|
||||
} else {
|
||||
// Clear invalid data
|
||||
localStorage.removeItem(`gallery_event_${currentSlug}`);
|
||||
localStorage.removeItem(`gallery_token_${currentSlug}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to parse stored event data');
|
||||
localStorage.removeItem('gallery_event');
|
||||
localStorage.removeItem(`gallery_event_${currentSlug}`);
|
||||
localStorage.removeItem(`gallery_token_${currentSlug}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,8 +92,9 @@ export const GalleryAuthProvider: React.FC<GalleryAuthProviderProps> = ({ childr
|
||||
setEvent(response.event);
|
||||
setIsAuthenticated(true);
|
||||
|
||||
// Store event data in localStorage
|
||||
localStorage.setItem('gallery_event', JSON.stringify(response.event));
|
||||
// Store event data and token in localStorage with slug-specific key
|
||||
localStorage.setItem(`gallery_event_${slug}`, JSON.stringify(response.event));
|
||||
localStorage.setItem(`gallery_token_${slug}`, response.token);
|
||||
} catch (err: any) {
|
||||
setError(err.response?.data?.error || 'Invalid password');
|
||||
throw err;
|
||||
@@ -81,10 +104,14 @@ export const GalleryAuthProvider: React.FC<GalleryAuthProviderProps> = ({ childr
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
const currentSlug = getCurrentGallerySlug();
|
||||
if (currentSlug) {
|
||||
localStorage.removeItem(`gallery_event_${currentSlug}`);
|
||||
localStorage.removeItem(`gallery_token_${currentSlug}`);
|
||||
}
|
||||
authService.galleryLogout();
|
||||
setIsAuthenticated(false);
|
||||
setEvent(null);
|
||||
localStorage.removeItem('gallery_event');
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user