From eec2a01618a98538d4ba1cfdeb8c1c8e80b271e5 Mon Sep 17 00:00:00 2001 From: MrWhiff Date: Thu, 11 Dec 2025 16:56:14 +0100 Subject: [PATCH] =?UTF-8?q?AstraOS=20Ver.=201.10:=20-=20Benachrichtigung?= =?UTF-8?q?=20aktualisiert=20-=20Logs=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AstraOS/Frontend/HTML/age_verification.html | 35 +- AstraOS/Frontend/HTML/dashboard.html | 28 +- AstraOS/Frontend/HTML/discord_bots.html | 34 ++ AstraOS/Frontend/HTML/logs.html | 64 +++ AstraOS/Frontend/HTML/role_management.html | 34 ++ AstraOS/Frontend/HTML/settings.html | 32 +- AstraOS/Frontend/HTML/sidebar.html | 440 +++++++++--------- AstraOS/Frontend/HTML/user_management.html | 28 +- .../Frontend/HTML/view_user_age_details.html | 34 ++ AstraOS/astra_os.py | 53 ++- 10 files changed, 560 insertions(+), 222 deletions(-) create mode 100644 AstraOS/Frontend/HTML/logs.html diff --git a/AstraOS/Frontend/HTML/age_verification.html b/AstraOS/Frontend/HTML/age_verification.html index 656b57d..d5a3588 100644 --- a/AstraOS/Frontend/HTML/age_verification.html +++ b/AstraOS/Frontend/HTML/age_verification.html @@ -2,6 +2,10 @@ {% block title %}AstraOS — Altersüberprüfung{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}

Altersüberprüfung

@@ -10,11 +14,35 @@ {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} +
{% for category, message in messages %} -
- {{ message }} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
{% endfor %} +
{% endif %} {% endwith %} @@ -31,7 +59,7 @@
-
@@ -116,4 +144,3 @@ function copyToClipboard(elementId) { } {% endblock %} - diff --git a/AstraOS/Frontend/HTML/dashboard.html b/AstraOS/Frontend/HTML/dashboard.html index aca0e8b..ac32ba0 100644 --- a/AstraOS/Frontend/HTML/dashboard.html +++ b/AstraOS/Frontend/HTML/dashboard.html @@ -37,11 +37,35 @@ {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} +
{% for category, message in messages %} -
- {{ message }} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
{% endfor %} +
{% endif %} {% endwith %} diff --git a/AstraOS/Frontend/HTML/discord_bots.html b/AstraOS/Frontend/HTML/discord_bots.html index 6947d31..48d5380 100644 --- a/AstraOS/Frontend/HTML/discord_bots.html +++ b/AstraOS/Frontend/HTML/discord_bots.html @@ -18,6 +18,40 @@ {% block content %}
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
+
+ {% endfor %} +
+ {% endif %} + {% endwith %}

Discord Bot Management

diff --git a/AstraOS/Frontend/HTML/logs.html b/AstraOS/Frontend/HTML/logs.html new file mode 100644 index 0000000..1372bda --- /dev/null +++ b/AstraOS/Frontend/HTML/logs.html @@ -0,0 +1,64 @@ +{% extends "sidebar.html" %} + +{% block title %}AstraOS — Logs{% endblock %} + +{% block content %} +
+

System-Logs

+
+ +
+
+ + + + + + + + + + + {% for log in logs %} + + + + + + + {% else %} + + + + {% endfor %} + +
BenutzerAktionDetailsZeitstempel (UTC)
{{ log.username }}{{ log.action }}{{ log.details if log.details else '-' }}{{ log.timestamp.strftime('%d.%m.%Y %H:%M:%S') }}
Keine Logs gefunden.
+
+
+ + +{% if total_pages > 1 %} + +{% endif %} + +{% endblock %} + diff --git a/AstraOS/Frontend/HTML/role_management.html b/AstraOS/Frontend/HTML/role_management.html index aba0995..1606eb8 100644 --- a/AstraOS/Frontend/HTML/role_management.html +++ b/AstraOS/Frontend/HTML/role_management.html @@ -9,6 +9,40 @@ {% block content %}
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
+
+ {% endfor %} +
+ {% endif %} + {% endwith %}

Rollen verwalten

diff --git a/AstraOS/Frontend/HTML/settings.html b/AstraOS/Frontend/HTML/settings.html index c2c7eb4..5566110 100644 --- a/AstraOS/Frontend/HTML/settings.html +++ b/AstraOS/Frontend/HTML/settings.html @@ -2,6 +2,10 @@ {% block title %}AstraOS — Einstellungen{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}
@@ -11,11 +15,35 @@ {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} +
{% for category, message in messages %} -
- {{ message }} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
{% endfor %} +
{% endif %} {% endwith %} diff --git a/AstraOS/Frontend/HTML/sidebar.html b/AstraOS/Frontend/HTML/sidebar.html index 58b6f5a..cfb369e 100644 --- a/AstraOS/Frontend/HTML/sidebar.html +++ b/AstraOS/Frontend/HTML/sidebar.html @@ -4,13 +4,26 @@ {% block title %}AstraOS{% endblock %} - - + - - {% block head %}{% endblock %} - + + {% block head %}{% endblock %} - + +
+ + + +
+
+ {% block content %}{% endblock %} +
+ +
+ © 2025 AstraOS +
+
+
+ + + + -
-

AstraOS

-
- -
- -
- - -
-
- {% block content %}{% endblock %} -
- -
- © 2025 AstraOS -
-
-
- - - - - - Logout - + Logout + - - + -{% if maintenance_active %} - -{% endif %} + + {% if maintenance_active %} + + {% endif %} diff --git a/AstraOS/Frontend/HTML/user_management.html b/AstraOS/Frontend/HTML/user_management.html index 9c779b5..f5b9511 100644 --- a/AstraOS/Frontend/HTML/user_management.html +++ b/AstraOS/Frontend/HTML/user_management.html @@ -34,11 +34,35 @@ {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} +
{% for category, message in messages %} -
- {{ message }} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
{% endfor %} +
{% endif %} {% endwith %} diff --git a/AstraOS/Frontend/HTML/view_user_age_details.html b/AstraOS/Frontend/HTML/view_user_age_details.html index 024e574..b047518 100644 --- a/AstraOS/Frontend/HTML/view_user_age_details.html +++ b/AstraOS/Frontend/HTML/view_user_age_details.html @@ -8,6 +8,40 @@ {% block content %}
+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
+
+
+
+ {% if category == 'success' %} + + {% elif category == 'danger' %} + + {% else %} + + {% endif %} +
+
+

{{ message }}

+
+
+
+
+ {% endfor %} +
+ {% endif %} + {% endwith %}

Benutzerdetails

diff --git a/AstraOS/astra_os.py b/AstraOS/astra_os.py index 01ad146..f25147b 100644 --- a/AstraOS/astra_os.py +++ b/AstraOS/astra_os.py @@ -180,6 +180,17 @@ try: except Exception as e: tickets_collection = None print(f"FATAL: Verbindung zu Tickets-DB fehlgeschlagen: {e}") + +def add_log(action, details=None): + if 'username' in session and logs_collection is not None: + log_entry = { + 'username': session['username'], + 'action': action, + 'details': details, + 'timestamp': datetime.utcnow() + } + logs_collection.insert_one(log_entry) + def get_user_permissions(user_id): user = accounts_collection.find_one({'_id': ObjectId(user_id)}) if not user or 'role_id' not in user: @@ -252,6 +263,7 @@ def login(): session['user_id'] = str(user['_id']) session['username'] = user['username'] session['permissions'] = get_user_permissions(str(user['_id'])) + add_log("User Login") # Prüfen, ob Discord verknüpft ist if not user.get('discord_id'): @@ -389,6 +401,7 @@ def dashboard(): @app.route('/logout') @login_required def logout(): + add_log("User Logout") session.clear() flash("Sie wurden erfolgreich abgemeldet.", "info") return redirect(url_for('login')) @@ -447,12 +460,13 @@ def add_user(): 'discord_username': None, 'discord_avatar': None }) + add_log("User Created", f"Username: {username}") if dashboard_collection is not None: dashboard_collection.update_one( {"key": "last_user_created"}, {"$set": { "time": datetime.utcnow(), - "by": username + "by": session.get('username') }}, upsert=True ) @@ -491,6 +505,7 @@ def edit_user(user_id): {'_id': ObjectId(user_id)}, {'$set': update_data} ) + add_log("User Edited", f"Username: {username}") flash(f"Benutzer '{username}' wurde erfolgreich aktualisiert.", "success") return redirect(url_for('user_management')) @app.route('/delete_user/', methods=['POST']) @@ -503,7 +518,9 @@ def delete_user(user_id): if session.get('user_id') == user_id: flash("Sie können sich nicht selbst löschen.", "danger") return redirect(url_for('user_management')) + user = accounts_collection.find_one({'_id': ObjectId(user_id)}) accounts_collection.delete_one({'_id': ObjectId(user_id)}) + add_log("User Deleted", f"Username: {user.get('username', 'N/A')}") flash("Benutzer wurde erfolgreich gelöscht.", "success") return redirect(url_for('user_management')) @@ -536,6 +553,7 @@ def update_password(): hashed_password = generate_password_hash(new_password) accounts_collection.update_one({'_id': ObjectId(user_id)}, {'$set': {'password': hashed_password}}) + add_log("Password Changed") flash("Dein Passwort wurde erfolgreich geändert.", "success") return redirect(url_for('settings')) @@ -547,6 +565,7 @@ def unlink_discord(): {'_id': ObjectId(user_id)}, {'$set': {'discord_id': None, 'discord_username': None, 'discord_avatar': None}} ) + add_log("Discord Unlinked") flash("Deine Discord-Verknüpfung wurde entfernt. Bitte verknüpfe dein Konto erneut.", "info") return redirect(url_for('link_discord')) @@ -621,6 +640,7 @@ def callback_discord(): 'discord_avatar': discord_avatar }} ) + add_log("Discord Linked") flash("Discord-Account erfolgreich verknüpft!", "success") return redirect(url_for('dashboard')) @@ -632,6 +652,7 @@ def callback_discord(): session['user_id'] = str(user['_id']) session['username'] = user['username'] session['permissions'] = get_user_permissions(str(user['_id'])) + add_log("User Login via Discord") flash("Erfolgreich mit Discord angemeldet!", "success") return redirect(url_for('dashboard')) else: @@ -666,6 +687,7 @@ def add_role(): "permissions": permissions, "is_deletable": True }) + add_log("Role Created", f"Role: {role_name}") flash(f"Rolle '{role_name}' wurde erstellt.", "success") return redirect(url_for('role_management')) @app.route('/edit_role/', methods=['POST']) @@ -681,6 +703,7 @@ def edit_role(role_id): {'_id': ObjectId(role_id)}, {'$set': {'name': role_name, 'permissions': permissions}} ) + add_log("Role Edited", f"Role: {role_name}") flash(f"Rolle '{role_name}' wurde aktualisiert.", "success") return redirect(url_for('role_management')) @app.route('/delete_role/', methods=['POST']) @@ -692,6 +715,7 @@ def delete_role(role_id): flash("Diese Rolle kann nicht gelöscht werden.", "danger") return redirect(url_for('role_management')) roles_collection.delete_one({'_id': ObjectId(role_id)}) + add_log("Role Deleted", f"Role: {role.get('name', 'N/A')}") flash("Rolle wurde gelöscht.", "success") return redirect(url_for('role_management')) @@ -734,6 +758,7 @@ def age_verification(): result['ban_duration_days'] = ban_duration_days result['ban_command'] = f"oban {steam_id} {ban_duration_days}d" + add_log("Age Verification Added", f"Ingame Name: {ingame_name}, SteamID: {steam_id}") flash("Altersüberprüfung erfolgreich durchgeführt und gespeichert.", "success") if search_query: @@ -803,6 +828,7 @@ def delete_age_verification(user_id): return redirect(url_for('view_user_age_details', user_id=user_id)) age_verification_collection.delete_one({'_id': ObjectId(user_id)}) + add_log("Age Verification Deleted", f"Ingame Name: {entry.get('ingame_name', 'N/A')}, SteamID: {entry.get('steam_id', 'N/A')}") flash("Eintrag zur Altersüberprüfung wurde gelöscht.", "success") return redirect(url_for('age_verification')) @app.route('/ip_analyzer', methods=['GET', 'POST']) @@ -844,6 +870,7 @@ def ip_analyzer(): "added_by": session["username"], "timestamp": datetime.utcnow() }) + add_log("IP Analyzed", f"IP: {ip_address}") flash("IP-Adresse erfolgreich analysiert und gespeichert.", "success") else: error = f"Fehler bei der API-Anfrage: Status {response.status_code}" @@ -856,6 +883,25 @@ def ip_analyzer(): ip_data=ip_data, error=error, similar_ips=similar_ips) + +@app.route('/logs') +@login_required +@permission_required('view_logs') +def logs(): + page = request.args.get('page', 1, type=int) + per_page = 25 + skip = (page - 1) * per_page + + log_entries = list(logs_collection.find().sort('timestamp', -1).skip(skip).limit(per_page)) + total_logs = logs_collection.count_documents({}) + total_pages = (total_logs + per_page - 1) // per_page + + return render_template('logs.html', + logs=log_entries, + page=page, + total_pages=total_pages, + active_page='logs') + def stream_bot_output(bot_id, process): def stream_to_socket(pipe, log_type): try: @@ -913,6 +959,7 @@ def upload_bot(): 'created_at': datetime.utcnow(), 'status': 'stopped' }) + add_log("Bot Uploaded", f"Bot Name: {bot_name}") flash(f"Bot '{bot_name}' wurde erfolgreich hochgeladen.", "success") return redirect(url_for('discord_bots')) @app.route('/delete_bot/', methods=['POST']) @@ -939,6 +986,7 @@ def delete_bot(bot_id): except Exception as e: flash(f"Fehler beim Löschen der Bot-Datei: {e}", "danger") discord_bots_collection.delete_one({'_id': ObjectId(bot_id)}) + add_log("Bot Deleted", f"Bot Name: {bot_info.get('name', 'N/A')}") flash(f"Bot '{bot_info['name']}' wurde erfolgreich gelöscht.", "success") return redirect(url_for('discord_bots')) @app.route('/bot_console/') @@ -994,6 +1042,7 @@ def handle_toggle_bot(data): thread.daemon = True thread.start() discord_bots_collection.update_one({'_id': ObjectId(bot_id)}, {'$set': {'status': 'running'}}) + add_log("Bot Started", f"Bot Name: {bot_info.get('name', 'N/A')}") emit('status_update', {'bot_id': bot_id, 'status': 'running'}, room=bot_id) emit('console_output', {'type': 'system', 'data': f'--- Bot-Prozess gestartet (PID: {process.pid}) ---'}, room=bot_id) except Exception as e: @@ -1008,6 +1057,7 @@ def handle_toggle_bot(data): if bot_id in running_bots: del running_bots[bot_id] discord_bots_collection.update_one({'_id': ObjectId(bot_id)}, {'$set': {'status': 'stopped'}}) + add_log("Bot Stopped", f"Bot Name: {bot_info.get('name', 'N/A')}") emit('status_update', {'bot_id': bot_id, 'status': 'stopped'}, room=bot_id) emit('console_output', {'type': 'system', 'data': '--- Bot-Prozess wird gestoppt... ---'}, room=bot_id) @app.route('/maintenance') @@ -1083,6 +1133,7 @@ def update_maintenance(): {"$set": update_data}, upsert=True ) + add_log("Maintenance Settings Updated", f"Enabled: {is_enabled}, Message: {status_message}") flash("Wartungseinstellungen wurden aktualisiert.", "success") return redirect(url_for('maintenance_management')) if __name__ == '__main__':