Marwan Alwali a710d1c4d8 update
2025-09-11 19:01:55 +03:00

391 lines
17 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Session Details - Session Management{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'accounts:user_list' %}">Users</a></li>
<li class="breadcrumb-item"><a href="{% url 'accounts:session_list' %}">Sessions</a></li>
<li class="breadcrumb-item active">Session Details</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
Session Details
<small>{{ object.session_key|truncatechars:16 }}...</small>
</h1>
<!-- END page-header -->
<div class="row">
<div class="col-xl-8">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Session Information</h4>
<div class="panel-heading-btn">
{% if object.is_active %}
<button class="btn btn-xs btn-danger me-2" onclick="terminateSession()">
<i class="fa fa-sign-out-alt"></i> Terminate
</button>
{% endif %}
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
</div>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold" width="150">Session Key:</td>
<td><code>{{ object.session_key }}</code></td>
</tr>
<tr>
<td class="fw-bold">User:</td>
<td>
{% if object.user %}
<a href="{% url 'accounts:user_detail' object.user.pk %}" class="text-decoration-none">
{{ object.user.get_full_name }}
</a>
<br><small class="text-muted">{{ object.user.username }}</small>
{% else %}
<span class="text-muted">Anonymous Session</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Status:</td>
<td>
{% if object.is_active %}
<span class="badge bg-success">Active</span>
{% else %}
<span class="badge bg-secondary">Expired</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Created:</td>
<td>{{ object.created_at|date:"M d, Y H:i:s" }}</td>
</tr>
<tr>
<td class="fw-bold">Last Activity:</td>
<td>
{{ object.last_activity|date:"M d, Y H:i:s" }}
<br><small class="text-muted">{{ object.last_activity|timesince }} ago</small>
</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold" width="150">IP Address:</td>
<td>
{{ object.ip_address|default:"Unknown" }}
{% if object.ip_address %}
<br><small class="text-muted">
<a href="#" onclick="lookupIP('{{ object.ip_address }}')" class="text-decoration-none">
<i class="fa fa-search me-1"></i>Lookup Location
</a>
</small>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">User Agent:</td>
<td>
{% if object.user_agent %}
<div class="small">{{ object.browser_info.name }} {{ object.browser_info.version }}</div>
<div class="text-muted small">{{ object.browser_info.os }}</div>
{% else %}
<span class="text-muted">Unknown</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Duration:</td>
<td>
{% if object.is_active %}
{{ object.duration }}
<br><small class="text-success">Currently active</small>
{% else %}
{{ object.duration }}
<br><small class="text-muted">Session ended</small>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Expires:</td>
<td>
{% if object.expires_at %}
{{ object.expires_at|date:"M d, Y H:i:s" }}
{% if object.is_active %}
<br><small class="text-muted">{{ object.expires_at|timeuntil }} remaining</small>
{% endif %}
{% else %}
<span class="text-muted">No expiration</span>
{% endif %}
</td>
</tr>
</table>
</div>
</div>
<!-- Session Data -->
{% if object.session_data %}
<div class="mt-4">
<h6>Session Data</h6>
<div class="bg-light p-3 rounded">
<pre class="mb-0"><code>{{ object.session_data_formatted }}</code></pre>
</div>
</div>
{% endif %}
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Session Activity</h4>
<div class="panel-heading-btn">
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
</div>
</div>
<div class="panel-body">
{% if session_activities %}
<div class="timeline">
{% for activity in session_activities %}
<div class="timeline-item">
<div class="timeline-time">{{ activity.timestamp|date:"H:i" }}</div>
<div class="timeline-icon bg-{{ activity.get_activity_color }}">
<i class="fa fa-{{ activity.get_activity_icon }}"></i>
</div>
<div class="timeline-body">
<div class="timeline-header">
<span class="fw-bold">{{ activity.get_activity_display }}</span>
</div>
<div class="timeline-content">
<div class="small text-muted">
{{ activity.description }}
{% if activity.ip_address %}
• IP: {{ activity.ip_address }}
{% endif %}
</div>
{% if activity.details %}
<div class="small">{{ activity.details }}</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-4 text-muted">
<i class="fa fa-history fa-3x mb-3"></i>
<p>No activity records found for this session.</p>
</div>
{% endif %}
</div>
</div>
<!-- END panel -->
</div>
<div class="col-xl-4">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Quick Actions</h4>
</div>
<div class="panel-body">
<div class="d-grid gap-2">
{% if object.is_active %}
<button class="btn btn-danger" onclick="terminateSession()">
<i class="fa fa-sign-out-alt me-2"></i>Terminate Session
</button>
{% endif %}
{% if object.user %}
<a href="{% url 'accounts:user_detail' object.user.pk %}" class="btn btn-primary">
<i class="fa fa-user me-2"></i>View User Profile
</a>
<button class="btn btn-warning" onclick="terminateUserSessions()">
<i class="fa fa-sign-out-alt me-2"></i>Terminate All User Sessions
</button>
{% endif %}
<button class="btn btn-info" onclick="refreshSessionData()">
<i class="fa fa-refresh me-2"></i>Refresh Data
</button>
<button class="btn btn-outline-secondary" onclick="exportSessionData()">
<i class="fa fa-download me-2"></i>Export Session Data
</button>
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Security Information</h4>
</div>
<div class="panel-body">
<div class="mb-3">
<strong>Security Score:</strong>
<div class="progress mt-2">
<div class="progress-bar bg-{{ object.security_score_color }}" style="width: {{ object.security_score }}%">
{{ object.security_score }}%
</div>
</div>
</div>
<div class="small">
<div class="mb-2">
<i class="fa fa-{{ object.is_secure_connection|yesno:'lock text-success,unlock text-warning' }} me-2"></i>
{{ object.is_secure_connection|yesno:'Secure Connection,Insecure Connection' }}
</div>
<div class="mb-2">
<i class="fa fa-{{ object.is_trusted_ip|yesno:'shield-alt text-success,exclamation-triangle text-warning' }} me-2"></i>
{{ object.is_trusted_ip|yesno:'Trusted IP,Unknown IP' }}
</div>
<div class="mb-2">
<i class="fa fa-{{ object.is_known_device|yesno:'check text-success,question text-info' }} me-2"></i>
{{ object.is_known_device|yesno:'Known Device,New Device' }}
</div>
{% if object.suspicious_activity %}
<div class="mb-2 text-danger">
<i class="fa fa-exclamation-triangle me-2"></i>
Suspicious Activity Detected
</div>
{% endif %}
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Location Information</h4>
</div>
<div class="panel-body">
{% if object.location_info %}
<table class="table table-sm table-borderless">
<tr>
<td class="text-muted">Country:</td>
<td>{{ object.location_info.country|default:"Unknown" }}</td>
</tr>
<tr>
<td class="text-muted">Region:</td>
<td>{{ object.location_info.region|default:"Unknown" }}</td>
</tr>
<tr>
<td class="text-muted">City:</td>
<td>{{ object.location_info.city|default:"Unknown" }}</td>
</tr>
<tr>
<td class="text-muted">ISP:</td>
<td>{{ object.location_info.isp|default:"Unknown" }}</td>
</tr>
</table>
{% else %}
<div class="text-center py-3 text-muted">
<i class="fa fa-map-marker-alt fa-2x mb-2"></i>
<p class="mb-0">Location information not available.</p>
{% if object.ip_address %}
<button class="btn btn-sm btn-outline-primary mt-2" onclick="lookupIP('{{ object.ip_address }}')">
Lookup Location
</button>
{% endif %}
</div>
{% endif %}
</div>
</div>
<!-- END panel -->
</div>
</div>
{% endblock %}
{% block js %}
<script>
function terminateSession() {
if (confirm('Are you sure you want to terminate this session?')) {
$.ajax({
url: '{% url "accounts:session_terminate" object.session_key %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
if (response.success) {
toastr.success('Session terminated successfully');
location.reload();
} else {
toastr.error('Failed to terminate session');
}
},
error: function() {
toastr.error('An error occurred while terminating the session');
}
});
}
}
{% if object.user %}
function terminateUserSessions() {
if (confirm('Are you sure you want to terminate ALL sessions for this user?')) {
$.ajax({
url: '{% url "accounts:user_terminate_sessions" object.user.pk %}',
method: 'POST',
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
if (response.success) {
toastr.success('All user sessions terminated successfully');
location.reload();
} else {
toastr.error('Failed to terminate user sessions');
}
},
error: function() {
toastr.error('An error occurred while terminating user sessions');
}
});
}
}
{% endif %}
function refreshSessionData() {
location.reload();
}
function exportSessionData() {
window.location.href = '{% url "accounts:session_export" %}?session={{ object.session_key }}';
}
function lookupIP(ipAddress) {
// Implementation for IP lookup
toastr.info('IP lookup functionality will be implemented');
}
// Auto-refresh every 30 seconds if session is active
{% if object.is_active %}
setInterval(function() {
location.reload();
}, 30000);
{% endif %}
</script>
{% endblock %}