Rebrand to PedsHub, fix CSP for fonts and Turnstile

- index.html: title → PedsHub, icon → 🏥, add meta description
- nginx.conf: CSP extended for Google Fonts, Cloudflare Turnstile (script/connect/frame/img)
- Navbar, LoginPage, ForgotPassword, ResetPassword, email_service, main.py: PedQuiz → PedsHub, 🩺🏥

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-04-04 01:56:53 +02:00
parent d4fb34e329
commit 10b9b1b7cf
7 changed files with 14 additions and 13 deletions

View file

@ -311,7 +311,7 @@ async def lifespan(app: FastAPI):
app = FastAPI(
title="PedQuiz",
title="PedsHub",
description="Pediatric Knowledge Quiz Platform",
version="2.0.0",
lifespan=lifespan,

View file

@ -14,7 +14,7 @@ def get_mail_config() -> ConnectionConfig:
MAIL_USERNAME=settings.MAIL_USERNAME,
MAIL_PASSWORD=settings.MAIL_PASSWORD,
MAIL_FROM=settings.MAIL_FROM,
MAIL_FROM_NAME="PedQuiz",
MAIL_FROM_NAME="PedsHub",
MAIL_PORT=settings.MAIL_PORT,
MAIL_SERVER=settings.MAIL_SERVER,
MAIL_STARTTLS=settings.MAIL_STARTTLS,
@ -73,7 +73,7 @@ def _wrap(subject: str, body_md: str) -> str:
<!-- Logo -->
<tr><td style="padding-bottom:36px;">
<span style="font-size:15px;font-weight:600;color:#09090b;letter-spacing:-0.2px;">🩺 PedQuiz</span>
<span style="font-size:15px;font-weight:600;color:#09090b;letter-spacing:-0.2px;">🏥 PedsHub</span>
</td></tr>
<!-- Card -->
@ -84,7 +84,7 @@ def _wrap(subject: str, body_md: str) -> str:
<!-- Footer -->
<tr><td style="padding:24px 0 0;">
<p style="margin:0;font-size:12px;color:#a1a1aa;line-height:1.6;">
PedQuiz · Pediatric Knowledge Platform<br/>
PedsHub · Pediatric Knowledge Platform<br/>
<a href="{settings.APP_URL}" style="color:#a1a1aa;text-decoration:underline;">{settings.APP_URL}</a>
</p>
<p style="margin:8px 0 0;font-size:11px;color:#d4d4d8;">
@ -112,12 +112,12 @@ async def _send(to_email: str, subject: str, html: str):
async def send_verification_email(to_email: str, name: str, token: str):
url = f"{settings.APP_URL}/verify-email?token={token}"
subject = "Verify your PedQuiz email"
subject = "Verify your PedsHub email"
md = f"""# Verify your email
Hi **{name}**,
Welcome to PedQuiz. Click below to verify your email address and activate your account.
Welcome to PedsHub. Click below to verify your email address and activate your account.
[button:Verify Email Address]({url})
@ -132,7 +132,7 @@ Welcome to PedQuiz. Click below to verify your email address and activate your a
async def send_password_reset_email(to_email: str, name: str, token: str):
url = f"{settings.APP_URL}/reset-password?token={token}"
subject = "Reset your PedQuiz password"
subject = "Reset your PedsHub password"
md = f"""# Reset your password
Hi **{name}**,

View file

@ -3,8 +3,9 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PedQuiz</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🩺</text></svg>" />
<title>PedsHub</title>
<meta name="description" content="Pediatric learning platform — create quizzes from PDFs, study with AI explanations, and track your progress." />
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🏥</text></svg>" />
<!-- Inter: clean professional UI font -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

View file

@ -16,7 +16,7 @@ server {
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; connect-src 'self'; font-src 'self';" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://challenges.cloudflare.com; media-src 'self' blob:; connect-src 'self' https://challenges.cloudflare.com; font-src 'self' https://fonts.gstatic.com; frame-src https://challenges.cloudflare.com;" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# API proxy to backend

View file

@ -99,7 +99,7 @@ export default function Navbar() {
return (
<div className="navbar">
<div className="container navbar-inner">
<Link to="/" className="logo" onClick={() => setMenuOpen(false)}>🩺 PedQuiz</Link>
<Link to="/" className="logo" onClick={() => setMenuOpen(false)}>🏥 PedsHub</Link>
{user && (
<>

View file

@ -30,7 +30,7 @@ export default function ForgotPasswordPage() {
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f1f5f9' }}>
<div style={{ width: '100%', maxWidth: 400, padding: '0 16px' }}>
<div style={{ textAlign: 'center', marginBottom: 32 }}>
<div style={{ fontSize: '2rem', fontWeight: 800, color: '#2563eb' }}>🩺 PedQuiz</div>
<div style={{ fontSize: '2rem', fontWeight: 800, color: '#2563eb' }}>🏥 PedsHub</div>
</div>
<div className="card">
{sent ? (

View file

@ -33,7 +33,7 @@ export default function ResetPasswordPage() {
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f1f5f9' }}>
<div style={{ width: '100%', maxWidth: 400, padding: '0 16px' }}>
<div style={{ textAlign: 'center', marginBottom: 32 }}>
<div style={{ fontSize: '2rem', fontWeight: 800, color: '#2563eb' }}>🩺 PedQuiz</div>
<div style={{ fontSize: '2rem', fontWeight: 800, color: '#2563eb' }}>🏥 PedsHub</div>
</div>
<div className="card">
{success ? (