Complete ircquotes application with all features

- Added copy quote functionality with clipboard integration
- Implemented bulk moderation actions for admin
- Created mobile responsive design with bash.org styling
- Added API rate limiting per IP address
- Implemented dark mode toggle with flash prevention
- Enhanced error messages throughout application
- Fixed all security vulnerabilities (SQL injection, XSS, CSRF)
- Added comprehensive rate limiting on all endpoints
- Implemented secure session configuration
- Added input validation and length limits
- Created centralized configuration system with config.json
- Set up production deployment with Gunicorn
- Added security headers and production hardening
- Added password generation and config management tools
This commit is contained in:
2025-09-20 19:41:23 +01:00
parent 0b1241714d
commit f409977257
21 changed files with 1936 additions and 304 deletions

44
static/theme.js Normal file
View File

@@ -0,0 +1,44 @@
// Dark mode toggle functionality for ircquotes
// Maintains bash.org aesthetic while providing dark theme option
function toggleDarkMode() {
const body = document.body;
const html = document.documentElement;
const isDark = body.classList.contains('dark-theme') || html.classList.contains('dark-theme');
if (isDark) {
body.classList.remove('dark-theme');
html.classList.remove('dark-theme');
localStorage.setItem('theme', 'light');
updateToggleButton(false);
} else {
body.classList.add('dark-theme');
html.classList.add('dark-theme');
localStorage.setItem('theme', 'dark');
updateToggleButton(true);
}
}
function updateToggleButton(isDark) {
const toggleBtn = document.getElementById('theme-toggle');
if (toggleBtn) {
toggleBtn.textContent = isDark ? '☀' : '🌙';
toggleBtn.title = isDark ? 'Switch to light mode' : 'Switch to dark mode';
}
}
// Initialize theme on page load
document.addEventListener('DOMContentLoaded', function() {
const savedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme === 'dark' || (!savedTheme && prefersDark)) {
document.body.classList.add('dark-theme');
document.documentElement.classList.add('dark-theme');
updateToggleButton(true);
} else {
document.body.classList.remove('dark-theme');
document.documentElement.classList.remove('dark-theme');
updateToggleButton(false);
}
});