added html email and made site deployment ready | security fixes still needed
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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():
|
||||
|
||||
BIN
app/static/h4tum_white.png
Normal file
BIN
app/static/h4tum_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
81
app/static/timeline.css
Normal file
81
app/static/timeline.css
Normal file
@@ -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; }
|
||||
}
|
||||
53
app/templates/email.html
Normal file
53
app/templates/email.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<html>
|
||||
<body style="margin: 0; padding: 0; background-color: #1a1a1a; font-family: 'Courier New', Courier, monospace; color: #ffffff;">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" style="background-color: #1a1a1a; padding: 20px;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" style="max-width: 600px; background-color: #222222; border: 1px solid #00ff00; padding: 30px;">
|
||||
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 20px;">
|
||||
<img src="{{ logo_url }}" alt="Club Logo" width="150" style="display: block; border: 0;">
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 20px;">
|
||||
<h1 style="color: #00ff00; font-size: 24px; margin: 0; text-transform: uppercase; text-align: center;">Registration Received</h1>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 30px; font-size: 16px; line-height: 1.5; text-align: center;">
|
||||
Thanks for registering <br>
|
||||
<strong style="color: #00ff00;">{{ user_email }}</strong><br><br>
|
||||
To secure your spot at the event, please confirm your attendance by clicking the button below.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" style="padding-bottom: 30px;">
|
||||
<table border="0" cellspacing="0" cellpadding="0" align="center">
|
||||
<tr>
|
||||
<td align="center" bgcolor="#00ff00" style="padding: 15px 25px;">
|
||||
<a href="{{ link }}" target="_blank" style="font-size: 18px; font-weight: bold; color: #000000; text-decoration: none; display: inline-block;">
|
||||
CONFIRM MY SPOT
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="center" style="padding-top: 20px; border-top: 1px solid #333333; font-size: 12px; color: #888888; text-align: center;">
|
||||
If you didn't request this, you can safely ignore this email.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='timeline.css') }}">
|
||||
<div class="container">
|
||||
<h1>> Info</h1>
|
||||
<ul>
|
||||
<li>Date: 23.01.2026</li>
|
||||
@@ -23,7 +25,44 @@
|
||||
<li>Teams will be finalized on site at the competition</li>
|
||||
</ul>
|
||||
<hr style="border-color: #333; margin: 30px 0;"></hr>
|
||||
<a href="{{ url_for('main.rules') }}">Rules and further information</a>
|
||||
<h1>> Timeline</h1>
|
||||
<div class="timeline-container">
|
||||
<div class="line"></div>
|
||||
|
||||
<div class="items-wrapper">
|
||||
<div class="item">
|
||||
<div class="time">12:00</div>
|
||||
<div class="dot"></div>
|
||||
<div class="label">Entry<span>Setup & find team</span></div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="time">13:00</div>
|
||||
<div class="dot"></div>
|
||||
<div class="label">Start of Event</div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="time">~18:30</div>
|
||||
<div class="dot"></div>
|
||||
<div class="label">Pizza Time<span>Bring cash. <a href="https://lapergola.igetnow.com/menu" target="_blank">Menu</a></span></div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="time">21:00</div>
|
||||
<div class="dot"></div>
|
||||
<div class="label">End of Event</div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="time">21:15</div>
|
||||
<div class="dot"></div>
|
||||
<div class="label">Awards</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr style="border-color: #333; margin: 30px 0;"></hr>
|
||||
<a href="{{ url_for('main.rules') }}" style="text-align: center;"><h3>Rules and Code of Conduct</h3></a>
|
||||
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
Reference in New Issue
Block a user