AstraOS Ver. 1.9:
- Age Verification hinzugefügt (für SkyFlo)
This commit is contained in:
parent
da97db7553
commit
1b7a12f8e2
119
AstraOS/Frontend/HTML/age_verification.html
Normal file
119
AstraOS/Frontend/HTML/age_verification.html
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
{% extends "sidebar.html" %}
|
||||
|
||||
{% block title %}AstraOS — Altersüberprüfung{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<header class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-4xl font-bold tracking-wide {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Altersüberprüfung</h2>
|
||||
</header>
|
||||
|
||||
<!-- FLASH MESSAGES -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="mb-4 rounded-md bg-{{ 'red' if category == 'danger' else ('green' if category == 'success' else 'blue') }}-500/20 p-4 text-sm text-{{ 'red' if category == 'danger' else ('green' if category == 'success' else 'blue') }}-300 border border-{{ 'red' if category == 'danger' else ('green' if category == 'success' else 'blue') }}-500/30">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<!-- Verification Form -->
|
||||
<div class="bg-black/40 p-6 rounded-xl backdrop-blur border {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %}">
|
||||
<h3 class="text-2xl font-semibold mb-4">Neue Überprüfung</h3>
|
||||
<form method="POST" class="space-y-4">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
<div>
|
||||
<label for="birthdate" class="block text-sm font-medium text-gray-300">Geburtsdatum</label>
|
||||
<input type="date" name="birthdate" id="birthdate" required
|
||||
class="mt-1 w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 {% if maintenance_active %}focus:ring-yellow-500{% else %}focus:ring-purple-500{% endif %}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="steam_id" class="block text-sm font-medium text-gray-300">SteamID</label>
|
||||
<input type="text" name="steam_id" id="steam_id" placeholder="z.B. STEAM_0:1:23456789" required
|
||||
class="mt-1 w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 {% if maintenance_active %}focus:ring-yellow-500{% else %}focus:ring-purple-500{% endif %}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="ingame_name" class="block text-sm font-medium text-gray-300">Ingame Name</label>
|
||||
<input type="text" name="ingame_name" id="ingame_name" placeholder="z.B. Max Mustermann" required
|
||||
class="mt-1 w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 {% if maintenance_active %}focus:ring-yellow-500{% else %}focus:ring-purple-500{% endif %}">
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="font-bold py-2 px-4 rounded-lg transition text-white {% if maintenance_active %}bg-yellow-600 hover:bg-yellow-700{% else %}bg-purple-600 hover:bg-purple-700{% endif %}">
|
||||
Überprüfen
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% if result %}
|
||||
<div class="mt-6 border-t {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %} pt-4">
|
||||
<h4 class="text-xl font-semibold mb-2">Ergebnis</h4>
|
||||
<p class="text-lg">Die Person ist <span class="font-bold {% if result.age < 13 %}text-red-400{% else %}text-green-400{% endif %}">{{ result.age }}</span> Jahre alt.</p>
|
||||
{% if result.age < 13 %}
|
||||
<p class="text-lg mt-2">Diese Person muss für <span class="font-bold text-yellow-400">{{ result.ban_duration_days }}</span> Tage gesperrt werden.</p>
|
||||
<div class="mt-4">
|
||||
<label for="ban-command" class="block text-sm font-medium text-gray-300">Bann-Befehl</label>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<input type="text" id="ban-command" readonly value="{{ result.ban_command }}"
|
||||
class="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white">
|
||||
<button onclick="copyToClipboard('ban-command')" class="flex-shrink-0 font-bold py-2 px-4 rounded-lg transition text-white {% if maintenance_active %}bg-yellow-600 hover:bg-yellow-700{% else %}bg-purple-600 hover:bg-purple-700{% endif %}">
|
||||
Kopieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-lg mt-2 text-green-400">Keine Sperre erforderlich.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- User Search -->
|
||||
<div class="bg-black/40 p-6 rounded-xl backdrop-blur border {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %}">
|
||||
<h3 class="text-2xl font-semibold mb-4">Benutzer suchen</h3>
|
||||
<form method="GET" class="flex gap-2 mb-4">
|
||||
<input type="text" name="search" placeholder="Suche nach Name oder SteamID..." value="{{ search_query }}"
|
||||
class="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 {% if maintenance_active %}focus:ring-yellow-500{% else %}focus:ring-purple-500{% endif %}">
|
||||
<button type="submit" class="font-bold py-2 px-4 rounded-lg transition text-white {% if maintenance_active %}bg-yellow-600 hover:bg-yellow-700{% else %}bg-purple-600 hover:bg-purple-700{% endif %}">
|
||||
Suchen
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="space-y-2 max-h-96 overflow-y-auto">
|
||||
{% for user in users %}
|
||||
<a href="{{ url_for('view_user_age_details', user_id=user._id) }}" class="block p-3 rounded-lg transition {% if maintenance_active %}hover:bg-yellow-500/10{% else %}hover:bg-purple-500/10{% endif %}">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<p class="font-semibold {% if user.age < 13 %}text-red-400{% else %}text-white{% endif %}">{{ user.ingame_name }}</p>
|
||||
<p class="text-sm text-gray-400">{{ user.steam_id }}</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<p class="text-lg font-bold">{{ user.age }} Jahre</p>
|
||||
<p class="text-xs text-gray-500">{{ user.timestamp.strftime('%d.%m.%Y') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{% else %}
|
||||
<p class="text-gray-400">Keine Benutzer gefunden.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyToClipboard(elementId) {
|
||||
const input = document.getElementById(elementId);
|
||||
input.select();
|
||||
input.setSelectionRange(0, 99999); // For mobile devices
|
||||
document.execCommand('copy');
|
||||
// Optional: Visuelles Feedback geben
|
||||
const originalButtonText = event.target.innerText;
|
||||
event.target.innerText = 'Kopiert!';
|
||||
setTimeout(() => {
|
||||
event.target.innerText = originalButtonText;
|
||||
}, 1500);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -247,7 +247,13 @@
|
|||
</a>
|
||||
{% endif %}
|
||||
<a href="https://intra.moon-lab.de" target="_blank" rel="noopener noreferrer" class="block px-3 py-1 rounded-md {% if maintenance_active %}hover:bg-yellow-500/10 hover:text-yellow-300{% else %}hover:bg-purple-500/10 hover:text-purple-300{% endif %}">🌐 Moonlab-Intranet</a>
|
||||
<a href="javascript:void(0);" onclick="alert('Diese Funktion wird in Kürze verfügbar sein.')" class="block px-3 py-1 rounded-md {% if maintenance_active %}hover:bg-yellow-500/10 hover:text-yellow-300{% else %}hover:bg-purple-500/10 hover:text-purple-300{% endif %}">🎂 Altersüberprüfung</a>
|
||||
{% if 'view_age_verification' in session.get('permissions', []) %}
|
||||
<a href="{{ url_for('age_verification') }}" class="block px-3 py-1 rounded-md transition
|
||||
{% if active_page == 'age_verification' %}{% if maintenance_active %}bg-yellow-500/10 text-yellow-300{% else %}bg-purple-500/10 text-purple-300{% endif %}{% else %}
|
||||
{% if maintenance_active %}hover:bg-yellow-500/10 hover:text-yellow-300{% else %}hover:bg-purple-500/10 hover:text-purple-300{% endif %}{% endif %}">
|
||||
🎂 Altersüberprüfung
|
||||
</a>
|
||||
{% endif %}
|
||||
<a href="javascript:void(0);" onclick="alert('Diese Funktion wird in Kürze verfügbar sein.')" class="block px-3 py-1 rounded-md {% if maintenance_active %}hover:bg-yellow-500/10 hover:text-yellow-300{% else %}hover:bg-purple-500/10 hover:text-purple-300{% endif %}">🎉 Events</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
74
AstraOS/Frontend/HTML/view_user_age_details.html
Normal file
74
AstraOS/Frontend/HTML/view_user_age_details.html
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
{% extends "sidebar.html" %}
|
||||
|
||||
{% block title %}AstraOS — Benutzerdetails{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<header class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-4xl font-bold tracking-wide {% if maintenance_active %}text-yellow-300{% else %}text-purple-300{% endif %}">Benutzerdetails</h2>
|
||||
<a href="{{ url_for('age_verification') }}" class="font-bold py-2 px-4 rounded-lg transition text-white {% if maintenance_active %}bg-yellow-600 hover:bg-yellow-700{% else %}bg-purple-600 hover:bg-purple-700{% endif %}">
|
||||
← Zurück
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<div class="bg-black/40 p-6 rounded-xl backdrop-blur border {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %}">
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<p class="text-sm text-gray-400">Ingame Name</p>
|
||||
<p class="text-xl font-semibold">{{ user.ingame_name }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-gray-400">SteamID</p>
|
||||
<p class="text-xl font-semibold">{{ user.steam_id }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-gray-400">Geburtsdatum</p>
|
||||
<p class="text-xl font-semibold">{{ user.birthdate }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-gray-400">Alter bei Überprüfung</p>
|
||||
<p class="text-xl font-bold {% if user.age < 13 %}text-red-400{% else %}text-green-400{% endif %}">{{ user.age }} Jahre</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-gray-400">Überprüft von</p>
|
||||
<p class="text-xl font-semibold">{{ user.checked_by }} am {{ user.timestamp.strftime('%d.%m.%Y um %H:%M') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if result %}
|
||||
<div class="mt-6 border-t {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %} pt-4">
|
||||
<h4 class="text-xl font-semibold mb-2">Aktion erforderlich</h4>
|
||||
<p class="text-lg mt-2">Diese Person muss für <span class="font-bold text-yellow-400">{{ result.ban_duration_days }}</span> Tage gesperrt werden.</p>
|
||||
<div class="mt-4">
|
||||
<label for="ban-command" class="block text-sm font-medium text-gray-300">Bann-Befehl</label>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<input type="text" id="ban-command" readonly value="{{ result.ban_command }}"
|
||||
class="w-full px-3 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white">
|
||||
<button onclick="copyToClipboard('ban-command')" class="flex-shrink-0 font-bold py-2 px-4 rounded-lg transition text-white {% if maintenance_active %}bg-yellow-600 hover:bg-yellow-700{% else %}bg-purple-600 hover:bg-purple-700{% endif %}">
|
||||
Kopieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif user.age >= 13 %}
|
||||
<div class="mt-6 border-t {% if maintenance_active %}border-yellow-500/30{% else %}border-purple-500/20{% endif %} pt-4">
|
||||
<p class="text-lg text-green-400">Keine Sperre erforderlich.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function copyToClipboard(elementId) {
|
||||
const input = document.getElementById(elementId);
|
||||
input.select();
|
||||
input.setSelectionRange(0, 99999); // For mobile devices
|
||||
document.execCommand('copy');
|
||||
// Optional: Visuelles Feedback geben
|
||||
const originalButtonText = event.target.innerText;
|
||||
event.target.innerText = 'Kopiert!';
|
||||
setTimeout(() => {
|
||||
event.target.innerText = originalButtonText;
|
||||
}, 1500);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
@ -61,6 +61,7 @@ try:
|
|||
dashboard_collection = db["dashboard_stats"]
|
||||
discord_bots_collection = db["discord_bots_data"]
|
||||
ip_analyzer_results_collection = db["ip_analyzer_results"]
|
||||
age_verification_collection = db["age_verification"]
|
||||
print("INFO: MongoDB-Verbindung erfolgreich hergestellt.")
|
||||
AVAILABLE_PERMISSIONS = [
|
||||
"view_dashboard",
|
||||
|
|
@ -72,7 +73,8 @@ try:
|
|||
"maintenance_management",
|
||||
"bypass_maintenance",
|
||||
"manage_discord_bots",
|
||||
"view_ip_analyzer"
|
||||
"view_ip_analyzer",
|
||||
"view_age_verification"
|
||||
]
|
||||
if roles_collection.count_documents({}) == 0:
|
||||
print("WARNUNG: Keine Rollen in der Datenbank gefunden. Erstelle Standard-Rollen...")
|
||||
|
|
@ -691,6 +693,83 @@ def delete_role(role_id):
|
|||
roles_collection.delete_one({'_id': ObjectId(role_id)})
|
||||
flash("Rolle wurde gelöscht.", "success")
|
||||
return redirect(url_for('role_management'))
|
||||
@app.route('/age_verification', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@permission_required('view_age_verification')
|
||||
def age_verification():
|
||||
result = None
|
||||
search_query = request.args.get('search', '')
|
||||
|
||||
if request.method == 'POST':
|
||||
birthdate_str = request.form.get('birthdate')
|
||||
steam_id = request.form.get('steam_id')
|
||||
ingame_name = request.form.get('ingame_name')
|
||||
|
||||
if birthdate_str and steam_id and ingame_name:
|
||||
birthdate_dt = datetime.strptime(birthdate_str, '%Y-%m-%d')
|
||||
today = datetime.today()
|
||||
age = today.year - birthdate_dt.year - ((today.month, today.day) < (birthdate_dt.month, birthdate_dt.day))
|
||||
|
||||
user_data = {
|
||||
'birthdate': birthdate_str,
|
||||
'steam_id': steam_id,
|
||||
'ingame_name': ingame_name,
|
||||
'age': age,
|
||||
'checked_by': session.get('username'),
|
||||
'timestamp': datetime.utcnow()
|
||||
}
|
||||
age_verification_collection.insert_one(user_data)
|
||||
|
||||
result = {'age': age, 'steam_id': steam_id}
|
||||
if age < 13:
|
||||
thirteenth_birthday = birthdate_dt.replace(year=birthdate_dt.year + 13)
|
||||
ban_duration_days = (thirteenth_birthday - today).days + 1
|
||||
result['ban_duration_days'] = ban_duration_days
|
||||
result['ban_command'] = f"oban {steam_id} {ban_duration_days}d"
|
||||
|
||||
flash("Altersüberprüfung erfolgreich durchgeführt und gespeichert.", "success")
|
||||
|
||||
if search_query:
|
||||
users = list(age_verification_collection.find({
|
||||
"$or": [
|
||||
{"ingame_name": {"$regex": search_query, "$options": "i"}},
|
||||
{"steam_id": {"$regex": search_query, "$options": "i"}}
|
||||
]
|
||||
}).sort("timestamp", -1))
|
||||
else:
|
||||
users = list(age_verification_collection.find().sort("timestamp", -1).limit(10))
|
||||
|
||||
return render_template('age_verification.html',
|
||||
active_page='age_verification',
|
||||
result=result,
|
||||
users=users,
|
||||
search_query=search_query)
|
||||
|
||||
@app.route('/age_verification/<user_id>')
|
||||
@login_required
|
||||
@permission_required('view_age_verification')
|
||||
def view_user_age_details(user_id):
|
||||
user = age_verification_collection.find_one({'_id': ObjectId(user_id)})
|
||||
if not user:
|
||||
flash("Benutzer nicht gefunden.", "danger")
|
||||
return redirect(url_for('age_verification'))
|
||||
|
||||
result = None
|
||||
if user.get('age') < 13:
|
||||
today = datetime.today()
|
||||
birthdate_dt = datetime.strptime(user['birthdate'], '%Y-%m-%d')
|
||||
thirteenth_birthday = birthdate_dt.replace(year=birthdate_dt.year + 13)
|
||||
ban_duration_days = (thirteenth_birthday - today).days + 1
|
||||
if ban_duration_days > 0:
|
||||
result = {
|
||||
'ban_duration_days': ban_duration_days,
|
||||
'ban_command': f"oban {user['steam_id']} {ban_duration_days}d"
|
||||
}
|
||||
|
||||
return render_template('view_user_age_details.html',
|
||||
active_page='age_verification',
|
||||
user=user,
|
||||
result=result)
|
||||
@app.route('/ip_analyzer', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@permission_required('view_ip_analyzer')
|
||||
|
|
|
|||
|
|
@ -885,59 +885,6 @@ def start_bots_on_server_start():
|
|||
start_bots_on_server_start()
|
||||
|
||||
|
||||
@app.route("/verify_age", methods=["GET", "POST"])
|
||||
@csrf.exempt
|
||||
def verify_age():
|
||||
if "username" not in session:
|
||||
return redirect(url_for("login"))
|
||||
|
||||
age = None
|
||||
birthdate_dt = None
|
||||
today = datetime.today()
|
||||
if request.method == "POST":
|
||||
birthdate = request.form["birthdate"]
|
||||
steam_id = request.form["steam_id"]
|
||||
ingame_name = request.form["ingame_name"]
|
||||
|
||||
birthdate_dt = datetime.strptime(birthdate, "%Y-%m-%d")
|
||||
age = today.year - birthdate_dt.year - ((today.month, today.day) < (birthdate_dt.month, birthdate_dt.day))
|
||||
|
||||
user_ages_collection.insert_one({
|
||||
"username": session["username"],
|
||||
"birthdate": birthdate,
|
||||
"age": age,
|
||||
"steam_id": steam_id,
|
||||
"ingame_name": ingame_name,
|
||||
"timestamp": datetime.now()
|
||||
})
|
||||
|
||||
search_query = request.args.get('search')
|
||||
if search_query:
|
||||
users = user_ages_collection.find({
|
||||
"$or": [
|
||||
{"ingame_name": {"$regex": search_query, "$options": "i"}},
|
||||
{"steam_id": {"$regex": search_query, "$options": "i"}}
|
||||
]
|
||||
})
|
||||
else:
|
||||
users = user_ages_collection.find().limit(10)
|
||||
|
||||
return render_template("verify_age.html", age=age, birthdate_dt=birthdate_dt, today=today, users=users)
|
||||
|
||||
|
||||
@app.route("/verify_age/<user_id>", methods=["GET"])
|
||||
def view_user_age(user_id):
|
||||
if "username" not in session:
|
||||
return redirect(url_for("login"))
|
||||
|
||||
user = user_ages_collection.find_one({"_id": ObjectId(user_id)})
|
||||
if user:
|
||||
user['_id'] = str(user['_id'])
|
||||
return render_template("view_user_age.html", user=user)
|
||||
else:
|
||||
return "Benutzer nicht gefunden", 404
|
||||
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
add_log(f"{session['username']} hat sich ausgeloggt")
|
||||
|
|
|
|||
Loading…
Reference in a new issue