Security hardening: env-based config, CSRF protection, secure code generation, plus presenter management and email communications system

- Move all credentials from hardcoded to .env with python-dotenv (add .env.example template and .gitignore)
- Add CSRF token generation and validation on all state-changing requests
- Replace random.choices with secrets.choice for all secure code generation
- Add session cookie security headers (HttpOnly, Secure, SameSite)
- Add presenter management: assign/remove presenters to breakout sessions, presenter QR scanning
- Add email communications system: templates per event, custom email sending, sent email tracking
- Add staff/organizer profile pages with staff code display
- New DB tables: event_email_templates, sent_emails, user_communications
- New DB columns: staff.reminder_count/reminder_dates, breakout_session_organizers.presenter_code
- Expand English translation strings across all new features

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 20:34:48 +00:00
parent 934848b7f5
commit a3546b4c01
45 changed files with 8296 additions and 3207 deletions
+55 -7
View File
@@ -1,16 +1,21 @@
#!/usr/bin/env python3
"""Database initialization script for NetEvent platform."""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import mysql.connector
from mysql.connector import Error
from config import Config
DB_HOST = 'roast.duckdns.org'
DB_PORT = 33062
DB_USER = 'root'
DB_PASSWORD = 'Tiegl!!!111...'
DB_NAME = 'netevent'
APP_USER = 'netevent_app'
APP_PASSWORD = 'netevent_pass_2024'
DB_HOST = Config.DB_HOST
DB_PORT = Config.DB_PORT
DB_USER = Config.DB_USER
DB_PASSWORD = Config.DB_PASSWORD
DB_NAME = Config.DB_NAME
APP_USER = Config.DB_APP_USER
APP_PASSWORD = Config.DB_APP_PASSWORD
def create_database():
"""Create the database and dedicated user."""
@@ -196,6 +201,46 @@ def create_tables():
FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE,
UNIQUE KEY unique_type_code_per_event (event_id, code)
)
""",
# Email templates per event
"""
CREATE TABLE IF NOT EXISTS event_email_templates (
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT NOT NULL,
template_type VARCHAR(50) NOT NULL,
subject VARCHAR(500),
body TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE,
UNIQUE KEY unique_event_template (event_id, template_type)
)
""",
# Sent custom emails
"""
CREATE TABLE IF NOT EXISTS sent_emails (
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT NOT NULL,
sender_id INT NOT NULL,
sender_type VARCHAR(20) NOT NULL,
recipient_type VARCHAR(30) NOT NULL,
recipient_id INT DEFAULT NULL,
subject VARCHAR(500) NOT NULL,
body TEXT NOT NULL,
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
)
""",
# User communications (links users to received emails)
"""
CREATE TABLE IF NOT EXISTS user_communications (
id INT PRIMARY KEY AUTO_INCREMENT,
user_type VARCHAR(20) NOT NULL,
user_id INT NOT NULL,
sent_email_id INT NOT NULL,
read_at TIMESTAMP NULL,
FOREIGN KEY (sent_email_id) REFERENCES sent_emails(id) ON DELETE CASCADE
)
"""
]
@@ -209,6 +254,9 @@ def create_tables():
"ALTER TABLE attendees ADD COLUMN attendee_type_id INT DEFAULT NULL",
"ALTER TABLE organizers ADD COLUMN reset_token VARCHAR(64) DEFAULT NULL",
"ALTER TABLE organizers ADD COLUMN reset_token_expiry DATETIME DEFAULT NULL",
"ALTER TABLE staff ADD COLUMN reminder_count INT DEFAULT 0",
"ALTER TABLE staff ADD COLUMN reminder_dates JSON DEFAULT NULL",
"ALTER TABLE breakout_session_organizers ADD COLUMN presenter_code VARCHAR(10) UNIQUE DEFAULT NULL",
]
try: