From 10fd6e63bfcfdcf0b0953a6da9b7d0ff9fe01966 Mon Sep 17 00:00:00 2001 From: cato447 Date: Fri, 9 Jan 2026 03:33:15 +0100 Subject: [PATCH] added html email and made site deployment ready | security fixes still needed --- app/config.py.example | 9 ++--- app/routes.py | 7 ++-- app/static/h4tum_white.png | Bin 0 -> 28267 bytes app/static/timeline.css | 81 +++++++++++++++++++++++++++++++++++++ app/templates/email.html | 53 ++++++++++++++++++++++++ app/templates/index.html | 43 +++++++++++++++++++- 6 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 app/static/h4tum_white.png create mode 100644 app/static/timeline.css create mode 100644 app/templates/email.html diff --git a/app/config.py.example b/app/config.py.example index 45a791b..29379df 100644 --- a/app/config.py.example +++ b/app/config.py.example @@ -8,14 +8,13 @@ class Config: 'sqlite:///' + os.path.join(basedir, '../instance/registration.db') SQLALCHEMY_TRACK_MODIFICATIONS = False - # Email Settings (Update these!) - MAIL_SERVER = - MAIL_PORT = + MAIL_SERVER = 'mail.your-server.de' + MAIL_PORT = 587 MAIL_USE_TLS = True MAIL_USERNAME = os.environ.get('EMAIL_USER') MAIL_PASSWORD = os.environ.get('EMAIL_PASS') MAIL_DEFAULT_SENDER = os.environ.get('EMAIL_USER') - MAX_SPOTS = + MAX_SPOTS = 84 TUM_DOMAIN = "tum.de" - DISCORD_LINK = + DISCORD_LINK = os.environ.get('DISCORD_LINK') diff --git a/app/routes.py b/app/routes.py index 4355f53..b8184dc 100644 --- a/app/routes.py +++ b/app/routes.py @@ -13,10 +13,11 @@ def send_verification_email(user_email): s = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) token = s.dumps(user_email, salt='email-confirm-h4tum-ctf-2025') link = url_for('main.verify_email', token=token, _external=True) + logo = url_for('static', filename='h4tum_white.png', _external=True) - #msg = Message('Verify your CTF Registration', recipients=["fdohq9ipugtc@mockmail.io"]) - #msg.body = f'Click here to confirm your spot: {link}\nThanks for registering {user_email}' - print(link) + msg = Message('Verify your CTF Registration', recipients=[user_email]) + msg.html = render_template("email.html", user_email=user_email, link=link, logo_url=logo) + mail.send(msg) @bp.route('/', methods=['GET', 'POST']) def index(): diff --git a/app/static/h4tum_white.png b/app/static/h4tum_white.png new file mode 100644 index 0000000000000000000000000000000000000000..674c206a037edbb8338550ff91ef2d8c7296c221 GIT binary patch literal 28267 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 literal 0 HcmV?d00001 diff --git a/app/static/timeline.css b/app/static/timeline.css new file mode 100644 index 0000000..4871a5a --- /dev/null +++ b/app/static/timeline.css @@ -0,0 +1,81 @@ +.timeline-container { + position: relative; + padding: 0 20px; +} + +/* The actual horizontal line */ +.line { + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 4px; + background: #dfe6e9; + transform: translateY(-50%); + z-index: 1; +} + +.items-wrapper { + display: flex; + justify-content: space-between; + position: relative; + z-index: 2; +} + +.item { + width: 120px; + text-align: center; + position: relative; + /* This height ensures the time is above and label is below the line */ + height: 120px; +} + +/* The Dot - centered perfectly on the line */ +.dot { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); /* Centers the dot exactly */ + width: 16px; + height: 16px; + background: #00ff00; + border: 2px solid #1a1a1a; + border-radius: 50%; + box-shadow: 0 0 8px #00ff00; +} + +/* Time - positioned above the dot */ +.time { + position: absolute; + bottom: 65%; /* Push above the center line */ + left: 0; + right: 0; + font-weight: bold; + color: #ffffff; +} + +/* Label - positioned below the dot */ +.label { + position: absolute; + top: 65%; /* Push below the center line */ + left: 0; + right: 0; + font-size: 0.9rem; + color: #ffffff; +} + +.label span { + display: block; + font-size: 0.75rem; + color: #dddddd; + margin-top: 4px; +} + +/* Mobile: Stack vertically */ +@media (max-width: 700px) { + .line { display: none; } + .items-wrapper { flex-direction: column; gap: 10px; align-items: flex-start; } + .item { height: auto; text-align: center; width: 100%; } + .dot { display: none;} + .time, .label { position: static; } +} diff --git a/app/templates/email.html b/app/templates/email.html new file mode 100644 index 0000000..bce7d06 --- /dev/null +++ b/app/templates/email.html @@ -0,0 +1,53 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ Club Logo +
+

Registration Received

+
+ Thanks for registering
+ {{ user_email }}

+ To secure your spot at the event, please confirm your attendance by clicking the button below. +
+ + + + +
+ + CONFIRM MY SPOT + +
+
+ If you didn't request this, you can safely ignore this email. +
+
+ + diff --git a/app/templates/index.html b/app/templates/index.html index d38c092..a9c16a3 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -1,7 +1,9 @@ {% extends "base.html" %} {% block content %} -
+ + +

> Info

  • Date: 23.01.2026
  • @@ -23,7 +25,44 @@
  • Teams will be finalized on site at the competition

- Rules and further information +

> Timeline

+
+
+ +
+
+
12:00
+
+
EntrySetup & find team
+
+ +
+
13:00
+
+
Start of Event
+
+ +
+
~18:30
+
+
Pizza TimeBring cash. Menu
+
+ +
+
21:00
+
+
End of Event
+
+ +
+
21:15
+
+
Awards
+
+
+
+
+

Rules and Code of Conduct