Initial commit - Project start (July 17, 2025)
Mirror to GitHub / mirror (push) Successful in 26s
Test and Lint / backend-test (push) Successful in 1m11s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m28s
Version and Release / version-bump (push) Successful in 32s
Version and Release / trigger-drone (push) Has been skipped
Mirror to GitHub / mirror (push) Successful in 26s
Test and Lint / backend-test (push) Successful in 1m11s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m28s
Version and Release / version-bump (push) Successful in 32s
Version and Release / trigger-drone (push) Has been skipped
Original: feat: enhance security logging and ensure rate limit blocks are properly tracked - Add comprehensive logging for rate limit blocks with full request details - IP address (with proper proxy detection), user agent, headers, timestamps - Rate limit info (current count, limit, remaining, reset time) - Separate tracking for auth vs general endpoints - Enhance authentication failure logging - JWT validation failures with detailed error info - Admin auth attempts without token - Failed token validation with user context - All events include IP, path, method, user agent - Improve Winston logger configuration for production - Add automatic log rotation (10MB errors, 50MB combined) - Create separate security.log for auth/rate limit events - Ensure logs directory exists automatically - Add structured JSON format for log aggregation - Support container logging with LOG_TO_CONSOLE env var - Create comprehensive documentation - Security logging guide with examples - Monitoring recommendations - Configuration reference - Add test script to verify logging functionality All rate limit settings remain configurable via admin panel: - Window duration, max requests, auth limits - Skip authenticated requests option - Public endpoints only option 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import { useEffect } from 'react';
|
||||
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
import 'react-toastify/dist/ReactToastify.css';
|
||||
import { analyticsService } from './services/analytics.service';
|
||||
|
||||
import { GalleryAuthProvider, MaintenanceProvider } from './contexts';
|
||||
import { ThemeProvider } from './contexts/ThemeContext';
|
||||
import { GalleryPage } from './pages/GalleryPage';
|
||||
import { PreviewPage } from './pages/gallery/PreviewPage';
|
||||
import { LegalPage } from './pages/public/LegalPage';
|
||||
import {
|
||||
AdminLoginPage,
|
||||
AdminDashboard,
|
||||
EventsListPage,
|
||||
CreateEventPageEnhanced as CreateEventPage,
|
||||
EventDetailsPage,
|
||||
EmailConfigPage,
|
||||
ArchivesPage,
|
||||
AnalyticsPage,
|
||||
BrandingPage,
|
||||
SettingsPage,
|
||||
CMSPage
|
||||
} from './pages/admin';
|
||||
import { CMSPageEnhanced } from './pages/admin/CMSPageEnhanced';
|
||||
import { AdminLayout, AdminAuthWrapper } from './components/admin';
|
||||
import { PageErrorBoundary, OfflineIndicator, SkipLink, DynamicFavicon } from './components/common';
|
||||
import { MaintenanceWrapper } from './components/MaintenanceWrapper';
|
||||
import { GlobalThemeProvider } from './components/GlobalThemeProvider';
|
||||
import { getApiBaseUrl } from './utils/url';
|
||||
|
||||
// Create a client
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
refetchOnWindowFocus: false,
|
||||
retry: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
function App() {
|
||||
// Initialize Umami Analytics based on settings
|
||||
useEffect(() => {
|
||||
const initializeAnalytics = async () => {
|
||||
const umamiUrl = import.meta.env.VITE_UMAMI_URL;
|
||||
const umamiWebsiteId = import.meta.env.VITE_UMAMI_WEBSITE_ID;
|
||||
|
||||
if (umamiUrl && umamiWebsiteId) {
|
||||
try {
|
||||
// Fetch public settings to check if analytics is enabled
|
||||
const response = await fetch(`${getApiBaseUrl()}/public/settings`);
|
||||
const settings = await response.json();
|
||||
|
||||
// Only initialize if analytics is enabled in settings
|
||||
if (settings.enable_analytics !== false) {
|
||||
analyticsService.initialize({
|
||||
websiteId: umamiWebsiteId,
|
||||
hostUrl: umamiUrl,
|
||||
autoTrack: true,
|
||||
doNotTrack: true
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch settings for analytics:', error);
|
||||
// Initialize analytics anyway if settings fetch fails
|
||||
analyticsService.initialize({
|
||||
websiteId: umamiWebsiteId,
|
||||
hostUrl: umamiUrl,
|
||||
autoTrack: true,
|
||||
doNotTrack: true
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
initializeAnalytics();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageErrorBoundary>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MaintenanceProvider>
|
||||
<ThemeProvider>
|
||||
<GlobalThemeProvider>
|
||||
<DynamicFavicon />
|
||||
<Router>
|
||||
<MaintenanceWrapper>
|
||||
<SkipLink />
|
||||
<Routes>
|
||||
{/* Public gallery routes */}
|
||||
<Route path="/gallery/preview" element={<PreviewPage />} />
|
||||
<Route path="/gallery/:slug/:token?" element={
|
||||
<GalleryAuthProvider>
|
||||
<GalleryPage />
|
||||
</GalleryAuthProvider>
|
||||
} />
|
||||
|
||||
{/* Admin routes - wrap with AdminAuthProvider */}
|
||||
<Route path="/admin" element={<AdminAuthWrapper />}>
|
||||
<Route path="login" element={<AdminLoginPage />} />
|
||||
<Route element={<AdminLayout />}>
|
||||
<Route path="dashboard" element={<AdminDashboard />} />
|
||||
<Route path="events" element={<EventsListPage />} />
|
||||
<Route path="events/new" element={<CreateEventPage />} />
|
||||
<Route path="events/:id" element={<EventDetailsPage />} />
|
||||
<Route path="archives" element={<ArchivesPage />} />
|
||||
<Route path="email" element={<EmailConfigPage />} />
|
||||
<Route path="analytics" element={<AnalyticsPage />} />
|
||||
<Route path="branding" element={<BrandingPage />} />
|
||||
<Route path="settings" element={<SettingsPage />} />
|
||||
<Route path="cms" element={<CMSPageEnhanced />} />
|
||||
<Route index element={<Navigate to="/admin/dashboard" replace />} />
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
{/* Public legal pages */}
|
||||
<Route path="/impressum" element={<LegalPage />} />
|
||||
<Route path="/datenschutz" element={<LegalPage />} />
|
||||
<Route path="/:slug" element={<LegalPage />} />
|
||||
|
||||
{/* Default redirect */}
|
||||
<Route path="/" element={<Navigate to="/admin/login" replace />} />
|
||||
</Routes>
|
||||
</MaintenanceWrapper>
|
||||
</Router>
|
||||
|
||||
{/* Offline indicator */}
|
||||
<OfflineIndicator />
|
||||
|
||||
{/* Toast notifications */}
|
||||
<ToastContainer
|
||||
position="bottom-right"
|
||||
autoClose={5000}
|
||||
hideProgressBar={false}
|
||||
newestOnTop
|
||||
closeOnClick
|
||||
rtl={false}
|
||||
pauseOnFocusLoss
|
||||
draggable
|
||||
pauseOnHover
|
||||
theme="light"
|
||||
/>
|
||||
</GlobalThemeProvider>
|
||||
</ThemeProvider>
|
||||
</MaintenanceProvider>
|
||||
</QueryClientProvider>
|
||||
</PageErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user