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:
@@ -8,10 +8,10 @@
|
||||
<h1>{{ event.name }}</h1>
|
||||
<p>{{ 'attendee_badges'|t }}</p>
|
||||
<div class="header-actions">
|
||||
<a href="{{ url_for('event_scan', event_id=event.id) }}" class="btn btn-secondary">📷 {{ 'scan_qr_codes'|t }}</a>
|
||||
<a href="{{ url_for('download_rectangular_badges', event_id=event.id) }}" class="btn btn-secondary">🏷️ Rectangular Labels (80x50mm)</a>
|
||||
<a href="{{ url_for('download_attendees_excel', event_id=event.id) }}" class="btn btn-secondary">📥 Download Excel</a>
|
||||
<button onclick="window.print()" class="btn btn-primary">{{ 'print_badges'|t }}</button>
|
||||
<a href="{{ url_for('event_scan', event_id=event.id) }}" class="btn btn-secondary"><i data-lucide="scan-line"></i> {{ 'scan_qr_codes'|t }}</a>
|
||||
<a href="{{ url_for('download_rectangular_badges', event_id=event.id) }}" class="btn btn-secondary"><i data-lucide="tag"></i> Rectangular Labels (80x50mm)</a>
|
||||
<a href="{{ url_for('download_attendees_excel', event_id=event.id) }}" class="btn btn-secondary"><i data-lucide="download"></i> Download Excel</a>
|
||||
<button onclick="window.print()" class="btn btn-primary"><i data-lucide="printer"></i> {{ 'print_badges'|t }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<div class="badge-footer">
|
||||
<span class="badge-id">#{{ attendee.id }}</span>
|
||||
<span class="badge-check {% if attendee.checked_in %}checked-in{% endif %}">
|
||||
{% if attendee.checked_in %}✓ {{ 'checked_in'|t }}{% else %}{{ 'pending'|t }}{% endif %}
|
||||
{% if attendee.checked_in %}<i data-lucide="check"></i> {{ 'checked_in'|t }}{% else %}{{ 'pending'|t }}{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="badge-event-bar">
|
||||
@@ -47,27 +47,6 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.badge-header h3 { margin: 0; font-size: 30pt; line-height: 1.1; }
|
||||
.badge-header h3 .first-name,
|
||||
.badge-header h3 .last-name { display: inline; line-height: 1.1; font-size: 30pt; }
|
||||
.badge-header h3 .last-name:before { content: ' '; }
|
||||
@media print {
|
||||
.navbar, .footer, .badges-header .header-actions button, .flash-messages { display: none !important; }
|
||||
.badges-page { padding: 0; }
|
||||
.badges-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
|
||||
.badge-card { border: 2px solid #000; padding: 15px; page-break-inside: avoid; }
|
||||
.badge-header h3 { margin: 0; font-size: 30pt; line-height: 1.1; }
|
||||
.badge-header h3 .first-name,
|
||||
.badge-header h3 .last-name { display: inline !important; line-height: 1.1; font-size: 30pt; }
|
||||
.badge-header h3 .last-name:before { content: ' '; }
|
||||
.badge-qr img { width: 80px !important; height: 80px !important; }
|
||||
.badge-body p { margin: 5px 0; }
|
||||
.badge-footer { display: flex; justify-content: space-between; margin-top: 10px; padding-top: 10px; border-top: 1px solid #ccc; }
|
||||
.badge-event-bar { background: #000; color: #fff; padding: 8px 15px; margin: 10px -15px -15px; font-size: 12pt; text-align: center; }
|
||||
.badge-event-bar { background: #000; color: #fff; padding: 8px 15px; margin: 10px -15px -15px; font-size: 12pt; text-align: center; }
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function() {
|
||||
// Create offscreen canvas for text measurement
|
||||
|
||||
Reference in New Issue
Block a user