160 lines
7.4 KiB
Plaintext
160 lines
7.4 KiB
Plaintext
<!-- <h1>Activity Log</h1>
|
|
|
|
<div id="sessions">
|
|
<% @events.each do |event| %>
|
|
<div id="<%= dom_id event %>">
|
|
<p>
|
|
<strong>User Agent:</strong>
|
|
<%= event.user_agent %>
|
|
</p>
|
|
|
|
<p>
|
|
<strong>Action:</strong>
|
|
<%= event.action %>
|
|
</p>
|
|
|
|
<p>
|
|
<strong>Ip Address:</strong>
|
|
<%= event.ip_address %>
|
|
</p>
|
|
|
|
<p>
|
|
<strong>Created at:</strong>
|
|
<%= event.created_at %>
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
|
|
<br>
|
|
|
|
<div>
|
|
<%= link_to "Back", root_path %>
|
|
</div>
|
|
|
|
-->
|
|
|
|
<% content_for :title, "Konto-Aktivitäten & Logs" %>
|
|
|
|
<div class="max-w-2xl mx-auto space-y-6">
|
|
|
|
<%= render "identity/account_tabs", active_tab: :activities %>
|
|
|
|
<!-- Info-Header -->
|
|
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 flex flex-col sm:flex-row items-start sm:items-center gap-4 justify-between">
|
|
<div class="flex items-center gap-4">
|
|
<div class="p-3 bg-blue-50 text-blue-600 rounded-lg shrink-0">
|
|
<!-- Heroicon: clock -->
|
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0z" />
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h2 class="text-lg font-bold text-gray-800">Sicherheits-Historie</h2>
|
|
<p class="text-sm text-gray-500">Chronologische Übersicht der letzten 30 kritischen und erfolgreichen Ereignisse deines Kontos.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- TIMELINE LOGBUCH -->
|
|
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 md:p-8">
|
|
<div class="flow-root">
|
|
|
|
<% if @events.any? %>
|
|
<ul class="-mb-8">
|
|
|
|
<% @events.each_with_index do |event, index| %>
|
|
<% is_last = (index == @events.size - 1) %>
|
|
|
|
<li>
|
|
<div class="relative pb-8">
|
|
<!-- Vertikale Verbindungslinie -->
|
|
<% unless is_last %>
|
|
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200" aria-hidden="true"></span>
|
|
<% end %>
|
|
|
|
<div class="relative flex space-x-3">
|
|
<div>
|
|
<!-- Dynamische Farb- und Icon-Weiche je nach Event-Typ -->
|
|
<% case event.action %>
|
|
<% when "signed_in" %>
|
|
<span class="h-8 w-8 rounded-full bg-blue-50 flex items-center justify-center ring-8 ring-white">
|
|
<svg class="h-4 w-4 text-blue-600" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15m3 0 3-3m0 0-3-3m3 3H9" />
|
|
</svg>
|
|
</span>
|
|
<% when "password_changed" %>
|
|
<span class="h-8 w-8 rounded-full bg-amber-50 flex items-center justify-center ring-8 ring-white">
|
|
<svg class="h-4 w-4 text-amber-600" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 0 1 3 3m3 0a6 6 0 0 1-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1 1 21.75 8.25Z" />
|
|
</svg>
|
|
</span>
|
|
<% when "two_factor_activated" %>
|
|
<span class="h-8 w-8 rounded-full bg-green-50 flex items-center justify-center ring-8 ring-white">
|
|
<svg class="h-4 w-4 text-green-600" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12z" />
|
|
</svg>
|
|
</span>
|
|
<% else %>
|
|
<!-- Roter Kreis für fehlgeschlagene Anmeldungen oder Ausloggen -->
|
|
<span class="h-8 w-8 rounded-full bg-red-50 flex items-center justify-center ring-8 ring-white">
|
|
<svg class="h-4 w-4 text-red-600" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25z" />
|
|
</svg>
|
|
</span>
|
|
<% end %>
|
|
</div>
|
|
|
|
<!-- Textinhalte des Events -->
|
|
<div class="flex-1 min-w-0 pt-1.5 flex justify-between space-x-4">
|
|
<div class="min-w-0">
|
|
<p class="text-sm font-medium text-gray-800">
|
|
<% case event.action %>
|
|
<% when "login_success" %>
|
|
Erfolgreiche Anmeldung im System
|
|
<% when "password_changed" %>
|
|
Passwort erfolgreich geändert
|
|
<% when "two_factor_activated" %>
|
|
Zwei-Faktor-Authentifizierung aktiviert
|
|
<% when "login_failed" %>
|
|
<span class="text-red-600 font-semibold">Fehlgeschlagener Anmeldeversuch</span>
|
|
<% else %>
|
|
<%= event.action.humanize %>
|
|
<% end %>
|
|
</p>
|
|
|
|
<!-- Metadaten: IP und gekürzter User-Agent -->
|
|
<p class="text-xs text-gray-400 font-mono mt-0.5 truncate">
|
|
IP: <%= event.ip_address.presence || "Unbekannt" %>
|
|
<% if event.respond_to?(:user_agent) && event.user_agent.present? %>
|
|
• <%= parse_user_agent(event.user_agent) %>
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Zeitstempel über Schätzwert "vor X Tagen" -->
|
|
<div class="text-right text-xs whitespace-nowrap text-gray-400 pt-0.5 shrink-0">
|
|
<time class="font-medium" datetime="<%= event.created_at.iso8601 %>">
|
|
<%= time_ago_in_words(event.created_at) %> vor
|
|
</time>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<% end %>
|
|
|
|
</ul>
|
|
<% else %>
|
|
<!-- Empty State falls noch gar keine Logs da sind -->
|
|
<div class="text-center py-8 text-gray-400">
|
|
<p class="text-sm">Bisher wurden keine Aktivitäten aufgezeichnet.</p>
|
|
</div>
|
|
<% end %>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|